shaped-texture: Reintroduce clip_region
In commit4c1fde9d
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 of4c1fde9d
: 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
This commit is contained in:
parent
f5c8e0d96d
commit
3187fe8ebc
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
region = get_scaled_region (surface_actor, clip_region);
|
||||
meta_shaped_texture_set_clip_region (stex, region);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_shaped_texture_set_clip_region (stex, clip_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);
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->paint (actor,
|
||||
paint_context);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user