Re: [PATCH v3 spice-gtk] Adjust to window scaling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,


On 5/27/19 8:29 PM, Marc-André Lureau wrote:
Hi

On Mon, May 27, 2019 at 10:04 AM Snir Sheriber <ssheribe@xxxxxxxxxx> wrote:
When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2

This issue was also reported at freedesktop gitlab repo:
https://gitlab.freedesktop.org/spice/spice-gtk/issues/99
---
  src/spice-widget-egl.c |  8 ++++----
  src/spice-widget.c     | 31 +++++++++++++++++++++++--------
  2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..f688fd2 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -360,9 +360,9 @@ gboolean spice_egl_realize_display(SpiceDisplay *display, GdkWindow *win, GError
      DISPLAY_DEBUG(display, "egl realize");
      if (!spice_widget_init_egl_win(display, win, err))
          return FALSE;
-
-    spice_egl_resize_display(display, gdk_window_get_width(win),
-                             gdk_window_get_height(win));
+    gint gdk_scale = gdk_window_get_scale_factor(win);
Here too, I suppose gtk_widget_get_scale_factor() would be better.


I used this for consistency although I'm still not sure which one is more consistent :P . If I'm using gtk_* would make sense to get also the sizes with gtk_* function but then
passing the GdkWindow also seems a bit unnecessary..

Another version is attached



+    spice_egl_resize_display(display, gdk_window_get_width(win) * gdk_scale,
+                             gdk_window_get_height(win) * gdk_scale);

      return TRUE;
  }
@@ -427,7 +427,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
  }

  G_GNUC_INTERNAL
-void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h) // w and h should be adjusted to gdk scaling
  {
      SpiceDisplayPrivate *d = display->priv;
      int prog;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 1f2a154..c475c39 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1382,7 +1382,8 @@ static void set_egl_enabled(SpiceDisplay *display, bool enabled)
      }

      if (enabled && d->egl.context_ready) {
-        spice_egl_resize_display(display, d->ww, d->wh);
+        gint gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        spice_egl_resize_display(display, d->ww * gdk_scale, d->wh * gdk_scale);
      }

      d->egl.enabled = enabled;
@@ -1978,11 +1979,16 @@ static void transform_input(SpiceDisplay *display,
      SpiceDisplayPrivate *d = display->priv;
      int display_x, display_y, display_w, display_h;
      double is;
+    gint gdk_scale = 1;

      spice_display_get_scaling(display, NULL,
                                &display_x, &display_y,
                                &display_w, &display_h);
-
+#if HAVE_EGL
+        if (egl_enabled(d)) {
+            gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        }
+#endif
      /* For input we need a different scaling factor in order to
         be able to reach the full width of a display. For instance, consider
         a display of 100 pixels showing in a window 10 pixels wide. The normal
@@ -1998,7 +2004,7 @@ static void transform_input(SpiceDisplay *display,
         coordinates in the inverse direction (window -> display) as the fb size
         (display -> window).
      */
-    is = (double)(d->area.width-1) / (double)(display_w-1);
+    is = ((double)(d->area.width-1) / (double)(display_w-1)) * gdk_scale;

      window_x -= display_x;
      window_y -= display_y;
@@ -2183,8 +2189,10 @@ static void size_allocate(GtkWidget *widget, GtkAllocation *conf, gpointer data)
          d->wh = conf->height;
          recalc_geometry(widget);
  #if HAVE_EGL
-        if (egl_enabled(d))
-            spice_egl_resize_display(display, conf->width, conf->height);
+        if (egl_enabled(d)) {
+            gint gdk_scale = gtk_widget_get_scale_factor(widget);
+            spice_egl_resize_display(display, conf->width * gdk_scale, conf->height * gdk_scale);
+        }
  #endif
      }

@@ -2942,10 +2950,16 @@ void spice_display_get_scaling(SpiceDisplay *display,
      int ww, wh;
      int x, y, w, h;
      double s;
+    gint gdk_scale = 1;

      if (gtk_widget_get_realized (GTK_WIDGET(display))) {
-        ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
-        wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+#if HAVE_EGL
+        if (egl_enabled(d)) {
+            gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        }
+#endif
+        ww = gtk_widget_get_allocated_width(GTK_WIDGET(display)) * gdk_scale;
+        wh = gtk_widget_get_allocated_height(GTK_WIDGET(display)) * gdk_scale;
      } else {
          ww = fbw;
          wh = fbh;
@@ -3091,7 +3105,8 @@ void spice_display_widget_gl_scanout(SpiceDisplay *display)
              g_clear_error(&err);
          }

-        spice_egl_resize_display(display, d->ww, d->wh);
+        gint gdk_scale = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        spice_egl_resize_display(display, d->ww * gdk_scale, d->wh * gdk_scale);
      }
  #endif

--
2.21.0

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel


>From a9f677ef4725a8331b30dc3dfb43963cc2c15694 Mon Sep 17 00:00:00 2001
From: Snir Sheriber <ssheribe@xxxxxxxxxx>
Date: Thu, 28 Feb 2019 11:44:34 +0200
Subject: [PATCH v4 spice-gtk] Adjust to window scaling

When GDK_SCALE is != 1 and egl is used, the image presented does not
fit to the window (scale of 2 is often used with hidpi monitors).
Usually this is not a problem since all components are adjusted by
gdk/gtk but with egl, pixel-based data is not being scaled. In this
case window's scale value can be used in order to determine whether
to use a pixel resource with higher resolution data.

In order to reproduce the problem set spice with virgl/Intel-vGPU
and run spice-gtk with GDK_SCALE=2

This issue was also reported at freedesktop gitlab repo:
https://gitlab.freedesktop.org/spice/spice-gtk/issues/99
---
Changes from v3:
-rename gdk_scale to scale_factor
-extract scale from gtk widget instead of gdk window
---
 src/spice-widget-egl.c |  8 ++++----
 src/spice-widget.c     | 31 +++++++++++++++++++++++--------
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/spice-widget-egl.c b/src/spice-widget-egl.c
index 43fccd7..4c2a58e 100644
--- a/src/spice-widget-egl.c
+++ b/src/spice-widget-egl.c
@@ -360,9 +360,9 @@ gboolean spice_egl_realize_display(SpiceDisplay *display, GdkWindow *win, GError
     DISPLAY_DEBUG(display, "egl realize");
     if (!spice_widget_init_egl_win(display, win, err))
         return FALSE;
-
-    spice_egl_resize_display(display, gdk_window_get_width(win),
-                             gdk_window_get_height(win));
+    gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+    spice_egl_resize_display(display, gdk_window_get_width(win) * scale_factor,
+                             gdk_window_get_height(win) * scale_factor);
 
     return TRUE;
 }
@@ -427,7 +427,7 @@ void spice_egl_unrealize_display(SpiceDisplay *display)
 }
 
 G_GNUC_INTERNAL
-void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h) // w and h should be adjusted to gdk scaling
 {
     SpiceDisplayPrivate *d = display->priv;
     int prog;
diff --git a/src/spice-widget.c b/src/spice-widget.c
index 1f2a154..a2651ff 100644
--- a/src/spice-widget.c
+++ b/src/spice-widget.c
@@ -1382,7 +1382,8 @@ static void set_egl_enabled(SpiceDisplay *display, bool enabled)
     }
 
     if (enabled && d->egl.context_ready) {
-        spice_egl_resize_display(display, d->ww, d->wh);
+        gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        spice_egl_resize_display(display, d->ww * scale_factor, d->wh * scale_factor);
     }
 
     d->egl.enabled = enabled;
@@ -1978,11 +1979,16 @@ static void transform_input(SpiceDisplay *display,
     SpiceDisplayPrivate *d = display->priv;
     int display_x, display_y, display_w, display_h;
     double is;
+    gint scale_factor = 1;
 
     spice_display_get_scaling(display, NULL,
                               &display_x, &display_y,
                               &display_w, &display_h);
-
+#if HAVE_EGL
+        if (egl_enabled(d)) {
+            scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        }
+#endif
     /* For input we need a different scaling factor in order to
        be able to reach the full width of a display. For instance, consider
        a display of 100 pixels showing in a window 10 pixels wide. The normal
@@ -1998,7 +2004,7 @@ static void transform_input(SpiceDisplay *display,
        coordinates in the inverse direction (window -> display) as the fb size
        (display -> window).
     */
-    is = (double)(d->area.width-1) / (double)(display_w-1);
+    is = ((double)(d->area.width-1) / (double)(display_w-1)) * scale_factor;
 
     window_x -= display_x;
     window_y -= display_y;
@@ -2183,8 +2189,10 @@ static void size_allocate(GtkWidget *widget, GtkAllocation *conf, gpointer data)
         d->wh = conf->height;
         recalc_geometry(widget);
 #if HAVE_EGL
-        if (egl_enabled(d))
-            spice_egl_resize_display(display, conf->width, conf->height);
+        if (egl_enabled(d)) {
+            gint scale_factor = gtk_widget_get_scale_factor(widget);
+            spice_egl_resize_display(display, conf->width * scale_factor, conf->height * scale_factor);
+        }
 #endif
     }
 
@@ -2942,10 +2950,16 @@ void spice_display_get_scaling(SpiceDisplay *display,
     int ww, wh;
     int x, y, w, h;
     double s;
+    gint scale_factor = 1;
 
     if (gtk_widget_get_realized (GTK_WIDGET(display))) {
-        ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
-        wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+#if HAVE_EGL
+        if (egl_enabled(d)) {
+            scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        }
+#endif
+        ww = gtk_widget_get_allocated_width(GTK_WIDGET(display)) * scale_factor;
+        wh = gtk_widget_get_allocated_height(GTK_WIDGET(display)) * scale_factor;
     } else {
         ww = fbw;
         wh = fbh;
@@ -3091,7 +3105,8 @@ void spice_display_widget_gl_scanout(SpiceDisplay *display)
             g_clear_error(&err);
         }
 
-        spice_egl_resize_display(display, d->ww, d->wh);
+        gint scale_factor = gtk_widget_get_scale_factor(GTK_WIDGET(display));
+        spice_egl_resize_display(display, d->ww * scale_factor, d->wh * scale_factor);
     }
 #endif
 
-- 
2.21.0

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/spice-devel

[Index of Archives]     [Linux Virtualization]     [Linux Virtualization]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]