[PATCH v1 3/3] dm: vdisplay: multi-vdisplay support.


Sun, Peng
 

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:

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


Zhao, Yakui
 

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


Sun, Peng
 

On Mon, 2022-08-08 at 16:52 +0800, Zhao, Yakui wrote:


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.
[Sun, Peng] vscr_id will be printed in next version.


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<hei
ght>+<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;
  }
--
Sun Peng <peng.p.sun@...>
SSE/ACRN Upstream