On 2022/8/8 13:36, peng.p.sun@... wrote: From: Sun Peng <peng.p.sun@...> Allow one VM have more than 1 virtual display for output. Till now, the max virtual display number is 2. So guest VM can use dual display for mirror and extend desktop mode. To specify multi-vdisplay, need use acrn-dm parameters like this: For fullscreen mode: After multi vscreens are supported, it will be better that the error message is printed with the vscr_id. Otherwise it is difficult to check where is the problem. virtio-gpu,geometry=fullscreen:monitor_id1,geometry=fullscreen:monitor_id2 For window mode: virtio-gpu,geometry=<width>x<height>+<x_off>+<y_off>,geometry=<width>x<height>+<x_off>+<y_off> Signed-off-by: Sun Peng <peng.p.sun@...> --- devicemodel/hw/vdisplay_sdl.c | 67 +++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/devicemodel/hw/vdisplay_sdl.c b/devicemodel/hw/vdisplay_sdl.c index 28457c52e..c7a279ab6 100644 --- a/devicemodel/hw/vdisplay_sdl.c +++ b/devicemodel/hw/vdisplay_sdl.c @@ -32,7 +32,7 @@ #define VDPY_MIN_WIDTH 640 #define VDPY_MIN_HEIGHT 480 #define transto_10bits(color) (uint16_t)(color * 1024 + 0.5) -#define VSCREEN_MAX_NUM 1 +#define VSCREEN_MAX_NUM 2 static unsigned char default_raw_argb[VDPY_DEFAULT_WIDTH * VDPY_DEFAULT_HEIGHT * 4]; @@ -1323,7 +1323,7 @@ gfx_ui_deinit() int vdpy_parse_cmd_option(const char *opts) { - char *str; + char *str, *stropts, *tmp; int snum, error; struct vscreen *vscr; @@ -1331,35 +1331,48 @@ int vdpy_parse_cmd_option(const char *opts) vdpy.vscrs = calloc(VSCREEN_MAX_NUM, sizeof(struct vscreen)); vdpy.vscrs_num = 0; - str = strcasestr(opts, "geometry="); - vscr = vdpy.vscrs + vdpy.vscrs_num; - if (opts && strcasestr(opts, "geometry=fullscreen")) { - snum = sscanf(str, "geometry=fullscreen:%d", &vscr->pscreen_id); - if (snum != 1) { + stropts = strdup(opts); + while ((str = strsep(&stropts, ",")) != NULL) { + vscr = vdpy.vscrs + vdpy.vscrs_num; + tmp = strcasestr(str, "geometry="); + if (str && strcasestr(str, "geometry=fullscreen")) { + snum = sscanf(tmp, "geometry=fullscreen:%d", &vscr->pscreen_id); + if (snum != 1) { + vscr->pscreen_id = 0; + } + vscr->width = VDPY_MAX_WIDTH; + vscr->height = VDPY_MAX_HEIGHT; + vscr->is_fullscreen = true; + pr_info("virtual display: fullscreen.\n"); + vscr->info.xoff = vscr->org_x; + vscr->info.yoff = vscr->org_y; + vscr->info.width = vscr->width; + vscr->info.height = vscr->height; + vdpy.vscrs_num++; + } else if (str && strcasestr(str, "geometry=")) { + snum = sscanf(tmp, "geometry=%dx%d+%d+%d", + &vscr->width, &vscr->height, + &vscr->org_x, &vscr->org_y); + if (snum != 4) { + pr_err("incorrect geometry option. Should be" + " WxH+x+y\n"); + error = -1; + } + vscr->is_fullscreen = false; vscr->pscreen_id = 0; + pr_info("virtual display: windowed.\n"); + vscr->info.xoff = vscr->org_x; + vscr->info.yoff = vscr->org_y; + vscr->info.width = vscr->width; + vscr->info.height = vscr->height; + vdpy.vscrs_num++; } - vscr->width = VDPY_MAX_WIDTH; - vscr->height = VDPY_MAX_HEIGHT; - vscr->is_fullscreen = true; - vdpy.vscrs_num++; - pr_info("virtual display: fullscreen.\n"); - } else if (opts && strcasestr(opts, "geometry=")) { - snum = sscanf(str, "geometry=%dx%d+%d+%d", - &vscr->width, &vscr->height, - &vscr->org_x, &vscr->org_y); - if (snum != 4) { - pr_err("incorrect geometry option. Should be" - " WxH+x+y\n"); - error = -1; + if (vdpy.vscrs_num > VSCREEN_MAX_NUM) { + pr_err("Too many virtual display that acrn-dm can't support!\n"); + break; } - vscr->is_fullscreen = false; - vdpy.vscrs_num++; - pr_info("virtual display: windowed.\n"); } + free(stropts); - vscr->info.xoff = 0; - vscr->info.yoff = 0; - vscr->info.width = vdpy.vscrs->width; - vscr->info.height = vdpy.vscrs->height; return error; }
|