Make fractional scaling for GL opt-in
authorMatthias Clasen <mclasen@redhat.com>
Sun, 2 Apr 2023 14:24:37 +0000 (10:24 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 2 Apr 2023 15:05:57 +0000 (11:05 -0400)
Fractional scaling with the GL renderer is
experimental for now, so we disable it unless
GDK_DEBUG=gl-fractional is set.

This will give us time to work out the kinks.

gdk/gdk.c
gdk/gdkdebugprivate.h
gdk/gdkglcontext.c
gdk/gdkglcontextprivate.h
gdk/wayland/gdksurface-wayland.c
gsk/gl/gskglrenderer.c

index 3d1457e07568183e09840548c518e5522be89b60..8c0bdaff00b2f94dba7f243873f974abb7e7bd1e 100644 (file)
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -121,6 +121,7 @@ static const GdkDebugKey gdk_debug_keys[] = {
   { "portals",         GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
   { "no-portals",      GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
   { "gl-disable",      GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
+  { "gl-fractional",   GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE },
   { "gl-debug",        GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
   { "gl-legacy",       GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
   { "gl-gles",         GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE },
index bbcf2d46304284f340c835175228edf462a8de84..d41cf3178f6fde8f8e95e3bbbd19fcbe39798af2 100644 (file)
@@ -41,6 +41,7 @@ typedef enum {
   GDK_DEBUG_PORTALS         = 1 << 12,
   GDK_DEBUG_NO_PORTALS      = 1 << 13,
   GDK_DEBUG_GL_DISABLE      = 1 << 14,
+  GDK_DEBUG_GL_FRACTIONAL   = 1 << 15,
   GDK_DEBUG_GL_LEGACY       = 1 << 16,
   GDK_DEBUG_GL_GLES         = 1 << 17,
   GDK_DEBUG_GL_DEBUG        = 1 << 18,
index b8972e57f8a9ffbfd875bf636d93a4281eac22c8..8614ec3e837f8ec9fac8d512541bbcc2e7778cad 100644 (file)
@@ -560,6 +560,23 @@ gdk_gl_context_real_make_current (GdkGLContext *context,
 #endif
 }
 
+double
+gdk_gl_context_get_scale (GdkGLContext *self)
+{
+  GdkDisplay *display;
+  GdkSurface *surface;
+  double scale;
+
+  surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self));
+  scale = gdk_surface_get_scale (surface);
+
+  display = gdk_gl_context_get_display (self);
+  if (!(gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL))
+    scale = ceil (scale);
+
+  return scale;
+}
+
 static void
 gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
                                  gboolean        prefers_high_depth,
@@ -569,9 +586,11 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
   G_GNUC_UNUSED GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
   GdkSurface *surface;
   cairo_region_t *damage;
+  double scale;
   int ww, wh;
 
   surface = gdk_draw_context_get_surface (draw_context);
+  scale = gdk_gl_context_get_scale (context);
 
 #ifdef HAVE_EGL
   if (priv->egl_context)
@@ -588,8 +607,8 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
   cairo_region_union (region, damage);
   cairo_region_destroy (damage);
 
-  ww = (int) ceil (gdk_surface_get_width (surface) * gdk_surface_get_scale (surface));
-  wh = (int) ceil (gdk_surface_get_height (surface) * gdk_surface_get_scale (surface));
+  ww = (int) ceil (gdk_surface_get_width (surface) * scale);
+  wh = (int) ceil (gdk_surface_get_height (surface) * scale);
 
   gdk_gl_context_make_current (context);
 
@@ -633,7 +652,7 @@ gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
       EGLint *heap_rects = NULL;
       int i, j, n_rects = cairo_region_num_rectangles (painted);
       int surface_height = gdk_surface_get_height (surface);
-      double scale = gdk_surface_get_scale (surface);
+      double scale = gdk_gl_context_get_scale (context);
       EGLint *rects;
 
       if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
index 2f19e96b1ccb11e366fad05567aabd2e6677fb99..847b1c54a0115a5a493ca7178c31aec5d0e091f2 100644 (file)
@@ -167,5 +167,7 @@ gboolean                gdk_gl_context_use_es_bgra              (GdkGLContext
 
 gboolean                gdk_gl_context_has_vertex_half_float    (GdkGLContext    *self) G_GNUC_PURE;
 
+double                  gdk_gl_context_get_scale                (GdkGLContext    *self);
+
 G_END_DECLS
 
index f51f081a43db5b6959fc266c7815c7d46b114d2a..ca27f653731c2c0f4cf5a635ab4ddaadf98ae39e 100644 (file)
@@ -230,6 +230,30 @@ gdk_wayland_surface_maybe_resize (GdkSurface               *surface,
     gdk_wayland_surface_create_wl_surface (surface);
 }
 
+static inline void
+get_egl_window_size (GdkSurface *surface,
+                     int        *width,
+                     int        *height)
+{
+  GdkDisplay *display = gdk_surface_get_display (surface);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+  if (gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL)
+    {
+      GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window", gdk_fractional_scale_to_double (&impl->scale));
+
+      *width = gdk_fractional_scale_scale (&impl->scale, surface->width),
+      *height = gdk_fractional_scale_scale (&impl->scale, surface->height);
+    }
+  else
+    {
+      GDK_DISPLAY_DEBUG (display, OPENGL, "Using integer scale %d for EGL window", gdk_fractional_scale_to_int (&impl->scale));
+
+      *width = surface->width * gdk_fractional_scale_to_int (&impl->scale);
+      *height = surface->height * gdk_fractional_scale_to_int (&impl->scale);
+    }
+}
+
 void
 gdk_wayland_surface_update_size (GdkSurface               *surface,
                                  int32_t                   width,
@@ -258,10 +282,11 @@ gdk_wayland_surface_update_size (GdkSurface               *surface,
     impl->viewport_dirty = TRUE;
 
   if (impl->display_server.egl_window)
-    wl_egl_window_resize (impl->display_server.egl_window,
-                          gdk_fractional_scale_scale (scale, width),
-                          gdk_fractional_scale_scale (scale, height),
-                          0, 0);
+    {
+      int w, h;
+      get_egl_window_size (surface, &w, &h);
+      wl_egl_window_resize (impl->display_server.egl_window, w, h, 0, 0);
+    }
 
   gdk_surface_invalidate_rect (surface, NULL);
 
@@ -1363,10 +1388,11 @@ gdk_wayland_surface_ensure_wl_egl_window (GdkSurface *surface)
 
   if (impl->display_server.egl_window == NULL)
     {
+      int width, height;
+
+      get_egl_window_size (surface, &width, &height);
       impl->display_server.egl_window =
-        wl_egl_window_create (impl->display_server.wl_surface,
-                              gdk_fractional_scale_scale (&impl->scale, surface->width),
-                              gdk_fractional_scale_scale (&impl->scale, surface->height));
+        wl_egl_window_create (impl->display_server.wl_surface, width, height);
       gdk_surface_set_egl_native_window (surface, impl->display_server.egl_window);
     }
 }
index eb3c77c72f7af33e624f30f51c38ae1dd96e6b4c..8451ad95634b49cfa0f11780781f694ac2458059 100644 (file)
@@ -288,7 +288,7 @@ gsk_gl_renderer_render (GskRenderer          *renderer,
   g_assert (root != NULL);
 
   surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context));
-  scale = gdk_surface_get_scale (surface);
+  scale = gdk_gl_context_get_scale (self->context);
 
   viewport.origin.x = 0;
   viewport.origin.y = 0;