From 27ab516f413f9688274f1f7e4f3c38f28bfa1b03 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Feb 2014 13:20:18 -0500 Subject: [PATCH] cullable: Reset the culling state instead of skipping the traversal When we traversed down to reset the culling state, previously we would just skip any actors that wanted culling. In order to properly reset the unobscured_region before painting, we need to traverse down to these places as well. Do this by calling cull_out with NULL regions for both arguments, and adapt existing cull_out implementations to match. https://bugzilla.gnome.org/show_bug.cgi?id=720631 --- src/compositor/meta-cullable.c | 40 ++++++++++++++-------- src/compositor/meta-shaped-texture.c | 6 ++-- src/compositor/meta-window-actor-private.h | 3 -- src/compositor/meta-window-actor.c | 16 ++++++--- src/compositor/meta-window-group.c | 14 -------- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/compositor/meta-cullable.c b/src/compositor/meta-cullable.c index 5eb19026a..801cda487 100644 --- a/src/compositor/meta-cullable.c +++ b/src/compositor/meta-cullable.c @@ -70,10 +70,16 @@ meta_cullable_cull_out_children (MetaCullable *cullable, while (clutter_actor_iter_prev (&iter, &child)) { float x, y; + gboolean needs_culling; - if (!CLUTTER_ACTOR_IS_VISIBLE (child)) + if (!META_IS_CULLABLE (child)) continue; + needs_culling = (unobscured_region != NULL && clip_region != NULL); + + if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child)) + needs_culling = FALSE; + /* If an actor has effects applied, then that can change the area * it paints and the opacity, so we no longer can figure out what * portion of the actor is obscured and what portion of the screen @@ -90,25 +96,29 @@ meta_cullable_cull_out_children (MetaCullable *cullable, * as well for the same reason, but omitted for simplicity in the * hopes that no-one will do that. */ - if (clutter_actor_has_effects (child)) - continue; + if (needs_culling && clutter_actor_has_effects (child)) + needs_culling = FALSE; - if (!META_IS_CULLABLE (child)) - continue; + if (needs_culling && !meta_actor_is_untransformed (child, NULL, NULL)) + needs_culling = FALSE; - if (!meta_actor_is_untransformed (child, NULL, NULL)) - continue; + if (needs_culling) + { + clutter_actor_get_position (child, &x, &y); - clutter_actor_get_position (child, &x, &y); + /* Temporarily move to the coordinate system of the actor */ + cairo_region_translate (unobscured_region, - x, - y); + cairo_region_translate (clip_region, - x, - y); - /* Temporarily move to the coordinate system of the actor */ - cairo_region_translate (unobscured_region, - x, - y); - cairo_region_translate (clip_region, - x, - y); + meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region); - - cairo_region_translate (unobscured_region, x, y); - cairo_region_translate (clip_region, x, y); + cairo_region_translate (unobscured_region, x, y); + cairo_region_translate (clip_region, x, y); + } + else + { + meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL); + } } } diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 6c11d7036..14248771a 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -863,8 +863,10 @@ meta_shaped_texture_cull_out (MetaCullable *cullable, { if (priv->opaque_region) { - cairo_region_subtract (unobscured_region, priv->opaque_region); - cairo_region_subtract (clip_region, priv->opaque_region); + if (unobscured_region) + cairo_region_subtract (unobscured_region, priv->opaque_region); + if (clip_region) + cairo_region_subtract (clip_region, priv->opaque_region); } } } diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h index 0207a88f4..9c6a8476e 100644 --- a/src/compositor/meta-window-actor-private.h +++ b/src/compositor/meta-window-actor-private.h @@ -59,9 +59,6 @@ void meta_window_actor_set_updates_frozen (MetaWindowActor *self, void meta_window_actor_queue_frame_drawn (MetaWindowActor *self, gboolean no_delay_frame); -void meta_window_actor_set_unobscured_region (MetaWindowActor *self, - cairo_region_t *unobscured_region); - void meta_window_actor_effect_completed (MetaWindowActor *actor, gulong event); diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 4084b6978..97654f034 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -1707,7 +1707,7 @@ 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. */ -void +static void meta_window_actor_set_unobscured_region (MetaWindowActor *self, cairo_region_t *unobscured_region) { @@ -1744,13 +1744,19 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self, if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow) { g_clear_pointer (&priv->shadow_clip, cairo_region_destroy); - priv->shadow_clip = cairo_region_copy (beneath_region); - if (clip_shadow_under_window (self)) + if (beneath_region) { - cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); - cairo_region_subtract (priv->shadow_clip, frame_bounds); + priv->shadow_clip = cairo_region_copy (beneath_region); + + if (clip_shadow_under_window (self)) + { + cairo_region_t *frame_bounds = meta_window_get_frame_bounds (priv->window); + cairo_region_subtract (priv->shadow_clip, frame_bounds); + } } + else + priv->shadow_clip = NULL; } } diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index a36d5961b..542060531 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -115,8 +115,6 @@ meta_window_group_paint (ClutterActor *actor) { cairo_region_t *clip_region; cairo_region_t *unobscured_region; - ClutterActorIter iter; - ClutterActor *child; cairo_rectangle_int_t visible_rect, clip_rect; int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; @@ -125,18 +123,6 @@ meta_window_group_paint (ClutterActor *actor) MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); ClutterActor *stage = clutter_actor_get_stage (actor); - /* Start off by treating all windows as completely unobscured, so damage anywhere - * in a window queues redraws, but confine it more below. */ - clutter_actor_iter_init (&iter, actor); - while (clutter_actor_iter_next (&iter, &child)) - { - if (META_IS_WINDOW_ACTOR (child)) - { - MetaWindowActor *window_actor = META_WINDOW_ACTOR (child); - meta_window_actor_set_unobscured_region (window_actor, NULL); - } - } - /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window