[mutter/gbsneto/content: 8/12] shaped-texture: Move MetaCullable helpers to MetaSurfaceActor
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/content: 8/12] shaped-texture: Move MetaCullable helpers to MetaSurfaceActor
- Date: Sun, 14 Jul 2019 04:16:57 +0000 (UTC)
commit 0eaa0b9cb507d6612bcec80be0a966807143309c
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Tue Jan 29 19:53:50 2019 -0200
shaped-texture: Move MetaCullable helpers to MetaSurfaceActor
Now that MetaShapedTexture is not a ClutterActor anymore, it does
not make sense to make it a MetaCullable semi-implementation. This
is, naturally, a responsibility of MetaSurfaceActor, since now
MetaShapedTexture is a ClutterContent and as such, it only cares
about what to draw.
Move the MetaCullable implementation of MetaShapedTexture to
MetaSurfaceActor.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/409
src/compositor/meta-shaped-texture-private.h | 6 -
src/compositor/meta-shaped-texture.c | 195 ++++-----------------------
src/compositor/meta-surface-actor.c | 146 ++++++++++++++++++--
src/meta/meta-shaped-texture.h | 11 +-
4 files changed, 171 insertions(+), 187 deletions(-)
---
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 42458daa2..6839b0872 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -40,7 +40,6 @@ void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
int fallback_width,
int fallback_height);
-gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
void meta_shaped_texture_set_transform (MetaShapedTexture *stex,
MetaMonitorTransform transform);
@@ -51,11 +50,6 @@ void meta_shaped_texture_set_viewport_dst_size (MetaShapedTexture *stex,
int dst_width,
int dst_height);
void meta_shaped_texture_reset_viewport_dst_size (MetaShapedTexture *stex);
-void meta_shaped_texture_cull_out (MetaShapedTexture *stex,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region,
- uint8_t opacity);
-void meta_shaped_texture_reset_culling (MetaShapedTexture *stex);
void meta_shaped_texture_set_buffer_scale (MetaShapedTexture *stex,
int buffer_scale);
int meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex);
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index c98aba954..235d54862 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -88,10 +88,6 @@ 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;
- cairo_region_t *unobscured_region;
-
gboolean size_invalid;
MetaMonitorTransform transform;
gboolean has_viewport_src_rect;
@@ -220,34 +216,6 @@ ensure_size_valid (MetaShapedTexture *stex)
update_size (stex);
}
-static void
-set_unobscured_region (MetaShapedTexture *stex,
- cairo_region_t *unobscured_region)
-{
- g_clear_pointer (&stex->unobscured_region, cairo_region_destroy);
- if (unobscured_region)
- {
- int width, height;
-
- ensure_size_valid (stex);
- width = stex->dst_width;
- height = stex->dst_height;
-
- cairo_rectangle_int_t bounds = { 0, 0, width, height };
- stex->unobscured_region = cairo_region_copy (unobscured_region);
- cairo_region_intersect_rectangle (stex->unobscured_region, &bounds);
- }
-}
-
-static void
-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_copy (clip_region);
-}
-
static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
@@ -272,12 +240,8 @@ meta_shaped_texture_dispose (GObject *object)
stex->paint_tower = NULL;
g_clear_pointer (&stex->texture, cogl_object_unref);
- g_clear_pointer (&stex->opaque_region, cairo_region_destroy);
meta_shaped_texture_set_mask_texture (stex, NULL);
- set_unobscured_region (stex, NULL);
- set_clip_region (stex, NULL);
-
meta_shaped_texture_reset_pipelines (stex);
g_clear_pointer (&stex->snippet, cogl_object_unref);
@@ -544,12 +508,6 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
return G_SOURCE_REMOVE;
}
-static cairo_region_t *
-effective_unobscured_region (MetaShapedTexture *stex)
-{
- return stex->unobscured_region;
-}
-
static void
do_paint_content (MetaShapedTexture *stex,
ClutterPaintNode *root_node,
@@ -561,7 +519,6 @@ do_paint_content (MetaShapedTexture *stex,
int dst_width, dst_height;
cairo_rectangle_int_t tex_rect;
gboolean use_opaque_region;
- cairo_region_t *clip_tex_region;
cairo_region_t *blended_tex_region;
CoglContext *ctx;
CoglPipelineFilter filter;
@@ -591,31 +548,14 @@ do_paint_content (MetaShapedTexture *stex,
use_opaque_region = stex->opaque_region && opacity == 255;
- if (stex->clip_region)
- {
- clip_tex_region =
- meta_region_scale (stex->clip_region, META_ROUNDING_STRATEGY_GROW);
- }
- else
- {
- clip_tex_region = NULL;
- }
-
if (use_opaque_region)
{
- if (clip_tex_region)
- blended_tex_region = cairo_region_copy (clip_tex_region);
- else
- blended_tex_region = cairo_region_create_rectangle (&tex_rect);
-
+ blended_tex_region = cairo_region_create_rectangle (&tex_rect);
cairo_region_subtract (blended_tex_region, stex->opaque_region);
}
else
{
- if (clip_tex_region)
- blended_tex_region = cairo_region_reference (clip_tex_region);
- else
- blended_tex_region = NULL;
+ blended_tex_region = NULL;
}
/* Limit to how many separate rectangles we'll draw; beyond this just
@@ -637,21 +577,10 @@ 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 (clip_tex_region)
- {
- region = cairo_region_copy (clip_tex_region);
- cairo_region_intersect (region, stex->opaque_region);
- }
- else
- {
- region = cairo_region_reference (stex->opaque_region);
- }
-
- if (!cairo_region_is_empty (region))
+ if (!cairo_region_is_empty (stex->opaque_region))
{
CoglPipeline *opaque_pipeline;
@@ -659,18 +588,16 @@ 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 (region);
+ n_rects = cairo_region_num_rectangles (stex->opaque_region);
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
- cairo_region_get_rectangle (region, i, &rect);
+ cairo_region_get_rectangle (stex->opaque_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. */
@@ -737,7 +664,6 @@ do_paint_content (MetaShapedTexture *stex,
}
}
- g_clear_pointer (&clip_tex_region, cairo_region_destroy);
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
}
@@ -791,9 +717,6 @@ 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
@@ -878,17 +801,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
clutter_content_invalidate (CLUTTER_CONTENT (stex));
}
-gboolean
-meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
-{
- cairo_region_t *unobscured_region = effective_unobscured_region (stex);
-
- if (unobscured_region)
- return cairo_region_is_empty (unobscured_region);
- else
- return FALSE;
-}
-
/**
* meta_shaped_texture_update_area:
* @stex: #MetaShapedTexture
@@ -896,6 +808,7 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
* @y: the y coordinate of the damaged area
* @width: the width of the damaged area
* @height: the height of the damaged area
+ * @clip: (out): the resulting clip region
*
* Repairs the damaged area indicated by @x, @y, @width and @height
* and potentially queues a redraw.
@@ -903,33 +816,37 @@ meta_shaped_texture_is_obscured (MetaShapedTexture *stex)
* Return value: Whether a redraw have been queued or not
*/
gboolean
-meta_shaped_texture_update_area (MetaShapedTexture *stex,
- int x,
- int y,
- int width,
- int height)
+meta_shaped_texture_update_area (MetaShapedTexture *stex,
+ int x,
+ int y,
+ int width,
+ int height,
+ cairo_rectangle_int_t *clip)
{
- cairo_region_t *unobscured_region;
- cairo_rectangle_int_t clip;
MetaMonitorTransform inverted_transform;
if (stex->texture == NULL)
return FALSE;
- clip = (cairo_rectangle_int_t) {
+ *clip = (cairo_rectangle_int_t) {
.x = x,
.y = y,
.width = width,
.height = height
};
+ meta_rectangle_scale_double (clip,
+ 1.0 / stex->buffer_scale,
+ META_ROUNDING_STRATEGY_SHRINK,
+ clip);
+
inverted_transform = meta_monitor_transform_invert (stex->transform);
ensure_size_valid (stex);
- meta_rectangle_transform (&clip,
+ meta_rectangle_transform (clip,
inverted_transform,
stex->dst_width,
stex->dst_height,
- &clip);
+ clip);
if (stex->has_viewport_src_rect || stex->has_viewport_dst_size)
{
@@ -974,18 +891,18 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
inverted_dst_width = ceilf (viewport.size.width);
inverted_dst_height = ceilf (viewport.size.height);
- meta_rectangle_crop_and_scale (&clip,
+ meta_rectangle_crop_and_scale (clip,
&inverted_viewport,
inverted_dst_width,
inverted_dst_height,
- &clip);
+ clip);
}
meta_texture_tower_update_area (stex->paint_tower,
- clip.x,
- clip.y,
- clip.width,
- clip.height);
+ clip->x,
+ clip->y,
+ clip->width,
+ clip->height);
stex->prev_invalidation = stex->last_invalidation;
stex->last_invalidation = g_get_monotonic_time ();
@@ -1001,34 +918,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
stex->fast_updates++;
}
- unobscured_region = effective_unobscured_region (stex);
- if (unobscured_region)
- {
- cairo_region_t *intersection;
-
- if (cairo_region_is_empty (unobscured_region))
- return FALSE;
-
- intersection = cairo_region_copy (unobscured_region);
- cairo_region_intersect_rectangle (intersection, &clip);
-
- if (!cairo_region_is_empty (intersection))
- {
- cairo_rectangle_int_t damage_rect;
- cairo_region_get_extents (intersection, &damage_rect);
- clutter_content_invalidate (CLUTTER_CONTENT (stex));
- cairo_region_destroy (intersection);
- return TRUE;
- }
-
- cairo_region_destroy (intersection);
- return FALSE;
- }
- else
- {
- clutter_content_invalidate (CLUTTER_CONTENT (stex));
- return TRUE;
- }
+ return TRUE;
}
/**
@@ -1458,34 +1348,3 @@ meta_shaped_texture_get_buffer_scale (MetaShapedTexture *stex)
return stex->buffer_scale;
}
-
-void
-meta_shaped_texture_cull_out (MetaShapedTexture *stex,
- cairo_region_t *unobscured_region,
- cairo_region_t *clip_region,
- uint8_t opacity)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- set_unobscured_region (stex, unobscured_region);
- set_clip_region (stex, clip_region);
-
- if (opacity == 0xff)
- {
- if (stex->opaque_region)
- {
- if (unobscured_region)
- cairo_region_subtract (unobscured_region, stex->opaque_region);
- if (clip_region)
- cairo_region_subtract (clip_region, stex->opaque_region);
- }
- }
-}
-
-void
-meta_shaped_texture_reset_culling (MetaShapedTexture *stex)
-{
- g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
-
- set_clip_region (stex, NULL);
-}
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index e50eb8018..b68eb5eee 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -30,6 +30,10 @@ 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 */
cairo_region_t *pending_damage;
guint frozen : 1;
@@ -51,6 +55,74 @@ enum
static guint signals[LAST_SIGNAL];
+static cairo_region_t *
+effective_unobscured_region (MetaSurfaceActor *surface_actor)
+{
+ MetaSurfaceActorPrivate *priv =
+ meta_surface_actor_get_instance_private (surface_actor);
+ ClutterActor *actor;
+
+ /* Fail if we have any mapped clones. */
+ actor = CLUTTER_ACTOR (surface_actor);
+ do
+ {
+ if (clutter_actor_has_mapped_clones (actor))
+ return NULL;
+ actor = clutter_actor_get_parent (actor);
+ }
+ while (actor != NULL);
+
+ return priv->unobscured_region;
+}
+
+
+static void
+set_unobscured_region (MetaSurfaceActor *surface_actor,
+ cairo_region_t *unobscured_region)
+{
+ MetaSurfaceActorPrivate *priv =
+ meta_surface_actor_get_instance_private (surface_actor);
+
+ g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
+ if (unobscured_region)
+ {
+ float width, height;
+
+ clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
+ &width,
+ &height);
+
+ cairo_rectangle_int_t bounds = { 0, 0, width, height };
+ priv->unobscured_region = cairo_region_copy (unobscured_region);
+ cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
+ }
+}
+
+static void
+set_clip_region (MetaSurfaceActor *surface_actor,
+ cairo_region_t *clip_region)
+{
+ MetaSurfaceActorPrivate *priv =
+ meta_surface_actor_get_instance_private (surface_actor);
+
+ g_clear_pointer (&priv->clip_region, cairo_region_destroy);
+ if (clip_region)
+ priv->clip_region = cairo_region_copy (clip_region);
+}
+
+static void
+meta_surface_actor_paint (ClutterActor *actor)
+{
+ 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);
+}
+
static void
meta_surface_actor_pick (ClutterActor *actor,
const ClutterColor *color)
@@ -126,6 +198,9 @@ meta_surface_actor_dispose (GObject *object)
g_clear_pointer (&priv->input_region, cairo_region_destroy);
+ set_unobscured_region (self, NULL);
+ set_clip_region (self, NULL);
+
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
}
@@ -136,6 +211,7 @@ 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;
@@ -164,17 +240,31 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
meta_surface_actor_get_instance_private (surface_actor);
uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable));
- meta_shaped_texture_cull_out (priv->texture, unobscured_region, clip_region, opacity);
+ set_unobscured_region (surface_actor, unobscured_region);
+ set_clip_region (surface_actor, clip_region);
+
+ if (opacity == 0xff)
+ {
+ cairo_region_t *opaque_region;
+
+ opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
+
+ if (opaque_region)
+ {
+ if (unobscured_region)
+ cairo_region_subtract (unobscured_region, opaque_region);
+ if (clip_region)
+ cairo_region_subtract (clip_region, opaque_region);
+ }
+ }
}
static void
meta_surface_actor_reset_culling (MetaCullable *cullable)
{
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (surface_actor);
- meta_shaped_texture_reset_culling (priv->texture);
+ set_clip_region (surface_actor, NULL);
}
static void
@@ -232,18 +322,58 @@ meta_surface_actor_update_area (MetaSurfaceActor *self,
{
MetaSurfaceActorPrivate *priv =
meta_surface_actor_get_instance_private (self);
+ gboolean repaint_scheduled = FALSE;
+ cairo_rectangle_int_t clip;
+
+ if (meta_shaped_texture_update_area (priv->texture, x, y, width, height, &clip))
+ {
+ cairo_region_t *unobscured_region;
+
+ unobscured_region = effective_unobscured_region (self);
- if (meta_shaped_texture_update_area (priv->texture, x, y, width, height))
+ if (unobscured_region)
+ {
+ cairo_region_t *intersection;
+
+ if (cairo_region_is_empty (unobscured_region))
+ return;
+
+ intersection = cairo_region_copy (unobscured_region);
+ cairo_region_intersect_rectangle (intersection, &clip);
+
+ if (!cairo_region_is_empty (intersection))
+ {
+ cairo_rectangle_int_t damage_rect;
+
+ cairo_region_get_extents (intersection, &damage_rect);
+ clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &damage_rect);
+ repaint_scheduled = TRUE;
+ }
+
+ cairo_region_destroy (intersection);
+ }
+ else
+ {
+ clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &clip);
+ repaint_scheduled = TRUE;
+ }
+ }
+
+ if (repaint_scheduled)
g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
}
gboolean
meta_surface_actor_is_obscured (MetaSurfaceActor *self)
{
- MetaSurfaceActorPrivate *priv =
- meta_surface_actor_get_instance_private (self);
+ cairo_region_t *unobscured_region;
- return meta_shaped_texture_is_obscured (priv->texture);
+ unobscured_region = effective_unobscured_region (self);
+
+ if (unobscured_region)
+ return cairo_region_is_empty (unobscured_region);
+ else
+ return FALSE;
}
void
diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h
index c36b8547f..9a4b5e7c6 100644
--- a/src/meta/meta-shaped-texture.h
+++ b/src/meta/meta-shaped-texture.h
@@ -45,11 +45,12 @@ void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
gboolean create_mipmaps);
META_EXPORT
-gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
- int x,
- int y,
- int width,
- int height);
+gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
+ int x,
+ int y,
+ int width,
+ int height,
+ cairo_rectangle_int_t *clip);
META_EXPORT
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]