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:
parent
c483b52d24
commit
fe1ccea1e1
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user