From c483b52d240136cf49b358cde2c0d2c0ed237e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 6 Feb 2020 09:00:12 +0100 Subject: [PATCH] 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 --- clutter/clutter/clutter-stage-private.h | 6 +- clutter/clutter/clutter-stage.c | 59 ++++++++++--------- clutter/clutter/clutter-stage.h | 5 +- clutter/clutter/cogl/clutter-stage-cogl.c | 39 ++---------- src/backends/meta-stage.c | 8 ++- .../clutter/conform/actor-shader-effect.c | 1 + 6 files changed, 50 insertions(+), 68 deletions(-) diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h index 7a8429067..c8c1ef34a 100644 --- a/clutter/clutter/clutter-stage-private.h +++ b/clutter/clutter/clutter-stage-private.h @@ -36,9 +36,9 @@ typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry; /* stage */ ClutterStageWindow *_clutter_stage_get_default_window (void); -void _clutter_stage_paint_view (ClutterStage *stage, - ClutterStageView *view, - const cairo_rectangle_int_t *clip); +void clutter_stage_paint_view (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip); void _clutter_stage_emit_after_paint (ClutterStage *stage); diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 25735c264..24930df70 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -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; @@ -903,15 +901,18 @@ 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) +clutter_stage_do_paint_view (ClutterStage *stage, + ClutterStageView *view, + 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, - ClutterStageView *view, - const cairo_rectangle_int_t *clip) +clutter_stage_paint_view (ClutterStage *stage, + ClutterStageView *view, + 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 @@ -1980,13 +1977,11 @@ clutter_stage_finalize (GObject *object) } static void -clutter_stage_real_paint_view (ClutterStage *stage, - ClutterStageView *view) +clutter_stage_real_paint_view (ClutterStage *stage, + 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) - return NULL; + { + 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); diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h index 5910e6140..11f2e8716 100644 --- a/clutter/clutter/clutter-stage.h +++ b/clutter/clutter/clutter-stage.h @@ -84,8 +84,9 @@ struct _ClutterStageClass gboolean (* delete_event) (ClutterStage *stage, ClutterEvent *event); - void (* paint_view) (ClutterStage *stage, - ClutterStageView *view); + void (* paint_view) (ClutterStage *stage, + ClutterStageView *view, + const cairo_region_t *redraw_clip); /*< private >*/ /* padding for future expansion */ diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c index 590061234..ec9e746bc 100644 --- a/clutter/clutter/cogl/clutter-stage-cogl.c +++ b/clutter/clutter/cogl/clutter-stage-cogl.c @@ -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); } } diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c index 478c60f33..4df6a4261 100644 --- a/src/backends/meta-stage.c +++ b/src/backends/meta-stage.c @@ -209,15 +209,17 @@ meta_stage_paint (ClutterActor *actor, } static void -meta_stage_paint_view (ClutterStage *stage, - ClutterStageView *view) +meta_stage_paint_view (ClutterStage *stage, + 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); } diff --git a/src/tests/clutter/conform/actor-shader-effect.c b/src/tests/clutter/conform/actor-shader-effect.c index 58d0a30b7..a2cea6d46 100644 --- a/src/tests/clutter/conform/actor-shader-effect.c +++ b/src/tests/clutter/conform/actor-shader-effect.c @@ -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);