[mutter] shaped-texture: Reintroduce clip_region
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] shaped-texture: Reintroduce clip_region
- Date: Mon, 22 Jun 2020 16:16:01 +0000 (UTC)
commit 3187fe8ebc73cb3907d1d02edecedc4e4ab0c689
Author: Robert Mader <robert mader posteo de>
Date: Mon Jun 22 15:53:23 2020 +0200
shaped-texture: Reintroduce clip_region
In commit 4c1fde9d MetaCullable related code was moved out of
MetaShapedTexture into MetaSurfaceActor. While generally desirable,
this removed drawing optimizations in MetaShapedTexture for partial
redraws. The common case for fully obscured actors was still supposed
to work, but it was now discovered that it actually did not.
This commit revert parts of 4c1fde9d: it reintroduces clipping
to MetaShapedTexture but leaves all culling and actor related logic
in MetaSurfaceActor.
Thanks to Daniel van Vugt for uncovering the issue.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/850
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1295
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1326
src/compositor/meta-shaped-texture-private.h | 3 ++
src/compositor/meta-shaped-texture.c | 46 +++++++++++++++++++++++++---
src/compositor/meta-surface-actor.c | 34 +++++++-------------
3 files changed, 55 insertions(+), 28 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 85d94b7534..c415260c0b 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -66,4 +66,7 @@ gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
int meta_shaped_texture_get_width (MetaShapedTexture *stex);
int meta_shaped_texture_get_height (MetaShapedTexture *stex);
+void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
+ cairo_region_t *clip_region);
+
#endif
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index d7066ad038..ed8e3c0bcf 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -92,6 +92,9 @@ struct _MetaShapedTexture
/* The region containing only fully opaque pixels */
cairo_region_t *opaque_region;
+ /* MetaCullable regions, see that documentation for more details */
+ cairo_region_t *clip_region;
+
gboolean size_invalid;
MetaMonitorTransform transform;
gboolean has_viewport_src_rect;
@@ -219,6 +222,15 @@ ensure_size_valid (MetaShapedTexture *stex)
update_size (stex);
}
+void
+meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
+ cairo_region_t *clip_region)
+{
+ g_clear_pointer (&stex->clip_region, cairo_region_destroy);
+ if (clip_region)
+ stex->clip_region = cairo_region_reference (clip_region);
+}
+
static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
@@ -244,6 +256,7 @@ meta_shaped_texture_dispose (GObject *object)
meta_shaped_texture_reset_pipelines (stex);
g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
+ g_clear_pointer (&stex->clip_region, cairo_region_destroy);
g_clear_pointer (&stex->snippet, cogl_object_unref);
@@ -590,12 +603,19 @@ do_paint_content (MetaShapedTexture *stex,
if (use_opaque_region)
{
- blended_tex_region = cairo_region_create_rectangle (&content_rect);
+ if (stex->clip_region)
+ blended_tex_region = cairo_region_copy (stex->clip_region);
+ else
+ blended_tex_region = cairo_region_create_rectangle (&content_rect);
+
cairo_region_subtract (blended_tex_region, stex->opaque_region);
}
else
{
- blended_tex_region = NULL;
+ if (stex->clip_region)
+ blended_tex_region = cairo_region_reference (stex->clip_region);
+ else
+ blended_tex_region = NULL;
}
/* Limit to how many separate rectangles we'll draw; beyond this just
@@ -617,10 +637,21 @@ do_paint_content (MetaShapedTexture *stex,
/* First, paint the unblended parts, which are part of the opaque region. */
if (use_opaque_region)
{
+ cairo_region_t *region;
int n_rects;
int i;
- if (!cairo_region_is_empty (stex->opaque_region))
+ if (stex->clip_region)
+ {
+ region = cairo_region_copy (stex->clip_region);
+ cairo_region_intersect (region, stex->opaque_region);
+ }
+ else
+ {
+ region = cairo_region_reference (stex->opaque_region);
+ }
+
+ if (!cairo_region_is_empty (region))
{
CoglPipeline *opaque_pipeline;
@@ -628,16 +659,18 @@ do_paint_content (MetaShapedTexture *stex,
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
- n_rects = cairo_region_num_rectangles (stex->opaque_region);
+ n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (stex->opaque_region, i, &rect);
+ cairo_region_get_rectangle (region, i, &rect);
paint_clipped_rectangle_node (stex, root_node,
opaque_pipeline,
&rect, alloc);
}
}
+
+ cairo_region_destroy (region);
}
/* Now, go ahead and paint the blended parts. */
@@ -762,6 +795,9 @@ meta_shaped_texture_paint_content (ClutterContent *content,
CoglTexture *paint_tex = NULL;
uint8_t opacity;
+ if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
+ return;
+
/* The GL EXT_texture_from_pixmap extension does allow for it to be
* used together with SGIS_generate_mipmap, however this is very
* rarely supported. Also, even when it is supported there
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 1213f48dff..ccad4888fe 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -34,7 +34,6 @@ typedef struct _MetaSurfaceActorPrivate
cairo_region_t *input_region;
/* MetaCullable regions, see that documentation for more details */
- cairo_region_t *clip_region;
cairo_region_t *unobscured_region;
/* Freeze/thaw accounting */
@@ -128,30 +127,21 @@ set_clip_region (MetaSurfaceActor *surface_actor,
{
MetaSurfaceActorPrivate *priv =
meta_surface_actor_get_instance_private (surface_actor);
+ MetaShapedTexture *stex = priv->texture;
- g_clear_pointer (&priv->clip_region, cairo_region_destroy);
- if (clip_region)
+ if (clip_region && !cairo_region_is_empty (clip_region))
{
- if (cairo_region_is_empty (clip_region))
- priv->clip_region = cairo_region_reference (clip_region);
- else
- priv->clip_region = get_scaled_region (surface_actor, clip_region);
- }
-}
+ cairo_region_t *region;
-static void
-meta_surface_actor_paint (ClutterActor *actor,
- ClutterPaintContext *paint_context)
-{
- MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (actor);
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
+ region = get_scaled_region (surface_actor, clip_region);
+ meta_shaped_texture_set_clip_region (stex, region);
- if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
- return;
-
- CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
- paint_context);
+ cairo_region_destroy (region);
+ }
+ else
+ {
+ meta_shaped_texture_set_clip_region (stex, clip_region);
+ }
}
static void
@@ -221,7 +211,6 @@ meta_surface_actor_dispose (GObject *object)
g_clear_object (&priv->texture);
set_unobscured_region (self, NULL);
- set_clip_region (self, NULL);
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
}
@@ -233,7 +222,6 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
object_class->dispose = meta_surface_actor_dispose;
- actor_class->paint = meta_surface_actor_paint;
actor_class->pick = meta_surface_actor_pick;
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]