mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
Merge branch 'wip/otte/for-main' into 'main'
wayland: Use wl_surface_damage_buffer() in Cairo See merge request GNOME/gtk!5886
This commit is contained in:
commit
c542351a73
57
gdk/gdkrectangleprivate.h
Normal file
57
gdk/gdkrectangleprivate.h
Normal file
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
#include "gdk/gdkprivate.h"
|
||||
#include "gdk/gdkrectangleprivate.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
@ -74,6 +75,25 @@ _graphene_rect_init_from_clip_extents (graphene_rect_t *rect,
|
||||
graphene_rect_init (rect, x1c, y1c, x2c - x1c, y2c - y1c);
|
||||
}
|
||||
|
||||
static void
|
||||
region_union_region_affine (cairo_region_t *region,
|
||||
const cairo_region_t *sub,
|
||||
float scale_x,
|
||||
float scale_y,
|
||||
float offset_x,
|
||||
float offset_y)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cairo_region_num_rectangles (sub); i++)
|
||||
{
|
||||
cairo_region_get_rectangle (sub, i, &rect);
|
||||
gdk_rectangle_transform_affine (&rect, scale_x, scale_y, offset_x, offset_y, &rect);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ GSK_COLOR_NODE */
|
||||
|
||||
/**
|
||||
@ -3354,11 +3374,22 @@ gsk_transform_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
{
|
||||
cairo_region_t *sub;
|
||||
float scale_x, scale_y, dx, dy;
|
||||
gsk_transform_to_affine (self1->transform, &scale_x, &scale_y, &dx, &dy);
|
||||
sub = cairo_region_create ();
|
||||
gsk_render_node_diff (self1->child, self2->child, sub);
|
||||
region_union_region_affine (region, sub, scale_x, scale_y, dx, dy);
|
||||
cairo_region_destroy (sub);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
default:
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user