Commit 3187fe8e authored by Robert Mader's avatar Robert Mader
Browse files

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 #850
Fixes #1295

!1326
parent f5c8e0d9
Pipeline #190443 passed with stages
in 10 minutes and 36 seconds
......@@ -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;
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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment