From a27744503b7235d02870481ec16e1b420dbfb9e0 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 21 Nov 2013 16:25:20 -0500 Subject: [PATCH] shaped-texture: Make Cullable Make MetaWindowActor chain up to the generic default MetaCullable implementation, and remove the helper methods for MetaSurfaceActor and MetaShapedTexture. --- src/compositor/meta-shaped-texture.c | 86 ++++++++++++++---------- src/compositor/meta-surface-actor.c | 34 +++++++--- src/compositor/meta-surface-actor.h | 3 - src/compositor/meta-window-actor.c | 98 ++++------------------------ src/meta/meta-shaped-texture.h | 3 - 5 files changed, 90 insertions(+), 134 deletions(-) diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 6f6422dd2..9a5e18386 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -39,6 +39,7 @@ #include #include #include /* for gdk_rectangle_intersect() */ +#include "meta-cullable.h" static void meta_shaped_texture_dispose (GObject *object); @@ -58,7 +59,10 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self, static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume); -G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); #define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \ @@ -111,6 +115,17 @@ meta_shaped_texture_init (MetaShapedTexture *self) priv->create_mipmaps = TRUE; } +static void +set_clip_region (MetaShapedTexture *self, + cairo_region_t *clip_region) +{ + MetaShapedTexturePrivate *priv = self->priv; + + g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy); + if (clip_region) + priv->clip_region = cairo_region_copy (clip_region); +} + static void meta_shaped_texture_dispose (GObject *object) { @@ -125,7 +140,7 @@ meta_shaped_texture_dispose (GObject *object) g_clear_pointer (&priv->opaque_region, cairo_region_destroy); meta_shaped_texture_set_mask_texture (self, NULL); - meta_shaped_texture_set_clip_region (self, NULL); + set_clip_region (self, NULL); G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object); } @@ -761,39 +776,6 @@ meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, clutter_actor_queue_redraw (CLUTTER_ACTOR (stex)); } -/** - * meta_shaped_texture_set_clip_region: - * @stex: a #MetaShapedTexture - * @clip_region: the region of the texture that is visible and - * should be painted. - * - * Provides a hint to the texture about what areas of the texture - * are not completely obscured and thus need to be painted. This - * is an optimization and is not supposed to have any effect on - * the output. - * - * Typically a parent container will set the clip region before - * painting its children, and then unset it afterwards. - */ -void -meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region) -{ - MetaShapedTexturePrivate *priv; - - g_return_if_fail (META_IS_SHAPED_TEXTURE (stex)); - - priv = stex->priv; - - if (priv->clip_region) - cairo_region_destroy (priv->clip_region); - - if (clip_region) - priv->clip_region = cairo_region_copy (clip_region); - else - priv->clip_region = NULL; -} - /** * meta_shaped_texture_set_opaque_region: * @stex: a #MetaShapedTexture @@ -922,6 +904,40 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex, return surface; } +static void +meta_shaped_texture_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable); + MetaShapedTexturePrivate *priv = self->priv; + + set_clip_region (self, clip_region); + + if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) + { + if (priv->opaque_region) + { + cairo_region_subtract (unobscured_region, priv->opaque_region); + cairo_region_subtract (clip_region, priv->opaque_region); + } + } +} + +static void +meta_shaped_texture_reset_culling (MetaCullable *cullable) +{ + MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable); + set_clip_region (self, NULL); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_shaped_texture_cull_out; + iface->reset_culling = meta_shaped_texture_reset_culling; +} + ClutterActor * meta_shaped_texture_new (void) { diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c index 690cd87c7..af599607b 100644 --- a/src/compositor/meta-surface-actor.c +++ b/src/compositor/meta-surface-actor.c @@ -15,6 +15,7 @@ #include #include #include "meta-surface-actor.h" +#include "meta-cullable.h" #include "meta-shaped-texture-private.h" @@ -24,7 +25,10 @@ struct _MetaSurfaceActorPrivate MetaWaylandBuffer *buffer; }; -G_DEFINE_TYPE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR); +static void cullable_iface_init (MetaCullableInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR, + G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); static void meta_surface_actor_class_init (MetaSurfaceActorClass *klass) @@ -32,6 +36,27 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass) g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate)); } +static void +meta_surface_actor_cull_out (MetaCullable *cullable, + cairo_region_t *unobscured_region, + cairo_region_t *clip_region) +{ + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); +} + +static void +meta_surface_actor_reset_culling (MetaCullable *cullable) +{ + meta_cullable_reset_culling_children (cullable); +} + +static void +cullable_iface_init (MetaCullableInterface *iface) +{ + iface->cull_out = meta_surface_actor_cull_out; + iface->reset_culling = meta_surface_actor_reset_culling; +} + static void meta_surface_actor_init (MetaSurfaceActor *self) { @@ -71,13 +96,6 @@ meta_surface_actor_get_texture (MetaSurfaceActor *self) return self->priv->texture; } -void -meta_surface_actor_set_clip_region (MetaSurfaceActor *self, - cairo_region_t *clip_region) -{ - meta_shaped_texture_set_clip_region (self->priv->texture, clip_region); -} - static void update_area (MetaSurfaceActor *self, int x, int y, int width, int height) diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h index a02ea3ce6..287b230a3 100644 --- a/src/compositor/meta-surface-actor.h +++ b/src/compositor/meta-surface-actor.h @@ -43,9 +43,6 @@ cairo_surface_t *meta_surface_actor_get_image (MetaSurfaceActor *self, MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self); -void meta_surface_actor_set_clip_region (MetaSurfaceActor *self, - cairo_region_t *clip_region); - gboolean meta_surface_actor_damage_all (MetaSurfaceActor *self, cairo_region_t *unobscured_region); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index dc352a5c2..44ec25367 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -74,11 +74,6 @@ struct _MetaWindowActorPrivate /* A region that matches the shape of the window, including frame bounds */ cairo_region_t *shape_region; - /* If the window has an input shape, a region that matches the shape */ - cairo_region_t *input_region; - /* The opaque region, from _NET_WM_OPAQUE_REGION, intersected with - * the shape region. */ - cairo_region_t *opaque_region; /* The region we should clip to when painting the shadow */ cairo_region_t *shadow_clip; @@ -447,10 +442,9 @@ meta_window_actor_constructed (GObject *object) meta_window_actor_update_opacity (self); - /* Start off with empty regions to maintain the invariant that - these regions are always set */ + /* Start off with an empty shape region to maintain the invariant + * that it's always set */ priv->shape_region = cairo_region_create (); - priv->input_region = cairo_region_create (); } static void @@ -482,8 +476,6 @@ meta_window_actor_dispose (GObject *object) g_clear_pointer (&priv->unobscured_region, cairo_region_destroy); g_clear_pointer (&priv->shape_region, cairo_region_destroy); - g_clear_pointer (&priv->input_region, cairo_region_destroy); - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); g_clear_pointer (&priv->shadow_class, g_free); @@ -1805,38 +1797,6 @@ meta_window_actor_unmapped (MetaWindowActor *self) } } -/** - * meta_window_actor_get_obscured_region: - * @self: a #MetaWindowActor - * - * Gets the region that is completely obscured by the window. Coordinates - * are relative to the upper-left of the window. - * - * Return value: (transfer none): the area obscured by the window, - * %NULL is the same as an empty region. - */ -static cairo_region_t * -meta_window_actor_get_obscured_region (MetaWindowActor *self) -{ - MetaWindowActorPrivate *priv = self->priv; - - if (!priv->window->shaded) - { - if (meta_is_wayland_compositor ()) - { - if (priv->opacity == 0xff) - return priv->opaque_region; - } - else - { - if (priv->back_pixmap && priv->opacity == 0xff) - return priv->opaque_region; - } - } - - return NULL; -} - #if 0 /* Print out a region; useful for debugging */ static void @@ -1886,8 +1846,6 @@ see_region (cairo_region_t *region, * * Provides a hint as to what areas of the window need to queue * redraws when damaged. Regions not in @unobscured_region are completely obscured. - * Unlike meta_window_actor_set_clip_region(), the region here - * doesn't take into account any clipping that is in effect while drawing. */ void meta_window_actor_set_unobscured_region (MetaWindowActor *self, @@ -1904,26 +1862,6 @@ meta_window_actor_set_unobscured_region (MetaWindowActor *self, priv->unobscured_region = NULL; } -/** - * meta_window_actor_set_clip_region: - * @self: a #MetaWindowActor - * @clip_region: the region of the screen that isn't completely - * obscured. - * - * Provides a hint as to what areas of the window need to be - * drawn. Regions not in @clip_region are completely obscured or - * not drawn in this frame. - * This will be set before painting then unset afterwards. - */ -static void -meta_window_actor_set_clip_region (MetaWindowActor *self, - cairo_region_t *clip_region) -{ - MetaWindowActorPrivate *priv = self->priv; - - meta_surface_actor_set_clip_region (priv->surface, clip_region); -} - /** * meta_window_actor_set_clip_region_beneath: * @self: a #MetaWindowActor @@ -1973,18 +1911,7 @@ meta_window_actor_cull_out (MetaCullable *cullable, } meta_window_actor_set_unobscured_region (self, unobscured_region); - meta_window_actor_set_clip_region (self, clip_region); - - if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff) - { - cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (self); - if (obscured_region) - { - cairo_region_subtract (unobscured_region, obscured_region); - cairo_region_subtract (clip_region, obscured_region); - } - } - + meta_cullable_cull_out_children (cullable, unobscured_region, clip_region); meta_window_actor_set_clip_region_beneath (self, clip_region); } @@ -1994,8 +1921,9 @@ meta_window_actor_reset_culling (MetaCullable *cullable) MetaWindowActor *self = META_WINDOW_ACTOR (cullable); MetaWindowActorPrivate *priv = self->priv; - meta_surface_actor_set_clip_region (priv->surface, NULL); g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); + + meta_cullable_reset_culling_children (cullable); } static void @@ -2468,13 +2396,12 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) { MetaWindowActorPrivate *priv = self->priv; MetaShapedTexture *stex; + cairo_region_t *opaque_region; stex = meta_surface_actor_get_texture (priv->surface); if (!stex) return; - g_clear_pointer (&priv->opaque_region, cairo_region_destroy); - if (priv->argb32 && priv->window->opaque_region != NULL) { MetaFrameBorders borders; @@ -2491,16 +2418,17 @@ meta_window_actor_update_opaque_region (MetaWindowActor *self) * to be undefined, and considered a client bug. In mutter's * case, graphical glitches will occur. */ - priv->opaque_region = cairo_region_copy (priv->window->opaque_region); - cairo_region_translate (priv->opaque_region, borders.total.left, borders.total.top); - cairo_region_intersect (priv->opaque_region, priv->shape_region); + opaque_region = cairo_region_copy (priv->window->opaque_region); + cairo_region_translate (opaque_region, borders.total.left, borders.total.top); + cairo_region_intersect (opaque_region, priv->shape_region); } else if (priv->argb32) - priv->opaque_region = NULL; + opaque_region = NULL; else - priv->opaque_region = cairo_region_reference (priv->shape_region); + opaque_region = cairo_region_reference (priv->shape_region); - meta_shaped_texture_set_opaque_region (stex, priv->opaque_region); + meta_shaped_texture_set_opaque_region (stex, opaque_region); + cairo_region_destroy (opaque_region); } static void diff --git a/src/meta/meta-shaped-texture.h b/src/meta/meta-shaped-texture.h index c7091d705..dac4ccc25 100644 --- a/src/meta/meta-shaped-texture.h +++ b/src/meta/meta-shaped-texture.h @@ -81,9 +81,6 @@ void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex, void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex, cairo_region_t *shape_region); -void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex, - cairo_region_t *clip_region); - void meta_shaped_texture_set_opaque_region (MetaShapedTexture *stex, cairo_region_t *opaque_region);