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