dm: vdisplay: multi-local-mornitor support.

To support full screen mode on one of multi-local-mornitor which
connected to service vm by monitor ID that customer specify. The
monitor ID is specified in acrn-dm's parameter like this:

virtio-gpu,geometry=fullscreen:monitor_id

For window mode, the vdisplay window always be shown on monitor 0,
because the customer can drag the window to anyone monitor. Besides, the
customer can set the monitor by x_off and y_off parameter like this:

virtio-gpu,geometry=<width>x<height>+<x_off>+<y_off>

v1->v2: Add note about zoom to pscreen width & height in fullscreen.
v2->v3: vdpy.width/height for window, used in host, vdpy.guest_width/
guest_height for guest framebuffer, used in guest.

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-07-28 16:07:24 +08:00 committed by acrnsi-robot
parent 770ecb399b
commit ddf35fb016
1 changed files with 40 additions and 26 deletions

View File

@ -52,6 +52,8 @@ struct egl_display_ops {
}; };
static struct display { static struct display {
int pscreen_id;
SDL_Rect pscreen_rect;
struct display_info info; struct display_info info;
struct state s; struct state s;
SDL_Texture *dpy_texture; SDL_Texture *dpy_texture;
@ -62,7 +64,6 @@ static struct display {
int width, height; // Width/height of dpy_win int width, height; // Width/height of dpy_win
int org_x, org_y; int org_x, org_y;
int guest_width, guest_height; int guest_width, guest_height;
int screen;
struct surface surf; struct surface surf;
struct cursor cur; struct cursor cur;
SDL_Texture *cursor_tex; SDL_Texture *cursor_tex;
@ -909,35 +910,48 @@ vdpy_sdl_display_thread(void *data)
struct vdpy_display_bh *bh; struct vdpy_display_bh *bh;
struct itimerspec ui_timer_spec; struct itimerspec ui_timer_spec;
if (vdpy.width && vdpy.height) { if (vdpy.guest_width && vdpy.guest_height) {
/* clip the region between (640x480) and (1920x1080) */ /* clip the region between (640x480) and (1920x1080) */
if (vdpy.width < VDPY_MIN_WIDTH) if (vdpy.guest_width < VDPY_MIN_WIDTH)
vdpy.width = VDPY_MIN_WIDTH; vdpy.guest_width = VDPY_MIN_WIDTH;
if (vdpy.width > VDPY_MAX_WIDTH) if (vdpy.guest_width > VDPY_MAX_WIDTH)
vdpy.width = VDPY_MAX_WIDTH; vdpy.guest_width = VDPY_MAX_WIDTH;
if (vdpy.height < VDPY_MIN_HEIGHT) if (vdpy.guest_height < VDPY_MIN_HEIGHT)
vdpy.height = VDPY_MIN_HEIGHT; vdpy.guest_height = VDPY_MIN_HEIGHT;
if (vdpy.height > VDPY_MAX_HEIGHT) if (vdpy.guest_height > VDPY_MAX_HEIGHT)
vdpy.height = VDPY_MAX_HEIGHT; vdpy.guest_height = VDPY_MAX_HEIGHT;
} else { } else {
/* the default window(1280x720) is created with undefined pos /* the default window(1280x720) is created with undefined pos
* when no geometry info is passed * when no geometry info is passed
*/ */
vdpy.org_x = 0xFFFF; vdpy.org_x = 0xFFFF;
vdpy.org_y = 0xFFFF; vdpy.org_y = 0xFFFF;
vdpy.width = VDPY_DEFAULT_WIDTH; vdpy.guest_width = VDPY_DEFAULT_WIDTH;
vdpy.height = VDPY_DEFAULT_HEIGHT; vdpy.guest_height = VDPY_DEFAULT_HEIGHT;
} }
vdpy.info.xoff = vdpy.org_x;
vdpy.info.yoff = vdpy.org_y;
vdpy.info.width = vdpy.guest_width;
vdpy.info.height = vdpy.guest_height;
win_flags = SDL_WINDOW_OPENGL | win_flags = SDL_WINDOW_OPENGL |
SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_ALWAYS_ON_TOP |
SDL_WINDOW_SHOWN; SDL_WINDOW_SHOWN;
if (vdpy.s.is_fullscreen) { if (vdpy.s.is_fullscreen) {
win_flags |= SDL_WINDOW_FULLSCREEN; win_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
vdpy.org_x = vdpy.pscreen_rect.x;
vdpy.org_y = vdpy.pscreen_rect.y;
vdpy.width = vdpy.pscreen_rect.w;
vdpy.height = vdpy.pscreen_rect.h;
} else {
vdpy.width = vdpy.guest_width;
vdpy.height = vdpy.guest_height;
} }
vdpy.dpy_win = NULL; vdpy.dpy_win = NULL;
vdpy.dpy_renderer = NULL; vdpy.dpy_renderer = NULL;
vdpy.dpy_img = NULL; vdpy.dpy_img = NULL;
// Zoom to width and height of pscreen is fullscreen enabled
vdpy.dpy_win = SDL_CreateWindow("ACRN_DM", vdpy.dpy_win = SDL_CreateWindow("ACRN_DM",
vdpy.org_x, vdpy.org_y, vdpy.org_x, vdpy.org_y,
vdpy.width, vdpy.height, vdpy.width, vdpy.height,
@ -946,6 +960,9 @@ vdpy_sdl_display_thread(void *data)
pr_err("Failed to Create SDL_Window\n"); pr_err("Failed to Create SDL_Window\n");
goto sdl_fail; goto sdl_fail;
} }
pr_info("SDL display bind to screen %d: [%d,%d,%d,%d].\n", vdpy.pscreen_id,
vdpy.org_x, vdpy.org_y, vdpy.width, vdpy.height);
vdpy.dpy_renderer = SDL_CreateRenderer(vdpy.dpy_win, -1, 0); vdpy.dpy_renderer = SDL_CreateRenderer(vdpy.dpy_win, -1, 0);
if (vdpy.dpy_renderer == NULL) { if (vdpy.dpy_renderer == NULL) {
pr_err("Failed to Create GL_Renderer \n"); pr_err("Failed to Create GL_Renderer \n");
@ -1134,7 +1151,6 @@ int
gfx_ui_init() gfx_ui_init()
{ {
SDL_SysWMinfo info; SDL_SysWMinfo info;
SDL_Rect disp_rect;
setenv("SDL_VIDEO_X11_FORCE_EGL", "1", 1); setenv("SDL_VIDEO_X11_FORCE_EGL", "1", 1);
setenv("SDL_OPENGL_ES_DRIVER", "1", 1); setenv("SDL_OPENGL_ES_DRIVER", "1", 1);
@ -1146,10 +1162,10 @@ gfx_ui_init()
return -1; return -1;
} }
SDL_GetDisplayBounds(0, &disp_rect); SDL_GetDisplayBounds(vdpy.pscreen_id, &vdpy.pscreen_rect);
if (disp_rect.w < VDPY_MIN_WIDTH || if (vdpy.pscreen_rect.w < VDPY_MIN_WIDTH ||
disp_rect.h < VDPY_MIN_HEIGHT) { vdpy.pscreen_rect.h < VDPY_MIN_HEIGHT) {
pr_err("Too small resolutions. Please check the " pr_err("Too small resolutions. Please check the "
" graphics system\n"); " graphics system\n");
SDL_Quit(); SDL_Quit();
@ -1198,17 +1214,19 @@ int vdpy_parse_cmd_option(const char *opts)
str = strcasestr(opts, "geometry="); str = strcasestr(opts, "geometry=");
if (opts && strcasestr(opts, "geometry=fullscreen")) { if (opts && strcasestr(opts, "geometry=fullscreen")) {
snum = sscanf(str, "geometry=fullscreen:%d", &vdpy.screen); snum = sscanf(str, "geometry=fullscreen:%d", &vdpy.pscreen_id);
if (snum != 1) { if (snum != 1) {
vdpy.screen = 0; vdpy.pscreen_id = 0;
} }
vdpy.width = VDPY_MAX_WIDTH; vdpy.org_x = 0;
vdpy.height = VDPY_MAX_HEIGHT; vdpy.org_y = 0;
vdpy.guest_width = VDPY_MAX_WIDTH;
vdpy.guest_height = VDPY_MAX_HEIGHT;
vdpy.s.is_fullscreen = true; vdpy.s.is_fullscreen = true;
pr_info("virtual display: fullscreen.\n"); pr_info("virtual display: fullscreen.\n");
} else if (opts && strcasestr(opts, "geometry=")) { } else if (opts && strcasestr(opts, "geometry=")) {
snum = sscanf(str, "geometry=%dx%d+%d+%d", snum = sscanf(str, "geometry=%dx%d+%d+%d",
&vdpy.width, &vdpy.height, &vdpy.guest_width, &vdpy.guest_height,
&vdpy.org_x, &vdpy.org_y); &vdpy.org_x, &vdpy.org_y);
if (snum != 4) { if (snum != 4) {
pr_err("incorrect geometry option. Should be" pr_err("incorrect geometry option. Should be"
@ -1219,9 +1237,5 @@ int vdpy_parse_cmd_option(const char *opts)
pr_info("virtual display: windowed.\n"); pr_info("virtual display: windowed.\n");
} }
vdpy.info.xoff = 0;
vdpy.info.yoff = 0;
vdpy.info.width = vdpy.width;
vdpy.info.height = vdpy.height;
return error; return error;
} }