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 */ /* stage */
ClutterStageWindow *_clutter_stage_get_default_window (void); ClutterStageWindow *_clutter_stage_get_default_window (void);
void _clutter_stage_paint_view (ClutterStage *stage, void clutter_stage_paint_view (ClutterStage *stage,
ClutterStageView *view, ClutterStageView *view,
const cairo_rectangle_int_t *clip); const cairo_region_t *redraw_clip);
void _clutter_stage_emit_after_paint (ClutterStage *stage); void _clutter_stage_emit_after_paint (ClutterStage *stage);

View File

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

View File

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

View File

@ -576,29 +576,12 @@ offset_scale_and_clamp_region (const cairo_region_t *region,
static void static void
paint_stage (ClutterStageCogl *stage_cogl, paint_stage (ClutterStageCogl *stage_cogl,
ClutterStageView *view, ClutterStageView *view,
cairo_region_t *fb_clip_region) cairo_region_t *redraw_clip)
{ {
ClutterStage *stage = stage_cogl->wrapper; 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_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); 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. */ /* Update the redraw clip region with the extra damage. */
cairo_region_union (stage_cogl->redraw_clip, view_damage); cairo_region_union (stage_cogl->redraw_clip, view_damage);
cairo_region_union (redraw_clip, view_damage);
cairo_region_destroy (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); 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); cogl_framebuffer_pop_clip (fb);
@ -971,24 +955,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
scissor_rect.width, scissor_rect.width,
scissor_rect.height); scissor_rect.height);
paint_stage (stage_cogl, view, fb_clip_region); paint_stage (stage_cogl, view, redraw_clip);
cogl_framebuffer_pop_clip (fb); cogl_framebuffer_pop_clip (fb);
} }
else else
{ {
cairo_rectangle_int_t clip; paint_stage (stage_cogl, view, redraw_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);
} }
} }

View File

@ -210,14 +210,16 @@ meta_stage_paint (ClutterActor *actor,
static void static void
meta_stage_paint_view (ClutterStage *stage, meta_stage_paint_view (ClutterStage *stage,
ClutterStageView *view) ClutterStageView *view,
const cairo_region_t *redraw_clip)
{ {
MetaStage *meta_stage = META_STAGE (stage); MetaStage *meta_stage = META_STAGE (stage);
notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT); notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_BEFORE_PAINT);
meta_stage->current_view = view; 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); notify_watchers_for_mode (meta_stage, view, META_STAGE_WATCH_AFTER_PAINT);
} }

View File

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