wayland: Allow creating fractional Cairo surfaces
authorBenjamin Otte <otte@redhat.com>
Sat, 1 Apr 2023 14:09:38 +0000 (16:09 +0200)
committerBenjamin Otte <otte@redhat.com>
Sat, 1 Apr 2023 18:05:05 +0000 (20:05 +0200)
We don't do that yet, because the buffer scale code can't deal with it,
but we can do it now.

gdk/wayland/gdkcairocontext-wayland.c
gdk/wayland/gdkcursor-wayland.c
gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkprivate-wayland.h
gdk/wayland/gdksurface-wayland-private.h

index b75353b5771a5bd99d05eec917b5947d047fdaf9..eb54c9ccab312bdca790f587f63dc1455880b1ed 100644 (file)
@@ -128,9 +128,9 @@ gdk_wayland_cairo_context_create_surface (GdkWaylandCairoContext *self)
 
   width = gdk_surface_get_width (surface);
   height = gdk_surface_get_height (surface);
-  cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
-                                                           width, height,
-                                                           gdk_surface_get_scale_factor (surface));
+  cairo_surface = gdk_wayland_display_create_shm_surface (display_wayland,
+                                                          width, height,
+                                                          &GDK_FRACTIONAL_SCALE_INIT_INT (gdk_surface_get_scale_factor (surface)));
   buffer = _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface);
   wl_buffer_add_listener (buffer, &buffer_listener, cairo_surface);
   gdk_wayland_cairo_context_add_surface (self, cairo_surface);
index 41cd2e4fc4a90eaba27d848e1637ae11c6e85517..35a07b564a534b29aa19f9271e33b0804587a369 100644 (file)
@@ -221,10 +221,10 @@ from_texture:
       surface = g_hash_table_lookup (display->cursor_surface_cache, cursor);
       if (surface == NULL)
         {
-          surface = _gdk_wayland_display_create_shm_surface (display,
-                                                             gdk_texture_get_width (texture),
-                                                             gdk_texture_get_height (texture),
-                                                             1);
+          surface = gdk_wayland_display_create_shm_surface (display,
+                                                            gdk_texture_get_width (texture),
+                                                            gdk_texture_get_height (texture),
+                                                            &GDK_FRACTIONAL_SCALE_INIT_INT (1));
           
           gdk_texture_download (texture,
                                 cairo_image_surface_get_data (surface),
index 9fbf93b938891b238a441dcd5e728d934264b41f..1aa66ae09bee86fe82497b58b478f2668dc11802 100644 (file)
@@ -1188,7 +1188,7 @@ typedef struct _GdkWaylandCairoSurfaceData {
   struct wl_shm_pool *pool;
   struct wl_buffer *buffer;
   GdkWaylandDisplay *display;
-  uint32_t scale;
+  GdkFractionalScale scale;
 } GdkWaylandCairoSurfaceData;
 
 static int
@@ -1313,25 +1313,28 @@ gdk_wayland_cairo_surface_destroy (void *p)
 }
 
 cairo_surface_t *
-_gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
-                                         int                width,
-                                         int                height,
-                                         guint              scale)
+gdk_wayland_display_create_shm_surface (GdkWaylandDisplay        *display,
+                                        int                       width,
+                                        int                       height,
+                                        const GdkFractionalScale *scale)
 {
   GdkWaylandCairoSurfaceData *data;
   cairo_surface_t *surface = NULL;
   cairo_status_t status;
+  int scaled_width, scaled_height;
   int stride;
 
   data = g_new (GdkWaylandCairoSurfaceData, 1);
   data->display = display;
   data->buffer = NULL;
-  data->scale = scale;
+  data->scale = *scale;
 
-  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width * scale);
+  scaled_width = gdk_fractional_scale_scale (scale, width);
+  scaled_height = gdk_fractional_scale_scale (scale, height);
+  stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, scaled_width);
 
   data->pool = create_shm_pool (display->shm,
-                                height * scale * stride,
+                                scaled_height * stride,
                                 &data->buf_length,
                                 &data->buf);
   if (G_UNLIKELY (data->pool == NULL))
@@ -1339,18 +1342,20 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
 
   surface = cairo_image_surface_create_for_data (data->buf,
                                                  CAIRO_FORMAT_ARGB32,
-                                                 width * scale,
-                                                 height * scale,
+                                                 scaled_width,
+                                                 scaled_height,
                                                  stride);
 
   data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
-                                            width * scale, height * scale,
+                                            scaled_width, scaled_height,
                                             stride, WL_SHM_FORMAT_ARGB8888);
 
   cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key,
                                data, gdk_wayland_cairo_surface_destroy);
 
-  cairo_surface_set_device_scale (surface, scale, scale);
+  cairo_surface_set_device_scale (surface,
+                                  gdk_fractional_scale_to_double (scale),
+                                  gdk_fractional_scale_to_double (scale));
 
   status = cairo_surface_status (surface);
   if (status != CAIRO_STATUS_SUCCESS)
index 0276d4c70d2b41995c2c6700ad4d757dd7c01e73..8db2dd8f49c09c5e16692bd3ddfb31b182253c08 100644 (file)
@@ -128,11 +128,11 @@ guint      _gdk_wayland_cursor_get_next_image_index (GdkWaylandDisplay *display,
                                                      guint              current_image_index,
                                                      guint             *next_image_delay);
 
-void       gdk_wayland_surface_sync (GdkSurface *surface);
-void       gdk_wayland_surface_commit (GdkSurface *surface);
-void       gdk_wayland_surface_notify_committed (GdkSurface *surface);
-void       gdk_wayland_surface_request_frame (GdkSurface *surface);
-gboolean   gdk_wayland_surface_has_surface (GdkSurface *surface);
+void            gdk_wayland_surface_sync                   (GdkSurface           *surface);
+void            gdk_wayland_surface_commit                 (GdkSurface           *surface);
+void            gdk_wayland_surface_notify_committed       (GdkSurface           *surface);
+void            gdk_wayland_surface_request_frame          (GdkSurface           *surface);
+gboolean        gdk_wayland_surface_has_surface            (GdkSurface           *surface);
 void            gdk_wayland_surface_attach_image           (GdkSurface           *surface,
                                                             cairo_surface_t      *cairo_surface,
                                                             const cairo_region_t *damage);
@@ -207,10 +207,10 @@ GdkMonitor *gdk_wayland_display_get_monitor_for_output (GdkDisplay       *displa
 void _gdk_wayland_surface_set_grab_seat (GdkSurface      *surface,
                                         GdkSeat        *seat);
 
-cairo_surface_t * _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
-                                                           int                width,
-                                                           int                height,
-                                                           guint              scale);
+cairo_surface_t * gdk_wayland_display_create_shm_surface  (GdkWaylandDisplay        *display,
+                                                           int                       width,
+                                                           int                       height,
+                                                           const GdkFractionalScale *scale);
 struct wl_buffer *_gdk_wayland_shm_surface_get_wl_buffer (cairo_surface_t *surface);
 gboolean _gdk_wayland_is_shm_surface (cairo_surface_t *surface);
 
index 7f33b448565fc50ced4fda3cbc94b704755d7f81..1d87cc4b0984e54a007feaff0e4f23602ef24439 100644 (file)
@@ -17,6 +17,8 @@
 
 #pragma once
 
+#include "gdkprivate-wayland.h"
+
 typedef enum _PopupState
 {
   POPUP_STATE_IDLE,
@@ -52,6 +54,7 @@ struct _GdkWaylandSurface
 
   gint64 pending_frame_counter;
   GdkFractionalScale scale;
+  gboolean buffer_is_fractional;
   gboolean buffer_scale_dirty;
   gboolean viewport_dirty;