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=<width>x<height>+<x_off>+<y_off>,geometry=<width>x<height>+<x_off>+<y_off>

v1->v2: add pscreen_id outputs for easier debugging.

Tracked-On: #7988
Signed-off-by: Sun Peng <peng.p.sun@linux.intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
This commit is contained in:
Sun Peng 2022-08-02 14:49:47 +08:00 committed by acrnsi-robot
parent ac294c59dd
commit 65f479c73b
1 changed files with 37 additions and 25 deletions

View File

@ -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;
}