clutter/stage: Pass redraw clip instead of extents when painting view

That's the struct we have ready, the callee can just call
cairo_region_get_extents() if it only cares about the extents rectangle.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
This commit is contained in:
Jonas Ådahl 2020-02-06 09:00:12 +01:00
parent f3dcba27f5
commit c483b52d24
6 changed files with 50 additions and 68 deletions

View File

@ -36,9 +36,9 @@ typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry;
/* stage */
ClutterStageWindow *_clutter_stage_get_default_window (void);
void _clutter_stage_paint_view (ClutterStage *stage,
void clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip);
const cairo_region_t *redraw_clip);
void _clutter_stage_emit_after_paint (ClutterStage *stage);

View File

@ -144,8 +144,6 @@ struct _ClutterStagePrivate
gpointer paint_data;
GDestroyNotify paint_notify;
cairo_rectangle_int_t view_clip;
int update_freeze_count;
guint redraw_pending : 1;
@ -905,13 +903,16 @@ setup_view_for_pick_or_paint (ClutterStage *stage,
static void
clutter_stage_do_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip)
const cairo_region_t *redraw_clip)
{
ClutterPaintContext *paint_context;
cairo_rectangle_int_t clip_rect;
paint_context = clutter_paint_context_new_for_view (view);
setup_view_for_pick_or_paint (stage, view, clip);
cairo_region_get_extents (redraw_clip, &clip_rect);
setup_view_for_pick_or_paint (stage, view, &clip_rect);
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
clutter_paint_context_destroy (paint_context);
}
@ -920,9 +921,9 @@ clutter_stage_do_paint_view (ClutterStage *stage,
* for picking or painting...
*/
void
_clutter_stage_paint_view (ClutterStage *stage,
clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view,
const cairo_rectangle_int_t *clip)
const cairo_region_t *redraw_clip)
{
ClutterStagePrivate *priv = stage->priv;
@ -931,15 +932,11 @@ _clutter_stage_paint_view (ClutterStage *stage,
COGL_TRACE_BEGIN_SCOPED (ClutterStagePaintView, "Paint (view)");
priv->view_clip = *clip;
if (g_signal_has_handler_pending (stage, stage_signals[PAINT_VIEW],
0, TRUE))
g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view);
g_signal_emit (stage, stage_signals[PAINT_VIEW], 0, view, redraw_clip);
else
CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view);
priv->view_clip = (cairo_rectangle_int_t) { 0 };
CLUTTER_STAGE_GET_CLASS (stage)->paint_view (stage, view, redraw_clip);
}
void
@ -1981,12 +1978,10 @@ clutter_stage_finalize (GObject *object)
static void
clutter_stage_real_paint_view (ClutterStage *stage,
ClutterStageView *view)
ClutterStageView *view,
const cairo_region_t *redraw_clip)
{
ClutterStagePrivate *priv = stage->priv;
const cairo_rectangle_int_t *clip = &priv->view_clip;
clutter_stage_do_paint_view (stage, view, clip);
clutter_stage_do_paint_view (stage, view, redraw_clip);
}
static void
@ -2212,6 +2207,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
* ClutterStage::paint-view:
* @stage: the stage that received the event
* @view: a #ClutterStageView
* @redraw_clip: a #cairo_region_t with the redraw clip
*
* The ::paint-view signal is emitted before a #ClutterStageView is being
* painted.
@ -2226,8 +2222,9 @@ clutter_stage_class_init (ClutterStageClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterStageClass, paint_view),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
CLUTTER_TYPE_STAGE_VIEW);
G_TYPE_NONE, 2,
CLUTTER_TYPE_STAGE_VIEW,
G_TYPE_POINTER);
/**
* ClutterStage::presented: (skip)
@ -2803,13 +2800,17 @@ clutter_stage_read_pixels (ClutterStage *stage,
.height = height,
});
cairo_region_get_extents (clip, &clip_rect);
cairo_region_destroy (clip);
if (clip_rect.width == 0 || clip_rect.height == 0)
{
cairo_region_destroy (clip);
return NULL;
}
framebuffer = clutter_stage_view_get_framebuffer (view);
clutter_stage_do_paint_view (stage, view, &clip_rect);
clutter_stage_do_paint_view (stage, view, clip);
cairo_region_destroy (clip);
view_scale = clutter_stage_view_get_scale (view);
pixel_width = roundf (clip_rect.width * view_scale);
@ -4449,8 +4450,12 @@ capture_view_into (ClutterStage *stage,
if (paint)
{
cairo_region_t *region;
_clutter_stage_maybe_setup_viewport (stage, view);
clutter_stage_do_paint_view (stage, view, rect);
region = cairo_region_create_rectangle (rect);
clutter_stage_do_paint_view (stage, view, region);
cairo_region_destroy (region);
}
view_scale = clutter_stage_view_get_scale (view);

View File

@ -85,7 +85,8 @@ struct _ClutterStageClass
ClutterEvent *event);
void (* paint_view) (ClutterStage *stage,
ClutterStageView *view);
ClutterStageView *view,
const cairo_region_t *redraw_clip);
/*< private >*/
/* padding for future expansion */

View File

@ -576,29 +576,12 @@ offset_scale_and_clamp_region (const cairo_region_t *region,
static void
paint_stage (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
cairo_region_t *fb_clip_region)
cairo_region_t *redraw_clip)
{
ClutterStage *stage = stage_cogl->wrapper;
cairo_rectangle_int_t clip_rect;
cairo_rectangle_int_t paint_rect;
cairo_rectangle_int_t view_rect;
graphene_rect_t rect;
float fb_scale;
clutter_stage_view_get_layout (view, &view_rect);
fb_scale = clutter_stage_view_get_scale (view);
cairo_region_get_extents (fb_clip_region, &clip_rect);
_clutter_util_rect_from_rectangle (&clip_rect, &rect);
scale_and_clamp_rect (&rect, 1.0f / fb_scale, &paint_rect);
_clutter_util_rectangle_offset (&paint_rect,
view_rect.x,
view_rect.y,
&paint_rect);
_clutter_stage_maybe_setup_viewport (stage, view);
_clutter_stage_paint_view (stage, view, &paint_rect);
clutter_stage_paint_view (stage, view, redraw_clip);
clutter_stage_view_after_paint (view);
}
@ -863,6 +846,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
/* Update the redraw clip region with the extra damage. */
cairo_region_union (stage_cogl->redraw_clip, view_damage);
cairo_region_union (redraw_clip, view_damage);
cairo_region_destroy (view_damage);
@ -939,7 +923,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cogl_framebuffer_push_region_clip (fb, fb_clip_region);
}
paint_stage (stage_cogl, view, fb_clip_region);
paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb);
@ -971,24 +955,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
scissor_rect.width,
scissor_rect.height);
paint_stage (stage_cogl, view, fb_clip_region);
paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb);
}
else
{
cairo_rectangle_int_t clip;
cairo_region_t *view_region;
clip = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
.width = ceilf (view_rect.width * fb_scale),
.height = ceilf (view_rect.height * fb_scale)
};
view_region = cairo_region_create_rectangle (&clip);
paint_stage (stage_cogl, view, view_region);
cairo_region_destroy (view_region);
paint_stage (stage_cogl, view, redraw_clip);
}
}

View File

@ -210,14 +210,16 @@ meta_stage_paint (ClutterActor *actor,
static void
meta_stage_paint_view (ClutterStage *stage,
ClutterStageView *view)
ClutterStageView *view,
const cairo_region_t *redraw_clip)
{
MetaStage *meta_stage = META_STAGE (stage);
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT);
meta_stage->current_view = view;
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view);
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->paint_view (stage, view,
redraw_clip);
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT);
}

View File

@ -232,6 +232,7 @@ get_pixel (CoglFramebuffer *fb,
static void
view_painted_cb (ClutterStage *stage,
ClutterStageView *view,
cairo_region_t *redraw_clip,
gpointer data)
{
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);