mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
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:
parent
40de265f90
commit
6b79a0bae1
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user