diff --git a/clutter/clutter/clutter-paint-context-private.h b/clutter/clutter/clutter-paint-context-private.h index 6d2f0e92c..a825c8ffd 100644 --- a/clutter/clutter/clutter-paint-context-private.h +++ b/clutter/clutter/clutter-paint-context-private.h @@ -20,7 +20,8 @@ #include "clutter-paint-context.h" -ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view); +ClutterPaintContext * clutter_paint_context_new_for_view (ClutterStageView *view, + const cairo_region_t *redraw_clip); gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context); diff --git a/clutter/clutter/clutter-paint-context.c b/clutter/clutter/clutter-paint-context.c index 1787435de..d0d334951 100644 --- a/clutter/clutter/clutter-paint-context.c +++ b/clutter/clutter/clutter-paint-context.c @@ -26,6 +26,8 @@ struct _ClutterPaintContext GList *framebuffers; ClutterStageView *view; + + cairo_region_t *redraw_clip; }; G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context, @@ -33,7 +35,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context, clutter_paint_context_unref) ClutterPaintContext * -clutter_paint_context_new_for_view (ClutterStageView *view) +clutter_paint_context_new_for_view (ClutterStageView *view, + const cairo_region_t *redraw_clip) { ClutterPaintContext *paint_context; CoglFramebuffer *framebuffer; @@ -41,6 +44,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view) paint_context = g_new0 (ClutterPaintContext, 1); g_ref_count_init (&paint_context->ref_count); paint_context->view = view; + paint_context->redraw_clip = cairo_region_copy (redraw_clip); framebuffer = clutter_stage_view_get_framebuffer (view); clutter_paint_context_push_framebuffer (paint_context, framebuffer); @@ -77,6 +81,7 @@ clutter_paint_context_dispose (ClutterPaintContext *paint_context) g_list_free_full (paint_context->framebuffers, cogl_object_unref); paint_context->framebuffers = NULL; + g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy); } void @@ -115,6 +120,12 @@ clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context) paint_context->framebuffers); } +const cairo_region_t * +clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context) +{ + return paint_context->redraw_clip; +} + /** * clutter_paint_context_get_framebuffer: * @paint_context: The #ClutterPaintContext diff --git a/clutter/clutter/clutter-paint-context.h b/clutter/clutter/clutter-paint-context.h index 59ce0fa45..c54f95c03 100644 --- a/clutter/clutter/clutter-paint-context.h +++ b/clutter/clutter/clutter-paint-context.h @@ -59,4 +59,7 @@ void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context, CLUTTER_EXPORT void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context); +CLUTTER_EXPORT +const cairo_region_t * clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context); + #endif /* CLUTTER_PAINT_CONTEXT_H */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 24930df70..ff7fed3bc 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -908,7 +908,7 @@ clutter_stage_do_paint_view (ClutterStage *stage, ClutterPaintContext *paint_context; cairo_rectangle_int_t clip_rect; - paint_context = clutter_paint_context_new_for_view (view); + paint_context = clutter_paint_context_new_for_view (view, redraw_clip); cairo_region_get_extents (redraw_clip, &clip_rect); setup_view_for_pick_or_paint (stage, view, &clip_rect); @@ -1631,26 +1631,6 @@ _clutter_stage_has_full_redraw_queued (ClutterStage *stage) return FALSE; } -cairo_region_t * -clutter_stage_get_redraw_clip (ClutterStage *stage) -{ - ClutterStagePrivate *priv; - cairo_rectangle_int_t clip; - cairo_region_t *region; - - g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); - - priv = stage->priv; - - region = _clutter_stage_window_get_redraw_clip (priv->impl); - if (region) - return region; - - /* Set clip to the full extents of the stage */ - _clutter_stage_window_get_geometry (priv->impl, &clip); - return cairo_region_create_rectangle (&clip); -} - static ClutterActor * _clutter_stage_do_pick_on_view (ClutterStage *stage, float x, diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h index 11f2e8716..f60bb3a8c 100644 --- a/clutter/clutter/clutter-stage.h +++ b/clutter/clutter/clutter-stage.h @@ -206,8 +206,6 @@ guchar * clutter_stage_read_pixels (ClutterStage gint width, gint height); -CLUTTER_EXPORT -cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage); CLUTTER_EXPORT void clutter_stage_ensure_viewport (ClutterStage *stage); CLUTTER_EXPORT diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index cca22b87d..49eb72b85 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -55,14 +55,23 @@ static void meta_window_group_paint (ClutterActor *actor, ClutterPaintContext *paint_context) { + MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); + ClutterActorClass *parent_actor_class = + CLUTTER_ACTOR_CLASS (meta_window_group_parent_class); + 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 paint_x_origin, paint_y_origin; int screen_width, screen_height; - MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); - ClutterActor *stage = clutter_actor_get_stage (actor); + redraw_clip = clutter_paint_context_get_redraw_clip (paint_context); + if (!redraw_clip) + { + parent_actor_class->paint (actor, paint_context); + return; + } meta_display_get_size (window_group->display, &screen_width, &screen_height); @@ -91,8 +100,7 @@ meta_window_group_paint (ClutterActor *actor, &paint_y_origin) || !meta_cullable_is_untransformed (META_CULLABLE (actor))) { - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor, - paint_context); + parent_actor_class->paint (actor, paint_context); return; } } @@ -108,13 +116,12 @@ meta_window_group_paint (ClutterActor *actor, unobscured_region = cairo_region_create_rectangle (&visible_rect); - /* Get the clipped redraw bounds from Clutter 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 with an accurate union of the - * monitors to avoid painting shadows that are visible only in the - * holes. */ - clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage)); + /* 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 + * with an accurate union of the monitors to avoid painting shadows that are + * visible only in the holes. */ + clip_region = cairo_region_copy (redraw_clip); cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin); @@ -123,8 +130,7 @@ meta_window_group_paint (ClutterActor *actor, cairo_region_destroy (unobscured_region); cairo_region_destroy (clip_region); - CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor, - paint_context); + parent_actor_class->paint (actor, paint_context); meta_cullable_reset_culling (META_CULLABLE (window_group)); }