mirror of
https://github.com/brl/mutter.git
synced 2024-12-28 13:52:15 +00:00
wayland/surface: Do not uncoditionally process surface damage
Most clients nowadays switched to buffer damage, most notably Mesa and Xwayland. Thus lets avoid the extra cost of allocating three `cairo_region_t`s and doing some calculations. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2168>
This commit is contained in:
parent
c166811695
commit
c498ae337f
@ -323,12 +323,7 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||||||
cairo_region_t *buffer_region)
|
cairo_region_t *buffer_region)
|
||||||
{
|
{
|
||||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||||
cairo_rectangle_int_t surface_rect;
|
|
||||||
cairo_rectangle_int_t buffer_rect;
|
cairo_rectangle_int_t buffer_rect;
|
||||||
cairo_region_t *scaled_region;
|
|
||||||
cairo_region_t *transformed_region;
|
|
||||||
cairo_region_t *viewport_region;
|
|
||||||
graphene_rect_t src_rect;
|
|
||||||
MetaSurfaceActor *actor;
|
MetaSurfaceActor *actor;
|
||||||
|
|
||||||
/* If the client destroyed the buffer it attached before committing, but
|
/* If the client destroyed the buffer it attached before committing, but
|
||||||
@ -343,59 +338,73 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||||||
.height = get_buffer_height (surface),
|
.height = get_buffer_height (surface),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Intersect the damage region with the surface region before scaling in
|
if (!cairo_region_is_empty (surface_region))
|
||||||
* order to avoid integer overflow when scaling a damage region is too large
|
|
||||||
* (for example INT32_MAX which mesa passes). */
|
|
||||||
surface_rect = (cairo_rectangle_int_t) {
|
|
||||||
.width = meta_wayland_surface_get_width (surface),
|
|
||||||
.height = meta_wayland_surface_get_height (surface),
|
|
||||||
};
|
|
||||||
cairo_region_intersect_rectangle (surface_region, &surface_rect);
|
|
||||||
|
|
||||||
/* The damage region must be in the same coordinate space as the buffer,
|
|
||||||
* i.e. scaled with surface->scale. */
|
|
||||||
if (surface->viewport.has_src_rect)
|
|
||||||
{
|
{
|
||||||
src_rect = (graphene_rect_t) {
|
cairo_rectangle_int_t surface_rect;
|
||||||
.origin.x = surface->viewport.src_rect.origin.x,
|
cairo_region_t *scaled_region;
|
||||||
.origin.y = surface->viewport.src_rect.origin.y,
|
cairo_region_t *transformed_region;
|
||||||
.size.width = surface->viewport.src_rect.size.width,
|
cairo_region_t *viewport_region;
|
||||||
.size.height = surface->viewport.src_rect.size.height
|
graphene_rect_t src_rect;
|
||||||
|
|
||||||
|
/* Intersect the damage region with the surface region before scaling in
|
||||||
|
* order to avoid integer overflow when scaling a damage region is too
|
||||||
|
* large (for example INT32_MAX which mesa passes). */
|
||||||
|
surface_rect = (cairo_rectangle_int_t) {
|
||||||
|
.width = meta_wayland_surface_get_width (surface),
|
||||||
|
.height = meta_wayland_surface_get_height (surface),
|
||||||
};
|
};
|
||||||
}
|
cairo_region_intersect_rectangle (surface_region, &surface_rect);
|
||||||
else
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
if (meta_monitor_transform_is_rotated (surface->buffer_transform))
|
/* The damage region must be in the same coordinate space as the buffer,
|
||||||
|
* i.e. scaled with surface->scale. */
|
||||||
|
if (surface->viewport.has_src_rect)
|
||||||
{
|
{
|
||||||
width = get_buffer_height (surface);
|
src_rect = (graphene_rect_t) {
|
||||||
height = get_buffer_width (surface);
|
.origin.x = surface->viewport.src_rect.origin.x,
|
||||||
|
.origin.y = surface->viewport.src_rect.origin.y,
|
||||||
|
.size.width = surface->viewport.src_rect.size.width,
|
||||||
|
.size.height = surface->viewport.src_rect.size.height
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = get_buffer_width (surface);
|
int width, height;
|
||||||
height = get_buffer_height (surface);
|
|
||||||
|
if (meta_monitor_transform_is_rotated (surface->buffer_transform))
|
||||||
|
{
|
||||||
|
width = get_buffer_height (surface);
|
||||||
|
height = get_buffer_width (surface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = get_buffer_width (surface);
|
||||||
|
height = get_buffer_height (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
src_rect = (graphene_rect_t) {
|
||||||
|
.size.width = width / surface->scale,
|
||||||
|
.size.height = height / surface->scale
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
viewport_region = meta_region_crop_and_scale (surface_region,
|
||||||
|
&src_rect,
|
||||||
|
surface_rect.width,
|
||||||
|
surface_rect.height);
|
||||||
|
scaled_region = meta_region_scale (viewport_region, surface->scale);
|
||||||
|
transformed_region = meta_region_transform (scaled_region,
|
||||||
|
surface->buffer_transform,
|
||||||
|
buffer_rect.width,
|
||||||
|
buffer_rect.height);
|
||||||
|
|
||||||
src_rect = (graphene_rect_t) {
|
/* Now add the scaled, cropped and transformed damage region to the
|
||||||
.size.width = width / surface->scale,
|
* buffer damage. Buffer damage is already in the correct coordinate
|
||||||
.size.height = height / surface->scale
|
* space. */
|
||||||
};
|
cairo_region_union (buffer_region, transformed_region);
|
||||||
|
|
||||||
|
cairo_region_destroy (viewport_region);
|
||||||
|
cairo_region_destroy (scaled_region);
|
||||||
|
cairo_region_destroy (transformed_region);
|
||||||
}
|
}
|
||||||
viewport_region = meta_region_crop_and_scale (surface_region,
|
|
||||||
&src_rect,
|
|
||||||
surface_rect.width,
|
|
||||||
surface_rect.height);
|
|
||||||
scaled_region = meta_region_scale (viewport_region, surface->scale);
|
|
||||||
transformed_region = meta_region_transform (scaled_region,
|
|
||||||
surface->buffer_transform,
|
|
||||||
buffer_rect.width,
|
|
||||||
buffer_rect.height);
|
|
||||||
|
|
||||||
/* Now add the scaled, cropped and transformed damage region to the
|
|
||||||
* buffer damage. Buffer damage is already in the correct coordinate space. */
|
|
||||||
cairo_region_union (buffer_region, transformed_region);
|
|
||||||
|
|
||||||
cairo_region_intersect_rectangle (buffer_region, &buffer_rect);
|
cairo_region_intersect_rectangle (buffer_region, &buffer_rect);
|
||||||
|
|
||||||
@ -417,10 +426,6 @@ surface_process_damage (MetaWaylandSurface *surface,
|
|||||||
rect.width, rect.height);
|
rect.width, rect.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_region_destroy (viewport_region);
|
|
||||||
cairo_region_destroy (scaled_region);
|
|
||||||
cairo_region_destroy (transformed_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaWaylandBuffer *
|
MetaWaylandBuffer *
|
||||||
|
Loading…
Reference in New Issue
Block a user