mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 02:24:58 -06:00
ui/gtk-egl: Render guest content with padding in fixed-scale mode
Scaling was not respected when rendering frames in gtk-egl.c (used if gl=on and X11 mode). To fix this, add fields x and y to struct egl_fb for x offset and y offset so we can add padding to window. Signed-off-by: Weifeng Liu <weifeng.liu.z@gmail.com> Message-ID: <20250511073337.876650-10-weifeng.liu.z@gmail.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
parent
fdc09b028f
commit
f05e1a93f4
4 changed files with 43 additions and 9 deletions
|
@ -17,6 +17,8 @@ extern bool qemu_egl_angle_d3d;
|
|||
typedef struct egl_fb {
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
GLuint texture;
|
||||
GLuint framebuffer;
|
||||
bool delete_texture;
|
||||
|
@ -26,7 +28,7 @@ typedef struct egl_fb {
|
|||
#define EGL_FB_INIT { 0, }
|
||||
|
||||
void egl_fb_destroy(egl_fb *fb);
|
||||
void egl_fb_setup_default(egl_fb *fb, int width, int height);
|
||||
void egl_fb_setup_default(egl_fb *fb, int width, int height, int x, int y);
|
||||
void egl_fb_setup_for_tex(egl_fb *fb, int width, int height,
|
||||
GLuint texture, bool delete);
|
||||
void egl_fb_setup_new_tex(egl_fb *fb, int width, int height);
|
||||
|
|
|
@ -93,14 +93,18 @@ void egl_fb_destroy(egl_fb *fb)
|
|||
|
||||
fb->width = 0;
|
||||
fb->height = 0;
|
||||
fb->x = 0;
|
||||
fb->y = 0;
|
||||
fb->texture = 0;
|
||||
fb->framebuffer = 0;
|
||||
}
|
||||
|
||||
void egl_fb_setup_default(egl_fb *fb, int width, int height)
|
||||
void egl_fb_setup_default(egl_fb *fb, int width, int height, int x, int y)
|
||||
{
|
||||
fb->width = width;
|
||||
fb->height = height;
|
||||
fb->x = x;
|
||||
fb->y = y;
|
||||
fb->framebuffer = 0; /* default framebuffer */
|
||||
}
|
||||
|
||||
|
@ -145,6 +149,7 @@ void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
|
|||
glBindFramebuffer(GL_READ_FRAMEBUFFER, src->framebuffer);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->framebuffer);
|
||||
glViewport(0, 0, dst->width, dst->height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (src->dmabuf) {
|
||||
x1 = qemu_dmabuf_get_x(src->dmabuf);
|
||||
|
@ -161,7 +166,8 @@ void egl_fb_blit(egl_fb *dst, egl_fb *src, bool flip)
|
|||
x2 = x1 + w;
|
||||
|
||||
glBlitFramebuffer(x1, y1, x2, y2,
|
||||
0, 0, dst->width, dst->height,
|
||||
dst->x, dst->y,
|
||||
dst->x + dst->width, dst->y + dst->height,
|
||||
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
}
|
||||
|
||||
|
|
36
ui/gtk-egl.c
36
ui/gtk-egl.c
|
@ -340,7 +340,11 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
|||
{
|
||||
VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
|
||||
GdkWindow *window;
|
||||
int ww, wh, ws;
|
||||
int px_offset, py_offset;
|
||||
int gs;
|
||||
int pw_widget, ph_widget, pw_surface, ph_surface;
|
||||
int ww_widget, wh_widget, ww_surface, wh_surface;
|
||||
int fbw, fbh;
|
||||
|
||||
if (!vc->gfx.scanout_mode) {
|
||||
return;
|
||||
|
@ -353,10 +357,32 @@ void gd_egl_scanout_flush(DisplayChangeListener *dcl,
|
|||
vc->gfx.esurface, vc->gfx.ectx);
|
||||
|
||||
window = gtk_widget_get_window(vc->gfx.drawing_area);
|
||||
ws = gdk_window_get_scale_factor(window);
|
||||
ww = gdk_window_get_width(window) * ws;
|
||||
wh = gdk_window_get_height(window) * ws;
|
||||
egl_fb_setup_default(&vc->gfx.win_fb, ww, wh);
|
||||
gs = gdk_window_get_scale_factor(window);
|
||||
ww_widget = gdk_window_get_width(window);
|
||||
wh_widget = gdk_window_get_height(window);
|
||||
fbw = surface_width(vc->gfx.ds);
|
||||
fbh = surface_height(vc->gfx.ds);
|
||||
|
||||
gd_update_scale(vc, ww_widget, wh_widget, fbw, fbh);
|
||||
|
||||
ww_surface = fbw * vc->gfx.scale_x;
|
||||
wh_surface = fbh * vc->gfx.scale_y;
|
||||
pw_widget = ww_widget * gs;
|
||||
ph_widget = wh_widget * gs;
|
||||
pw_surface = ww_surface * gs;
|
||||
ph_surface = wh_surface * gs;
|
||||
|
||||
px_offset = 0;
|
||||
py_offset = 0;
|
||||
if (pw_widget > pw_surface) {
|
||||
px_offset = (pw_widget - pw_surface) / 2;
|
||||
}
|
||||
if (ph_widget > ph_surface) {
|
||||
py_offset = (ph_widget - ph_surface) / 2;
|
||||
}
|
||||
|
||||
egl_fb_setup_default(&vc->gfx.win_fb, pw_surface, ph_surface,
|
||||
px_offset, py_offset);
|
||||
if (vc->gfx.cursor_fb.texture) {
|
||||
egl_texture_blit(vc->gfx.gls, &vc->gfx.win_fb, &vc->gfx.guest_fb,
|
||||
vc->gfx.y0_top);
|
||||
|
|
|
@ -241,7 +241,7 @@ void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
|
|||
SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
|
||||
|
||||
SDL_GetWindowSize(scon->real_window, &ww, &wh);
|
||||
egl_fb_setup_default(&scon->win_fb, ww, wh);
|
||||
egl_fb_setup_default(&scon->win_fb, ww, wh, 0, 0);
|
||||
egl_fb_blit(&scon->win_fb, &scon->guest_fb, !scon->y0_top);
|
||||
|
||||
SDL_GL_SwapWindow(scon->real_window);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue