diff mbox series

[v2,3/3] ui: Fix gtk/gl when the scaled virtual console does not fit the window

Message ID 20211222001051.2295513-4-orzechowski.alexander@gmail.com
State New
Headers show
Series UI fixups | expand

Commit Message

Alexander Orzechowski Dec. 22, 2021, 12:10 a.m. UTC
gtk/gl was incorrectly always rendering as if the 'Zoom to Fit' was
always checked even if it wasn't. This is now using logic closer
to what is being used for the existing cairo code paths.

Signed-off-by: Alexander Orzechowski <orzechowski.alexander@gmail.com>
---
 ui/gtk-gl-area.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

Comments

Marc-André Lureau Dec. 22, 2021, 11:52 a.m. UTC | #1
Hi

On Wed, Dec 22, 2021 at 4:11 AM Alexander Orzechowski <
orzechowski.alexander@gmail.com> wrote:

> gtk/gl was incorrectly always rendering as if the 'Zoom to Fit' was
> always checked even if it wasn't. This is now using logic closer
> to what is being used for the existing cairo code paths.
>
> Signed-off-by: Alexander Orzechowski <orzechowski.alexander@gmail.com>
>

This is definitely an improvement for me (on hidpi), but I have some
questions and I don't have much interest in working on qemu GTK3 code.

(fwiw, I hope the future will be around the gtk4 widget I work on at
https://gitlab.com/marcandre.lureau/qemu-display/)

The 2nd patch should come after this one imho, to avoid intermediary extra
regressions.

---
>  ui/gtk-gl-area.c | 34 +++++++++++++++++++++++++++++-----
>  1 file changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
> index 01e4e74ee3..f4f2dac882 100644
> --- a/ui/gtk-gl-area.c
> +++ b/ui/gtk-gl-area.c
> @@ -41,16 +41,40 @@ void gd_gl_area_draw(VirtualConsole *vc)
>  #ifdef CONFIG_GBM
>      QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
>  #endif
> +    GtkDisplayState *s = vc->s;
>      int ww, wh, ws, y1, y2;
> +    int mx, my;
> +    int fbh, fbw;
>
>      if (!vc->gfx.gls) {
>          return;
>      }
>
>      gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
> +
> +    fbw = surface_width(vc->gfx.ds);
> +    fbh = surface_height(vc->gfx.ds);
> +
>      ws =
> gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area));
> -    ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws;
> -    wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws;
> +    ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
> +    wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
> +
> +    if (s->full_screen) {
> +        vc->gfx.scale_x = (double)ww / fbw;
> +        vc->gfx.scale_y = (double)wh / fbh;
>

Why not keep aspect-ratio in full-screen?

(and hopefully the pointer follows the same size logic, as well as the
2d/cairo & gtk-x11/egl code paths..)

+    } else if (s->free_scale) {
> +        double sx, sy;
> +
> +        sx = (double)ww / fbw;
> +        sy = (double)wh / fbh;
> +
> +        vc->gfx.scale_x = vc->gfx.scale_y = MIN(sx, sy);
> +    }
> +
> +    fbw *= vc->gfx.scale_x * ws;
> +    fbh *= vc->gfx.scale_y * ws;
> +    mx = (ww * ws - fbw) / 2;
> +    my = (wh * ws - fbh) / 2;
>
>      if (vc->gfx.scanout_mode) {
>          if (!vc->gfx.guest_fb.framebuffer) {
> @@ -70,11 +94,11 @@ void gd_gl_area_draw(VirtualConsole *vc)
>          glBindFramebuffer(GL_READ_FRAMEBUFFER,
> vc->gfx.guest_fb.framebuffer);
>          /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
>
> -        glViewport(0, 0, ww, wh);
> +        glViewport(mx, my, fbw, fbh);
>          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, ww, wh,
> +                          mx, my, fbw + mx, fbh + my,
>                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
>  #ifdef CONFIG_GBM
>          if (dmabuf) {
> @@ -98,7 +122,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
>          }
>          gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
>
> -        surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
> +        glViewport(mx, my, fbw, fbh);
>

 We should be able to reuse and share the surface_gl_setup_viewport()
logic, no?
diff mbox series

Patch

diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 01e4e74ee3..f4f2dac882 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -41,16 +41,40 @@  void gd_gl_area_draw(VirtualConsole *vc)
 #ifdef CONFIG_GBM
     QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
 #endif
+    GtkDisplayState *s = vc->s;
     int ww, wh, ws, y1, y2;
+    int mx, my;
+    int fbh, fbw;
 
     if (!vc->gfx.gls) {
         return;
     }
 
     gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
+
+    fbw = surface_width(vc->gfx.ds);
+    fbh = surface_height(vc->gfx.ds);
+
     ws = gdk_window_get_scale_factor(gtk_widget_get_window(vc->gfx.drawing_area));
-    ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area) * ws;
-    wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area) * ws;
+    ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
+    wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
+
+    if (s->full_screen) {
+        vc->gfx.scale_x = (double)ww / fbw;
+        vc->gfx.scale_y = (double)wh / fbh;
+    } else if (s->free_scale) {
+        double sx, sy;
+
+        sx = (double)ww / fbw;
+        sy = (double)wh / fbh;
+
+        vc->gfx.scale_x = vc->gfx.scale_y = MIN(sx, sy);
+    }
+
+    fbw *= vc->gfx.scale_x * ws;
+    fbh *= vc->gfx.scale_y * ws;
+    mx = (ww * ws - fbw) / 2;
+    my = (wh * ws - fbh) / 2;
 
     if (vc->gfx.scanout_mode) {
         if (!vc->gfx.guest_fb.framebuffer) {
@@ -70,11 +94,11 @@  void gd_gl_area_draw(VirtualConsole *vc)
         glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.guest_fb.framebuffer);
         /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
 
-        glViewport(0, 0, ww, wh);
+        glViewport(mx, my, fbw, fbh);
         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, ww, wh,
+                          mx, my, fbw + mx, fbh + my,
                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
 #ifdef CONFIG_GBM
         if (dmabuf) {
@@ -98,7 +122,7 @@  void gd_gl_area_draw(VirtualConsole *vc)
         }
         gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
 
-        surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
+        glViewport(mx, my, fbw, fbh);
         surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
     }