clutter: Pass redraw clip via paint context

Instead of users fetching it via `clutter_stage_get_redraw_clip()`, pass
it via the paint context. This is helpful as it is only valid during a
paint, making it more obvious that it needs to be handled differently
when there is no redraw clip (i.e. we're painting off-screen).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
This commit is contained in:
Jonas Ådahl 2020-02-06 10:04:49 +01:00
parent c483b52d24
commit fe1ccea1e1
6 changed files with 37 additions and 38 deletions

View File

@ -20,7 +20,8 @@
#include "clutter-paint-context.h" #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); gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);

View File

@ -26,6 +26,8 @@ struct _ClutterPaintContext
GList *framebuffers; GList *framebuffers;
ClutterStageView *view; ClutterStageView *view;
cairo_region_t *redraw_clip;
}; };
G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context, G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
@ -33,7 +35,8 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
clutter_paint_context_unref) clutter_paint_context_unref)
ClutterPaintContext * 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; ClutterPaintContext *paint_context;
CoglFramebuffer *framebuffer; CoglFramebuffer *framebuffer;
@ -41,6 +44,7 @@ clutter_paint_context_new_for_view (ClutterStageView *view)
paint_context = g_new0 (ClutterPaintContext, 1); paint_context = g_new0 (ClutterPaintContext, 1);
g_ref_count_init (&paint_context->ref_count); g_ref_count_init (&paint_context->ref_count);
paint_context->view = view; paint_context->view = view;
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
framebuffer = clutter_stage_view_get_framebuffer (view); framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_paint_context_push_framebuffer (paint_context, framebuffer); 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, g_list_free_full (paint_context->framebuffers,
cogl_object_unref); cogl_object_unref);
paint_context->framebuffers = NULL; paint_context->framebuffers = NULL;
g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy);
} }
void void
@ -115,6 +120,12 @@ clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context)
paint_context->framebuffers); 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: * clutter_paint_context_get_framebuffer:
* @paint_context: The #ClutterPaintContext * @paint_context: The #ClutterPaintContext

View File

@ -59,4 +59,7 @@ void clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context); 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 */ #endif /* CLUTTER_PAINT_CONTEXT_H */

View File

@ -908,7 +908,7 @@ clutter_stage_do_paint_view (ClutterStage *stage,
ClutterPaintContext *paint_context; ClutterPaintContext *paint_context;
cairo_rectangle_int_t clip_rect; 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); cairo_region_get_extents (redraw_clip, &clip_rect);
setup_view_for_pick_or_paint (stage, view, &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; 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 * static ClutterActor *
_clutter_stage_do_pick_on_view (ClutterStage *stage, _clutter_stage_do_pick_on_view (ClutterStage *stage,
float x, float x,

View File

@ -206,8 +206,6 @@ guchar * clutter_stage_read_pixels (ClutterStage
gint width, gint width,
gint height); gint height);
CLUTTER_EXPORT
cairo_region_t * clutter_stage_get_redraw_clip (ClutterStage *stage);
CLUTTER_EXPORT CLUTTER_EXPORT
void clutter_stage_ensure_viewport (ClutterStage *stage); void clutter_stage_ensure_viewport (ClutterStage *stage);
CLUTTER_EXPORT CLUTTER_EXPORT

View File

@ -55,14 +55,23 @@ static void
meta_window_group_paint (ClutterActor *actor, meta_window_group_paint (ClutterActor *actor,
ClutterPaintContext *paint_context) 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 *clip_region;
cairo_region_t *unobscured_region; cairo_region_t *unobscured_region;
cairo_rectangle_int_t visible_rect; cairo_rectangle_int_t visible_rect;
int paint_x_origin, paint_y_origin; int paint_x_origin, paint_y_origin;
int screen_width, screen_height; int screen_width, screen_height;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); redraw_clip = clutter_paint_context_get_redraw_clip (paint_context);
ClutterActor *stage = clutter_actor_get_stage (actor); if (!redraw_clip)
{
parent_actor_class->paint (actor, paint_context);
return;
}
meta_display_get_size (window_group->display, &screen_width, &screen_height); meta_display_get_size (window_group->display, &screen_width, &screen_height);
@ -91,8 +100,7 @@ meta_window_group_paint (ClutterActor *actor,
&paint_y_origin) || &paint_y_origin) ||
!meta_cullable_is_untransformed (META_CULLABLE (actor))) !meta_cullable_is_untransformed (META_CULLABLE (actor)))
{ {
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor, parent_actor_class->paint (actor, paint_context);
paint_context);
return; return;
} }
} }
@ -108,13 +116,12 @@ meta_window_group_paint (ClutterActor *actor,
unobscured_region = cairo_region_create_rectangle (&visible_rect); unobscured_region = cairo_region_create_rectangle (&visible_rect);
/* Get the clipped redraw bounds from Clutter so that we can avoid /* Get the clipped redraw bounds so that we can avoid painting shadows on
* painting shadows on windows that don't need to be painted in this * windows that don't need to be painted in this frame. In the case of a
* frame. In the case of a multihead setup with mismatched monitor * multihead setup with mismatched monitor sizes, we could intersect this
* sizes, we could intersect this with an accurate union of the * with an accurate union of the monitors to avoid painting shadows that are
* monitors to avoid painting shadows that are visible only in the * visible only in the holes. */
* holes. */ clip_region = cairo_region_copy (redraw_clip);
clip_region = clutter_stage_get_redraw_clip (CLUTTER_STAGE (stage));
cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin); 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 (unobscured_region);
cairo_region_destroy (clip_region); cairo_region_destroy (clip_region);
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor, parent_actor_class->paint (actor, paint_context);
paint_context);
meta_cullable_reset_culling (META_CULLABLE (window_group)); meta_cullable_reset_culling (META_CULLABLE (window_group));
} }