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.
This commit is contained in:
Benjamin Otte 2023-04-01 16:09:38 +02:00
parent ea82f50d13
commit 84b235aac1
5 changed files with 36 additions and 28 deletions

View 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);

View 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),

View 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)

View 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);

View 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;