diff options
author | Benjamin Otte <otte@redhat.com> | 2023-04-29 05:07:03 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2023-04-29 05:07:03 +0200 |
commit | 11aaa29a6917458b40266bf72ecbc4ecb8295bee (patch) | |
tree | d47f72631a458d2a949321731bd19ffe4d274341 /gdk | |
parent | b4c859c0113f8802d9c6f047dcf2b689223848da (diff) | |
download | gtk+-11aaa29a6917458b40266bf72ecbc4ecb8295bee.tar.gz |
wayland: Use wl_surface_damage_buffer() in Cairo
... when it is available.
Also introduce the new function gdk_rectangle_transform_affine(), which
looks like overkill for this purpose, but I'm about to use it elsewhere.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdkrectangleprivate.h | 57 | ||||
-rw-r--r-- | gdk/wayland/gdksurface-wayland.c | 18 |
2 files changed, 72 insertions, 3 deletions
diff --git a/gdk/gdkrectangleprivate.h b/gdk/gdkrectangleprivate.h new file mode 100644 index 0000000000..b7857d5037 --- /dev/null +++ b/gdk/gdkrectangleprivate.h @@ -0,0 +1,57 @@ +#pragma once + +#include "gdkrectangle.h" + +#include <math.h> + +G_BEGIN_DECLS + +/* + * gdk_rectangle_transform_affine: + * @src: the rectangle to transform + * @scale_x: scale factor in the X direction. The scale factor + * may be negative or 0. + * @scale_y: scale factor in the Y direction. The scale factor + * may be negative or 0. + * @offset_x: offset of result in X direction. + * @offset_y: offset of result in Y direction. + * @dest: (out caller-allocates): destination rectangle, may be + * identical to @src + * + * Does an affine transform of the source rectangle and stores the + * result in the dest rectangle. If the destination rectangle does + * not fit on integer bounds, the result will be enlarged to make it + * fit. + * (Fun fact: This means with a scale of 0 and an offset of 0.5, + * the resulting rect will have a width of 1.) + * + * The width and height of the result will be positive, even if the + * src rectangle or the scale were negative. + * + * This function can be used with the output of + * gsk_transform_to_affine(). + **/ +static inline void +gdk_rectangle_transform_affine (const GdkRectangle *src, + float scale_x, + float scale_y, + float offset_x, + float offset_y, + GdkRectangle *dest) +{ + float x1, x2, y1, y2; + + x1 = offset_x + src->x * scale_x; + x2 = offset_x + (src->x + src->width) * scale_x; + y1 = offset_y + src->y * scale_y; + y2 = offset_y + (src->y + src->height) * scale_y; + + dest->x = floorf (MIN (x1, x2)); + dest->y = floorf (MIN (y1, y2)); + dest->width = ceilf (MAX (x1, x2)) - dest->x; + dest->height = ceilf (MAX (y1, y2)) - dest->y; +} + + +G_END_DECLS + diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index a4049bab72..483ccec8a2 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -28,6 +28,7 @@ #include "gdkmonitor-wayland.h" #include "gdkpopupprivate.h" #include "gdkprivate-wayland.h" +#include "gdkrectangleprivate.h" #include "gdkseat-wayland.h" #include "gdksurfaceprivate.h" #include "gdktoplevelprivate.h" @@ -468,6 +469,7 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, { GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface); cairo_rectangle_int_t rect; + uint32_t wl_surface_version; int i, n; if (GDK_SURFACE_DESTROYED (surface)) @@ -475,14 +477,15 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, g_assert (_gdk_wayland_is_shm_surface (cairo_surface)); + wl_surface_version = wl_surface_get_version (impl->display_server.wl_surface); + /* Attach this new buffer to the surface */ wl_surface_attach (impl->display_server.wl_surface, _gdk_wayland_shm_surface_get_wl_buffer (cairo_surface), 0, 0); if ((impl->pending_buffer_offset_x || impl->pending_buffer_offset_y) && - wl_surface_get_version (impl->display_server.wl_surface) >= - WL_SURFACE_OFFSET_SINCE_VERSION) + wl_surface_version >= WL_SURFACE_OFFSET_SINCE_VERSION) wl_surface_offset (impl->display_server.wl_surface, impl->pending_buffer_offset_x, impl->pending_buffer_offset_y); @@ -493,7 +496,16 @@ gdk_wayland_surface_attach_image (GdkSurface *surface, for (i = 0; i < n; i++) { cairo_region_get_rectangle (damage, i, &rect); - wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height); + if (wl_surface_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) + { + float scale = gdk_surface_get_scale (surface); + gdk_rectangle_transform_affine (&rect, scale, scale, 0, 0, &rect); + wl_surface_damage_buffer (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height); + } + else + { + wl_surface_damage (impl->display_server.wl_surface, rect.x, rect.y, rect.width, rect.height); + } } } |