[PATCH 4/4] ui: Fix gtk/gl when the scaled virtual console does not fit the window

Alexander Orzechowski posted 4 patches 4 years, 1 month ago
Maintainers: Gerd Hoffmann <kraxel@redhat.com>
There is a newer version of this series
[PATCH 4/4] ui: Fix gtk/gl when the scaled virtual console does not fit the window
Posted by Alexander Orzechowski 4 years, 1 month ago
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(-)

diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 01e4e74ee3..ea72f1817b 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, fbh,
                           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);
     }
 
-- 
2.34.1


Re: [PATCH 4/4] ui: Fix gtk/gl when the scaled virtual console does not fit the window
Posted by Marc-André Lureau 4 years, 1 month ago
Hi

On Sun, Dec 19, 2021 at 6:32 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 doesn't work as expected, the display is not being centered correctly.

---
>  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..ea72f1817b 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, fbh,
>                            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);
>      }
>
> --
> 2.34.1
>
>
>

-- 
Marc-André Lureau
Re: [PATCH 4/4] ui: Fix gtk/gl when the scaled virtual console does not fit the window
Posted by Alexander Orzechowski 4 years, 1 month ago
On 12/21/21 02:48, Marc-André Lureau wrote:

> Hi
>
> On Sun, Dec 19, 2021 at 6:32 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 doesn't work as expected, the display is not being centered 
> correctly.
>
>     ---
>      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..ea72f1817b 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, fbh,
>                                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);
>          }
>
>     -- 
>     2.34.1
>
>
>
>
> -- 
> Marc-André Lureau

It seems glBlitFramebuffer takes two coordinates instead of a width and 
height. I have corrected this locally and I will have v2 up tomorrow. 
Thanks for the thorough testing!

--

Alexander Orzechowski