aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeifeng Liu <weifeng.liu.z@gmail.com>2025-05-11 15:33:18 +0800
committerMarc-André Lureau <marcandre.lureau@redhat.com>2025-05-24 17:04:00 +0200
commitfdc09b028fde9d2ec70418735f354b51c8295d0f (patch)
tree59103a3b4b297e2c009c8f8a206174a4fcf2071c
parenta1b28f71f7ff0fcafbe0672b788e8e57ee4fe8f6 (diff)
downloadqemu-fdc09b028fde9d2ec70418735f354b51c8295d0f.zip
qemu-fdc09b028fde9d2ec70418735f354b51c8295d0f.tar.gz
qemu-fdc09b028fde9d2ec70418735f354b51c8295d0f.tar.bz2
ui/gtk-gl-area: Render guest content with padding in fixed-scale mode
In fixed-scale mode (zoom-to-fit=false), we expect that scale should not change, meaning that if window size is larger than guest surface, padding is supposed to be added to preserve the scale. However, in OpenGL mode (gl=on), guest surface is always painted to the whole canvas without any padding. This change tries to fix this bug by adding appropriate padding when drawing surfaces. Signed-off-by: Weifeng Liu <weifeng.liu.z@gmail.com> Message-ID: <20250511073337.876650-9-weifeng.liu.z@gmail.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-rw-r--r--ui/gtk-gl-area.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index db93cd6..8151cc4 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -44,7 +44,9 @@ void gd_gl_area_draw(VirtualConsole *vc)
#endif
int pw, ph, gs, y1, y2;
int ww, wh;
+ int ww_surface, wh_surface;
int fbw, fbh;
+ int wx_offset, wy_offset;
if (!vc->gfx.gls) {
return;
@@ -61,6 +63,17 @@ void gd_gl_area_draw(VirtualConsole *vc)
gd_update_scale(vc, ww, wh, fbw, fbh);
+ ww_surface = fbw * vc->gfx.scale_x;
+ wh_surface = fbh * vc->gfx.scale_y;
+
+ wx_offset = wy_offset = 0;
+ if (ww > ww_surface) {
+ wx_offset = (ww - ww_surface) / 2;
+ }
+ if (wh > wh_surface) {
+ wy_offset = (wh - wh_surface) / 2;
+ }
+
if (vc->gfx.scanout_mode) {
if (!vc->gfx.guest_fb.framebuffer) {
return;
@@ -79,11 +92,29 @@ void gd_gl_area_draw(VirtualConsole *vc)
glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
/* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
+ if (wx_offset > 0) {
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0, 0, wx_offset * gs, wh * gs);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glScissor((ww - wx_offset) * gs, 0, wx_offset * gs, wh * gs);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_SCISSOR_TEST);
+ }
+ if (wy_offset > 0) {
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(0, 0, ww * gs, wy_offset * gs);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glScissor(0, (wh - wy_offset) * gs, ww * gs, wy_offset * gs);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDisable(GL_SCISSOR_TEST);
+ }
+
glViewport(0, 0, pw, ph);
y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
glBlitFramebuffer(0, y1, vc->gfx.w, y2,
- 0, 0, pw, ph,
+ wx_offset * gs, wy_offset * gs,
+ (ww - wx_offset) * gs, (wh - wy_offset) * gs,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
#ifdef CONFIG_GBM
if (dmabuf) {