From 65f479c73becf3a86d8a37dbebdc3b7cdba263e9 Mon Sep 17 00:00:00 2001 From: Sun Peng Date: Tue, 2 Aug 2022 14:49:47 +0800 Subject: [PATCH] dm: vdisplay: multi-vdisplay support. 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: virtio-gpu,geometry=fullscreen:monitor_id1,geometry=fullscreen:monitor_id2 For window mode: virtio-gpu,geometry=x++,geometry=x++ v1->v2: add pscreen_id outputs for easier debugging. Tracked-On: #7988 Signed-off-by: Sun Peng Reviewed-by: Zhao Yakui --- devicemodel/hw/vdisplay_sdl.c | 62 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/devicemodel/hw/vdisplay_sdl.c b/devicemodel/hw/vdisplay_sdl.c index dfbde6c89..47ff4914f 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,33 +1331,45 @@ 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->org_x = 0; + vscr->org_y = 0; + vscr->guest_width = VDPY_MAX_WIDTH; + vscr->guest_height = VDPY_MAX_HEIGHT; + vscr->is_fullscreen = true; + pr_info("virtual display: fullscreen on monitor %d.\n", + vscr->pscreen_id); + vdpy.vscrs_num++; + } else if (str && strcasestr(str, "geometry=")) { + snum = sscanf(tmp, "geometry=%dx%d+%d+%d", + &vscr->guest_width, &vscr->guest_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 on monitor %d.\n", + vscr->pscreen_id); + vdpy.vscrs_num++; } - vscr->org_x = 0; - vscr->org_y = 0; - vscr->guest_width = VDPY_MAX_WIDTH; - vscr->guest_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->guest_width, &vscr->guest_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("%d virtual displays are too many that acrn-dm can't support!\n"); + break; } - vscr->is_fullscreen = false; - vdpy.vscrs_num++; - pr_info("virtual display: windowed.\n"); } + free(stropts); return error; }