cullable: Split unobscured and redraw clip region culling

This splits culling into two different phases to move unobscured region
culling to pre-paint to fix #2680. This is needed as direct scanout
skips the paint phase altogether, but the pre-paint phase always runs as
it's used for selecting the direct scanout surface.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3127>
This commit is contained in:
msizanoen 2023-06-11 13:18:29 +07:00 committed by Marge Bot
parent 40de265f90
commit 6b79a0bae1
11 changed files with 219 additions and 209 deletions

View File

@ -56,6 +56,7 @@
#include "clutter/clutter-mutter.h"
#include "cogl/cogl.h"
#include "compositor/meta-cullable.h"
#include "compositor/meta-later-private.h"
#include "compositor/meta-window-actor-private.h"
#include "compositor/meta-window-group-private.h"
@ -1028,9 +1029,30 @@ meta_compositor_real_before_paint (MetaCompositor *compositor,
{
MetaCompositorPrivate *priv =
meta_compositor_get_instance_private (compositor);
ClutterActor *stage = meta_backend_get_stage (priv->backend);
ClutterStageView *stage_view;
cairo_rectangle_int_t stage_rect;
cairo_region_t *unobscured_region;
GList *l;
stage_rect = (cairo_rectangle_int_t) {
0, 0,
clutter_actor_get_width (stage),
clutter_actor_get_height (stage),
};
unobscured_region = cairo_region_create_rectangle (&stage_rect);
meta_cullable_cull_unobscured (META_CULLABLE (priv->window_group), unobscured_region);
cairo_region_destroy (unobscured_region);
unobscured_region = cairo_region_create_rectangle (&stage_rect);
meta_cullable_cull_unobscured (META_CULLABLE (priv->top_window_group), unobscured_region);
cairo_region_destroy (unobscured_region);
unobscured_region = cairo_region_create_rectangle (&stage_rect);
meta_cullable_cull_unobscured (META_CULLABLE (priv->feedback_group), unobscured_region);
cairo_region_destroy (unobscured_region);
stage_view = meta_compositor_view_get_stage_view (compositor_view);
for (l = priv->windows; l; l = l->next)

View File

@ -164,36 +164,34 @@ meta_background_actor_new (MetaDisplay *display,
}
static void
meta_background_actor_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_background_actor_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
if (!self->content)
return;
meta_background_content_cull_out (self->content,
unobscured_region,
clip_region);
meta_background_content_cull_unobscured (self->content, unobscured_region);
}
static void
meta_background_actor_reset_culling (MetaCullable *cullable)
meta_background_actor_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
if (!self->content)
return;
meta_background_content_reset_culling (self->content);
meta_background_content_cull_redraw_clip (self->content, clip_region);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_background_actor_cull_out;
iface->reset_culling = meta_background_actor_reset_culling;
iface->cull_unobscured = meta_background_actor_cull_unobscured;
iface->cull_redraw_clip = meta_background_actor_cull_redraw_clip;
}
/**

View File

@ -6,8 +6,8 @@
cairo_region_t *meta_background_content_get_clip_region (MetaBackgroundContent *self);
void meta_background_content_cull_out (MetaBackgroundContent *self,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void meta_background_content_cull_unobscured (MetaBackgroundContent *self,
cairo_region_t *unobscured_region);
void meta_background_content_reset_culling (MetaBackgroundContent *self);
void meta_background_content_cull_redraw_clip (MetaBackgroundContent *self,
cairo_region_t *clip_region);

View File

@ -1215,17 +1215,15 @@ meta_background_content_get_clip_region (MetaBackgroundContent *self)
}
void
meta_background_content_cull_out (MetaBackgroundContent *self,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_background_content_cull_unobscured (MetaBackgroundContent *self,
cairo_region_t *unobscured_region)
{
set_unobscured_region (self, unobscured_region);
set_clip_region (self, clip_region);
}
void
meta_background_content_reset_culling (MetaBackgroundContent *self)
meta_background_content_cull_redraw_clip (MetaBackgroundContent *self,
cairo_region_t *clip_region)
{
set_unobscured_region (self, NULL);
set_clip_region (self, NULL);
set_clip_region (self, clip_region);
}

View File

@ -30,24 +30,24 @@ meta_background_group_class_init (MetaBackgroundGroupClass *klass)
}
static void
meta_background_group_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_background_group_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
meta_cullable_cull_unobscured_children (cullable, unobscured_region);
}
static void
meta_background_group_reset_culling (MetaCullable *cullable)
meta_background_group_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
meta_cullable_reset_culling_children (cullable);
meta_cullable_cull_redraw_clip_children (cullable, clip_region);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_background_group_cull_out;
iface->reset_culling = meta_background_group_reset_culling;
iface->cull_unobscured = meta_background_group_cull_unobscured;
iface->cull_redraw_clip = meta_background_group_cull_redraw_clip;
}
static void

View File

@ -75,21 +75,13 @@ region_apply_transform_expand_maybe_ref (cairo_region_t *region,
* so that actors underneath know not to draw there as well.
*/
/**
* meta_cullable_cull_out_children:
* @cullable: The #MetaCullable
* @unobscured_region: The unobscured region, as passed into cull_out()
* @clip_region: The clip region, as passed into cull_out()
*
* This is a helper method for actors that want to recurse over their
* child actors, and cull them out.
*
* See #MetaCullable and meta_cullable_cull_out() for more details.
*/
void
meta_cullable_cull_out_children (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
typedef void (* ChildCullMethod) (MetaCullable *cullable,
cairo_region_t *region);
static void
cull_out_children_common (MetaCullable *cullable,
cairo_region_t *region,
ChildCullMethod method)
{
ClutterActor *actor = CLUTTER_ACTOR (cullable);
ClutterActor *child;
@ -103,7 +95,7 @@ meta_cullable_cull_out_children (MetaCullable *cullable,
if (!META_IS_CULLABLE (child))
continue;
needs_culling = (unobscured_region != NULL && clip_region != NULL);
needs_culling = (region != NULL);
if (needs_culling && !clutter_actor_is_visible (child))
needs_culling = FALSE;
@ -129,8 +121,7 @@ meta_cullable_cull_out_children (MetaCullable *cullable,
if (needs_culling)
{
cairo_region_t *actor_unobscured_region, *actor_clip_region;
cairo_region_t *reduced_unobscured_region, *reduced_clip_region;
cairo_region_t *actor_region, *reduced_region;
graphene_matrix_t actor_transform, inverted_actor_transform;
clutter_actor_get_transform (child, &actor_transform);
@ -138,9 +129,7 @@ meta_cullable_cull_out_children (MetaCullable *cullable,
if (graphene_matrix_is_identity (&actor_transform))
{
/* No transformation needed, simply pass through to child */
meta_cullable_cull_out (META_CULLABLE (child),
unobscured_region,
clip_region);
method (META_CULLABLE (child), region);
continue;
}
@ -148,71 +137,72 @@ meta_cullable_cull_out_children (MetaCullable *cullable,
&inverted_actor_transform) ||
!graphene_matrix_is_2d (&actor_transform))
{
meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL);
method (META_CULLABLE (child), NULL);
continue;
}
actor_unobscured_region =
region_apply_transform_expand_maybe_ref (unobscured_region,
&inverted_actor_transform);
actor_clip_region =
region_apply_transform_expand_maybe_ref (clip_region,
actor_region =
region_apply_transform_expand_maybe_ref (region,
&inverted_actor_transform);
g_assert (actor_unobscured_region && actor_clip_region);
g_assert (actor_region);
meta_cullable_cull_out (META_CULLABLE (child),
actor_unobscured_region,
actor_clip_region);
method (META_CULLABLE (child), actor_region);
reduced_unobscured_region =
region_apply_transform_expand_maybe_ref (actor_unobscured_region,
&actor_transform);
reduced_clip_region =
region_apply_transform_expand_maybe_ref (actor_clip_region,
reduced_region =
region_apply_transform_expand_maybe_ref (actor_region,
&actor_transform);
g_assert (reduced_unobscured_region && reduced_clip_region);
g_assert (reduced_region);
cairo_region_intersect (unobscured_region, reduced_unobscured_region);
cairo_region_intersect (clip_region, reduced_clip_region);
cairo_region_intersect (region, reduced_region);
cairo_region_destroy (actor_unobscured_region);
cairo_region_destroy (actor_clip_region);
cairo_region_destroy (reduced_unobscured_region);
cairo_region_destroy (reduced_clip_region);
cairo_region_destroy (actor_region);
cairo_region_destroy (reduced_region);
}
else
{
meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL);
method (META_CULLABLE (child), NULL);
}
}
}
/**
* meta_cullable_reset_culling_children:
* meta_cullable_cull_unobscured_children:
* @cullable: The #MetaCullable
* @unobscured_region: The unobscured region, as passed into cull_unobscured()
*
* This is a helper method for actors that want to recurse over their
* child actors, and cull them out.
*
* See #MetaCullable and meta_cullable_reset_culling() for more details.
* See #MetaCullable and meta_cullable_cull_unobscured() for more details.
*/
void
meta_cullable_reset_culling_children (MetaCullable *cullable)
meta_cullable_cull_unobscured_children (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
ClutterActor *actor = CLUTTER_ACTOR (cullable);
ClutterActor *child;
ClutterActorIter iter;
cull_out_children_common (cullable,
unobscured_region,
meta_cullable_cull_unobscured);
}
clutter_actor_iter_init (&iter, actor);
while (clutter_actor_iter_next (&iter, &child))
{
if (!META_IS_CULLABLE (child))
continue;
meta_cullable_reset_culling (META_CULLABLE (child));
}
/**
* meta_cullable_cull_redraw_clip_children:
* @cullable: The #MetaCullable
* @clip_region: The clip region, as passed into cull_redraw_clip()
*
* This is a helper method for actors that want to recurse over their
* child actors, and cull them out.
*
* See #MetaCullable and meta_cullable_cull_redraw_clip() for more details.
*/
void
meta_cullable_cull_redraw_clip_children (MetaCullable *cullable,
cairo_region_t *clip_region)
{
cull_out_children_common (cullable,
clip_region,
meta_cullable_cull_redraw_clip);
}
static void
@ -221,48 +211,48 @@ meta_cullable_default_init (MetaCullableInterface *iface)
}
/**
* meta_cullable_cull_out:
* meta_cullable_cull_unobscured:
* @cullable: The #MetaCullable
* @unobscured_region: The unobscured region, in @cullable's space.
*
* When #MetaWindowGroup is painted, we walk over its direct cullable
* children from top to bottom and ask themselves to "cull out". Cullables
* can use @unobscured_region record what parts of their window are unobscured
* for e.g. scheduling repaints.
*
* Actors that may have fully opaque parts should also subtract out a region
* that is fully opaque from @unobscured_region.
*
* Actors that have children can also use the meta_cullable_cull_unobscured_children()
* helper method to do a simple cull across all their children.
*/
void
meta_cullable_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
META_CULLABLE_GET_IFACE (cullable)->cull_unobscured (cullable, unobscured_region);
}
/**
* meta_cullable_cull_redraw_clip:
* @cullable: The #MetaCullable
* @clip_region: The clip region, in @cullable's space.
*
* When #MetaWindowGroup is painted, we walk over its direct cullable
* children from top to bottom and ask themselves to "cull out". Cullables
* can use @unobscured_region and @clip_region to clip their drawing. Actors
* interested in eliminating overdraw should copy the @clip_region and only
* paint those parts, as everything else has been obscured by actors above it.
* can use @clip_region to clip their drawing. Actors interested in eliminating
* overdraw should copy the @clip_region and only paint those parts, as
* everything else has been obscured by actors above it.
*
* Actors that may have fully opaque parts should also subtract out a region
* that is fully opaque from @unobscured_region and @clip_region.
* that is fully opaque from @clip_region.
*
* @unobscured_region and @clip_region are extremely similar. The difference
* is that @clip_region starts off with the stage's clip, if Clutter detects
* that we're doing a clipped redraw. @unobscured_region, however, starts off
* with the full stage size, so actors that may want to record what parts of
* their window are unobscured for e.g. scheduling repaints can do so.
*
* Actors that have children can also use the meta_cullable_cull_out_children()
* Actors that have children can also use the meta_cullable_cull_redraw_clip_children()
* helper method to do a simple cull across all their children.
*/
void
meta_cullable_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_cullable_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region);
}
/**
* meta_cullable_reset_culling:
* @cullable: The #MetaCullable
*
* Actors that copied data in their cull_out() implementation can now
* reset their data, as the paint is now over. Additional paints may be
* done by #ClutterClone or similar, and they should not be affected by
* the culling operation.
*/
void
meta_cullable_reset_culling (MetaCullable *cullable)
{
META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable);
META_CULLABLE_GET_IFACE (cullable)->cull_redraw_clip (cullable, clip_region);
}

View File

@ -35,21 +35,21 @@ struct _MetaCullableInterface
{
GTypeInterface g_iface;
void (* cull_out) (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void (* reset_culling) (MetaCullable *cullable);
void (* cull_unobscured) (MetaCullable *cullable,
cairo_region_t *unobscured_region);
void (* cull_redraw_clip) (MetaCullable *cullable,
cairo_region_t *clip_region);
};
void meta_cullable_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void meta_cullable_reset_culling (MetaCullable *cullable);
void meta_cullable_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region);
void meta_cullable_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region);
/* Utility methods for implementations */
void meta_cullable_cull_out_children (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region);
void meta_cullable_reset_culling_children (MetaCullable *cullable);
void meta_cullable_cull_unobscured_children (MetaCullable *cullable,
cairo_region_t *unobscured_region);
void meta_cullable_cull_redraw_clip_children (MetaCullable *cullable,
cairo_region_t *clip_region);
G_END_DECLS

View File

@ -237,17 +237,15 @@ meta_surface_actor_is_opaque (MetaSurfaceActor *self)
}
static void
meta_surface_actor_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
subtract_opaque_region (MetaSurfaceActor *surface_actor,
cairo_region_t *region)
{
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
MetaSurfaceActorPrivate *priv =
meta_surface_actor_get_instance_private (surface_actor);
uint8_t opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (cullable));
uint8_t opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (surface_actor));
set_unobscured_region (surface_actor, unobscured_region);
set_clip_region (surface_actor, clip_region);
if (!region)
return;
if (opacity == 0xff)
{
@ -258,26 +256,37 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
if (!opaque_region)
return;
if (unobscured_region)
cairo_region_subtract (unobscured_region, opaque_region);
if (clip_region)
cairo_region_subtract (clip_region, opaque_region);
cairo_region_subtract (region, opaque_region);
}
}
static void
meta_surface_actor_reset_culling (MetaCullable *cullable)
meta_surface_actor_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
set_clip_region (surface_actor, NULL);
set_clip_region (surface_actor, clip_region);
subtract_opaque_region (surface_actor, clip_region);
}
static void
meta_surface_actor_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
set_unobscured_region (surface_actor, unobscured_region);
subtract_opaque_region (surface_actor, unobscured_region);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_surface_actor_cull_out;
iface->reset_culling = meta_surface_actor_reset_culling;
iface->cull_redraw_clip = meta_surface_actor_cull_redraw_clip;
iface->cull_unobscured = meta_surface_actor_cull_unobscured;
}
static void

View File

@ -80,24 +80,24 @@ surface_container_new (MetaWindowActor *window_actor)
}
static void
surface_container_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
surface_container_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
meta_cullable_cull_unobscured_children (cullable, unobscured_region);
}
static void
surface_container_reset_culling (MetaCullable *cullable)
surface_container_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
meta_cullable_reset_culling_children (cullable);
meta_cullable_cull_redraw_clip_children (cullable, clip_region);
}
static void
surface_container_cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = surface_container_cull_out;
iface->reset_culling = surface_container_reset_culling;
iface->cull_unobscured = surface_container_cull_unobscured;
iface->cull_redraw_clip = surface_container_cull_redraw_clip;
}
static void
@ -286,16 +286,12 @@ calculate_background_cull_region (MetaWindowActorWayland *self)
}
static void
meta_window_actor_wayland_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
subtract_background_opaque_region (MetaWindowActorWayland *self,
cairo_region_t *region)
{
MetaWindowActorWayland *self =
META_WINDOW_ACTOR_WAYLAND (cullable);
if (!region)
return;
meta_cullable_cull_out_children (META_CULLABLE (self),
unobscured_region,
clip_region);
if (self->background &&
clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
{
@ -303,26 +299,41 @@ meta_window_actor_wayland_cull_out (MetaCullable *cullable,
background_cull_region = calculate_background_cull_region (self);
if (unobscured_region)
cairo_region_subtract (unobscured_region, background_cull_region);
if (clip_region)
cairo_region_subtract (clip_region, background_cull_region);
cairo_region_subtract (region, background_cull_region);
cairo_region_destroy (background_cull_region);
}
}
static void
meta_window_actor_wayland_reset_culling (MetaCullable *cullable)
meta_window_actor_wayland_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
meta_cullable_reset_culling_children (cullable);
MetaWindowActorWayland *self =
META_WINDOW_ACTOR_WAYLAND (cullable);
meta_cullable_cull_unobscured_children (META_CULLABLE (self), unobscured_region);
subtract_background_opaque_region (self, unobscured_region);
}
static void
meta_window_actor_wayland_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaWindowActorWayland *self =
META_WINDOW_ACTOR_WAYLAND (cullable);
meta_cullable_cull_redraw_clip_children (META_CULLABLE (self), clip_region);
subtract_background_opaque_region (self, clip_region);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_window_actor_wayland_cull_out;
iface->reset_culling = meta_window_actor_wayland_reset_culling;
iface->cull_unobscured = meta_window_actor_wayland_cull_unobscured;
iface->cull_redraw_clip = meta_window_actor_wayland_cull_redraw_clip;
}
static MetaSurfaceActor *

View File

@ -1504,34 +1504,28 @@ meta_window_actor_x11_constructed (GObject *object)
}
static void
meta_window_actor_x11_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_window_actor_x11_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
meta_cullable_cull_unobscured_children (cullable, unobscured_region);
}
static void
meta_window_actor_x11_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
MetaWindowActorX11 *self = META_WINDOW_ACTOR_X11 (cullable);
meta_cullable_cull_out_children (cullable,
unobscured_region,
clip_region);
meta_cullable_cull_redraw_clip_children (cullable, clip_region);
set_clip_region_beneath (self, clip_region);
}
static void
meta_window_actor_x11_reset_culling (MetaCullable *cullable)
{
MetaWindowActorX11 *actor_x11 = META_WINDOW_ACTOR_X11 (cullable);
g_clear_pointer (&actor_x11->shadow_clip, cairo_region_destroy);
meta_cullable_reset_culling_children (cullable);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_window_actor_x11_cull_out;
iface->reset_culling = meta_window_actor_x11_reset_culling;
iface->cull_unobscured = meta_window_actor_x11_cull_unobscured;
iface->cull_redraw_clip = meta_window_actor_x11_cull_redraw_clip;
}
static void

View File

@ -31,24 +31,24 @@ G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
static void
meta_window_group_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,
cairo_region_t *clip_region)
meta_window_group_cull_unobscured (MetaCullable *cullable,
cairo_region_t *unobscured_region)
{
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
meta_cullable_cull_unobscured_children (cullable, unobscured_region);
}
static void
meta_window_group_reset_culling (MetaCullable *cullable)
meta_window_group_cull_redraw_clip (MetaCullable *cullable,
cairo_region_t *clip_region)
{
meta_cullable_reset_culling_children (cullable);
meta_cullable_cull_redraw_clip_children (cullable, clip_region);
}
static void
cullable_iface_init (MetaCullableInterface *iface)
{
iface->cull_out = meta_window_group_cull_out;
iface->reset_culling = meta_window_group_reset_culling;
iface->cull_unobscured = meta_window_group_cull_unobscured;
iface->cull_redraw_clip = meta_window_group_cull_redraw_clip;
}
static void
@ -61,17 +61,12 @@ meta_window_group_paint (ClutterActor *actor,
ClutterActor *stage = clutter_actor_get_stage (actor);
const cairo_region_t *redraw_clip;
cairo_region_t *clip_region;
cairo_region_t *unobscured_region;
cairo_rectangle_int_t visible_rect;
int screen_width, screen_height;
graphene_matrix_t stage_to_actor;
redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
if (!redraw_clip)
goto fail;
meta_display_get_size (window_group->display, &screen_width, &screen_height);
/* 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.
@ -120,12 +115,6 @@ meta_window_group_paint (ClutterActor *actor,
if (!graphene_matrix_is_2d (&stage_to_actor))
goto fail;
visible_rect.x = visible_rect.y = 0;
visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
unobscured_region = cairo_region_create_rectangle (&visible_rect);
/* Get the clipped redraw bounds so that we can avoid painting shadows on
* windows that don't need to be painted in this frame. In the case of a
* multihead setup with mismatched monitor sizes, we could intersect this
@ -134,14 +123,13 @@ meta_window_group_paint (ClutterActor *actor,
clip_region = meta_region_apply_matrix_transform_expand (redraw_clip,
&stage_to_actor);
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
meta_cullable_cull_redraw_clip (META_CULLABLE (window_group), clip_region);
cairo_region_destroy (unobscured_region);
cairo_region_destroy (clip_region);
parent_actor_class->paint (actor, paint_context);
meta_cullable_reset_culling (META_CULLABLE (window_group));
meta_cullable_cull_redraw_clip (META_CULLABLE (window_group), NULL);
return;