wayland: Use wp_viewport to set buffer scale
authorBenjamin Otte <otte@redhat.com>
Sat, 1 Apr 2023 12:41:30 +0000 (14:41 +0200)
committerBenjamin Otte <otte@redhat.com>
Sat, 1 Apr 2023 18:05:01 +0000 (20:05 +0200)
Instead of setting the buffer scale via the buffer-scale command, set it
via the viewport.

This technically allows setting fractional scales, but we're not doing
that.

gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkdisplay-wayland.h
gdk/wayland/gdksurface-wayland-private.h
gdk/wayland/gdksurface-wayland.c
gdk/wayland/meson.build

index 4a27302904264b9ebeea5892ad11b174d0a7f5d6..9fbf93b938891b238a441dcd5e728d934264b41f 100644 (file)
@@ -516,6 +516,13 @@ gdk_registry_handle_global (void               *data,
                           &wp_fractional_scale_manager_v1_interface,
                           MIN (version, 1));
     }
+  else if (strcmp (interface, "wp_viewporter") == 0)
+    {
+      display_wayland->viewporter =
+        wl_registry_bind (display_wayland->wl_registry, id,
+                          &wp_viewporter_interface,
+                          MIN (version, 1));
+    }
 
 
   g_hash_table_insert (display_wayland->known_globals,
index 6dbe7931579adb0edf2936444b16962f170a019c..b7d9a90c0c69c767731b1ef44def2d2a585acafc 100644 (file)
@@ -38,6 +38,7 @@
 #include <gdk/wayland/primary-selection-unstable-v1-client-protocol.h>
 #include <gdk/wayland/xdg-activation-v1-client-protocol.h>
 #include <gdk/wayland/fractional-scale-v1-client-protocol.h>
+#include <gdk/wayland/viewporter-client-protocol.h>
 
 #include <glib.h>
 #include <gdk/gdkkeys.h>
@@ -113,6 +114,7 @@ struct _GdkWaylandDisplay
   struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
   struct xdg_activation_v1 *xdg_activation;
   struct wp_fractional_scale_manager_v1 *fractional_scale;
+  struct wp_viewporter *viewporter;
 
   GList *async_roundtrips;
 
index e6c08a4bb4da0c9f329e73e26f1a9ac55b81bc71..7f33b448565fc50ced4fda3cbc94b704755d7f81 100644 (file)
@@ -36,6 +36,7 @@ struct _GdkWaylandSurface
     struct zxdg_surface_v6 *zxdg_surface_v6;
     struct wl_egl_window *egl_window;
     struct wp_fractional_scale_v1 *fractional_scale;
+    struct wp_viewport *viewport;
   } display_server;
 
   struct wl_event_queue *event_queue;
@@ -52,6 +53,7 @@ struct _GdkWaylandSurface
   gint64 pending_frame_counter;
   GdkFractionalScale scale;
   gboolean buffer_scale_dirty;
+  gboolean viewport_dirty;
 
   int shadow_left;
   int shadow_right;
index 2581015a2ec57674eb4fd444c32746755f62b097..f19887460c9ec13a7f19de10842f1abf7efcd124 100644 (file)
@@ -61,11 +61,6 @@ G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE)
 
 static void gdk_wayland_surface_configure (GdkSurface *surface);
 
-static void gdk_wayland_surface_sync_shadow (GdkSurface *surface);
-static void gdk_wayland_surface_sync_input_region (GdkSurface *surface);
-static void gdk_wayland_surface_sync_opaque_region (GdkSurface *surface);
-static void gdk_wayland_surface_sync_buffer_scale (GdkSurface *surface);
-
 /* {{{ Utilities */
 
 static void
@@ -176,6 +171,7 @@ static void
 gdk_wayland_surface_init (GdkWaylandSurface *impl)
 {
   impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (1);
+  impl->viewport_dirty = TRUE;
 }
 
 void
@@ -256,7 +252,10 @@ gdk_wayland_surface_update_size (GdkSurface               *surface,
     {
       impl->scale = *scale;
       impl->buffer_scale_dirty = TRUE;
+      impl->viewport_dirty = TRUE;
     }
+  if (width_changed || height_changed)
+    impl->viewport_dirty = TRUE;
 
   if (impl->display_server.egl_window)
     wl_egl_window_resize (impl->display_server.egl_window,
@@ -617,15 +616,6 @@ gdk_wayland_surface_attach_image (GdkSurface           *surface,
     }
 }
 
-void
-gdk_wayland_surface_sync (GdkSurface *surface)
-{
-  gdk_wayland_surface_sync_shadow (surface);
-  gdk_wayland_surface_sync_opaque_region (surface);
-  gdk_wayland_surface_sync_input_region (surface);
-  gdk_wayland_surface_sync_buffer_scale (surface);
-}
-
 static gboolean
 gdk_wayland_surface_beep (GdkSurface *surface)
 {
@@ -781,20 +771,53 @@ gdk_wayland_surface_sync_input_region (GdkSurface *surface)
 static void
 gdk_wayland_surface_sync_buffer_scale (GdkSurface *surface)
 {
-  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+  GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
 
-  if (!impl->display_server.wl_surface)
+  if (!self->display_server.wl_surface)
     return;
 
-  if (!impl->buffer_scale_dirty)
+  if (!self->buffer_scale_dirty)
     return;
 
-  /* Only set the buffer scale if supported by the compositor */
-  if (wl_surface_get_version (impl->display_server.wl_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
-    wl_surface_set_buffer_scale (impl->display_server.wl_surface,
-                                 gdk_fractional_scale_to_int (&impl->scale));
+  if (self->display_server.viewport)
+    {
+      /* The viewport takes care of buffer scale */
+    }
+  else if (wl_surface_get_version (self->display_server.wl_surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION)
+    {
+      wl_surface_set_buffer_scale (self->display_server.wl_surface,
+                                   gdk_fractional_scale_to_int (&self->scale));
+    }
 
-  impl->buffer_scale_dirty = FALSE;
+  self->buffer_scale_dirty = FALSE;
+}
+
+static void
+gdk_wayland_surface_sync_viewport (GdkSurface *surface)
+{
+  GdkWaylandSurface *self = GDK_WAYLAND_SURFACE (surface);
+
+  if (!self->display_server.viewport)
+    return;
+
+  if (!self->viewport_dirty)
+    return;
+
+  wp_viewport_set_destination (self->display_server.viewport,
+                               surface->width,
+                               surface->height);
+
+  self->viewport_dirty = FALSE;
+}
+
+void
+gdk_wayland_surface_sync (GdkSurface *surface)
+{
+  gdk_wayland_surface_sync_shadow (surface);
+  gdk_wayland_surface_sync_opaque_region (surface);
+  gdk_wayland_surface_sync_input_region (surface);
+  gdk_wayland_surface_sync_buffer_scale (surface);
+  gdk_wayland_surface_sync_viewport (surface);
 }
 
 static void
@@ -881,6 +904,11 @@ gdk_wayland_surface_create_wl_surface (GdkSurface *surface)
       wp_fractional_scale_v1_add_listener (self->display_server.fractional_scale,
                                            &fractional_scale_listener, self);
     }
+  if (display_wayland->viewporter)
+    {
+      self->display_server.viewport =
+          wp_viewporter_get_viewport (display_wayland->viewporter, wl_surface);
+    }
 
   self->display_server.wl_surface = wl_surface;
 }
@@ -1051,6 +1079,7 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
         }
 
       g_clear_pointer (&impl->display_server.fractional_scale, wp_fractional_scale_v1_destroy);
+      g_clear_pointer (&impl->display_server.viewport, wp_viewport_destroy);
 
       g_clear_pointer (&impl->display_server.wl_surface, wl_surface_destroy);
 
@@ -1061,6 +1090,7 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
   impl->has_uncommitted_ack_configure = FALSE;
   impl->input_region_dirty = TRUE;
   impl->opaque_region_dirty = TRUE;
+  impl->viewport_dirty = TRUE;
   if (!gdk_fractional_scale_equal (&impl->scale, &GDK_FRACTIONAL_SCALE_INIT_INT (1)))
     impl->buffer_scale_dirty = TRUE;
 
index 67d16e01f5675c17c61efdf8cb94afc94ed4bf0c..d325b4edea279d3128f9b4e3353f0278984b525d 100644 (file)
@@ -55,6 +55,7 @@ proto_sources = [
   ['gtk-shell', 'private', ],
   ['primary-selection', 'unstable', 'v1', ],
   ['pointer-gestures', 'unstable', 'v1', ],
+  ['viewporter', 'stable', ],
   ['xdg-shell', 'unstable', 'v6', ],
   ['xdg-shell', 'stable', ],
   ['xdg-foreign', 'unstable', 'v1', ],