summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-01 16:09:38 +0200
committerBenjamin Otte <otte@redhat.com>2023-04-01 20:05:05 +0200
commit84b235aac1f460721ca79efdebcf1894a21b0942 (patch)
treebd02a91afd95f19b50c40fad314b7d6629c6521d
parentea82f50d13ae3da35b7e57880b919559a3f8bae2 (diff)
downloadgtk+-84b235aac1f460721ca79efdebcf1894a21b0942.tar.gz
wayland: Allow creating fractional Cairo surfaces
We don't do that yet, because the buffer scale code can't deal with it, but we can do it now.
-rw-r--r--gdk/wayland/gdkcairocontext-wayland.c6
-rw-r--r--gdk/wayland/gdkcursor-wayland.c8
-rw-r--r--gdk/wayland/gdkdisplay-wayland.c29
-rw-r--r--gdk/wayland/gdkprivate-wayland.h18
-rw-r--r--gdk/wayland/gdksurface-wayland-private.h3
5 files changed, 36 insertions, 28 deletions
diff --git a/gdk/wayland/gdkcairocontext-wayland.c b/gdk/wayland/gdkcairocontext-wayland.c
index b75353b577..eb54c9ccab 100644
--- a/gdk/wayland/gdkcairocontext-wayland.c
+++ b/gdk/wayland/gdkcairocontext-wayland.c
@@ -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);
diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c
index 41cd2e4fc4..35a07b564a 100644
--- a/gdk/wayland/gdkcursor-wayland.c
+++ b/gdk/wayland/gdkcursor-wayland.c
@@ -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),
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 9fbf93b938..1aa66ae09b 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -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)
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 0276d4c70d..8db2dd8f49 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -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);
diff --git a/gdk/wayland/gdksurface-wayland-private.h b/gdk/wayland/gdksurface-wayland-private.h
index 7f33b44856..1d87cc4b09 100644
--- a/gdk/wayland/gdksurface-wayland-private.h
+++ b/gdk/wayland/gdksurface-wayland-private.h
@@ -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;