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"
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);

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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));
}