diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 944c0a465..e994af860 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -1780,7 +1780,6 @@ clutter_actor_real_queue_redraw (ClutterActor *self, ClutterActor *origin) { ClutterActor *parent; - ClutterMainContext *context; CLUTTER_NOTE (PAINT, "Redraw queued on '%s' (from: '%s')", get_actor_debug_name (self), @@ -1798,17 +1797,6 @@ clutter_actor_real_queue_redraw (ClutterActor *self, if (!CLUTTER_ACTOR_IS_VISIBLE (self)) return; - /* We have an optimization in _clutter_do_pick to detect when the scene is - * static so we can cache a full, un-clipped pick buffer to avoid continuous - * pick renders. - * - * Currently the assumption is that actors queue a redraw when some state - * changes that affects painting *or* picking so we can use this point - * to invalidate any currently cached pick buffer. - */ - context = _clutter_context_get_default (); - context->have_complete_pick_buffer = FALSE; - /* Although we could determine here that a full stage redraw * has already been queued and immediately bail out, we actually * guarantee that we will propagate a queue-redraw signal to our diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 0768833d6..7795f75b3 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -274,12 +274,8 @@ _clutter_do_redraw (ClutterStage *stage) ctx = _clutter_context_get_default (); - /* We have an optimization to avoid pick renders while scene is static. - * This is implied by seeing multiple picks per frame so we have to - * reset a pick counter each frame and also invalidate any current pick - * buffer. */ - ctx->picks_per_frame = 0; - ctx->have_complete_pick_buffer = FALSE; + _clutter_stage_set_pick_buffer_valid (stage, FALSE); + _clutter_stage_unset_pick_counter (stage); /* Before we can paint, we have to be sure we have the latest layout */ _clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage)); @@ -601,7 +597,7 @@ _clutter_do_pick (ClutterStage *stage, /* It's possible that we currently have a static scene and have renderered a * full, unclipped pick buffer. If so we can simply continue to read from * this cached buffer until the scene next changes. */ - if (context->have_complete_pick_buffer) + if (_clutter_stage_get_pick_buffer_valid (stage)) { CLUTTER_TIMER_START (_clutter_uprof_context, pick_read); cogl_read_pixels (x, y, 1, 1, @@ -628,7 +624,7 @@ _clutter_do_pick (ClutterStage *stage, goto result; } - context->picks_per_frame++; + _clutter_stage_increment_pick_counter (stage); _clutter_backend_ensure_context (context->backend, stage); @@ -638,7 +634,7 @@ _clutter_do_pick (ClutterStage *stage, /* If we are seeing multiple picks per frame that means the scene is static * so we promote to doing a non-scissored pick render so that all subsequent * picks for the same static scene won't require additional renders */ - if (context->picks_per_frame < 2) + if (_clutter_stage_get_pick_counter (stage) < 2) { if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))) @@ -680,7 +676,7 @@ _clutter_do_pick (ClutterStage *stage, cogl_clip_pop (); } else - context->have_complete_pick_buffer = TRUE; + _clutter_stage_set_pick_buffer_valid (stage, TRUE); /* Make sure Cogl flushes any batched geometry to the GPU driver */ cogl_flush (); diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index 7c460d393..30e4f75a9 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -183,9 +183,6 @@ struct _ClutterMainContext GList *repaint_funcs; ClutterSettings *settings; - - gint picks_per_frame; - gboolean have_complete_pick_buffer; }; #define CLUTTER_CONTEXT() (_clutter_context_get_default ()) @@ -279,6 +276,13 @@ int _clutter_stage_get_pending_swaps (ClutterStage *stage); gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage); +void _clutter_stage_set_pick_buffer_valid (ClutterStage *stage, + gboolean valid); +gboolean _clutter_stage_get_pick_buffer_valid (ClutterStage *stage); +void _clutter_stage_increment_pick_counter (ClutterStage *stage); +void _clutter_stage_unset_pick_counter (ClutterStage *stage); +guint _clutter_stage_get_pick_counter (ClutterStage *stage); + /* vfuncs implemented by backend */ GType _clutter_backend_impl_get_type (void); diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 7b7c8c867..6c3dd2928 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -116,6 +116,8 @@ struct _ClutterStagePrivate ClutterStageHint stage_hints; + gint picks_per_frame; + guint redraw_pending : 1; guint is_fullscreen : 1; guint is_cursor_visible : 1; @@ -126,6 +128,7 @@ struct _ClutterStagePrivate guint min_size_changed : 1; guint dirty_viewport : 1; guint dirty_projection : 1; + guint have_valid_pick_buffer : 1; }; enum @@ -734,6 +737,16 @@ clutter_stage_real_queue_redraw (ClutterActor *actor, else CLUTTER_CONTEXT ()->redraw_count += 1; + /* We have an optimization in _clutter_do_pick to detect when the + * scene is static so we can cache a full, un-clipped pick buffer to + * avoid continuous pick renders. + * + * Currently the assumption is that actors queue a redraw when some + * state changes that affects painting *or* picking so we can use + * this point to invalidate any currently cached pick buffer. + */ + _clutter_stage_set_pick_buffer_valid (stage, FALSE); + /* If the backend can't do anything with redraw clips (e.g. it already knows * it needs to redraw everything anyway) then don't spend time transforming * any clip regions into stage coordinates... */ @@ -2929,3 +2942,36 @@ clutter_stage_get_no_clear_hint (ClutterStage *stage) return (stage->priv->stage_hints & CLUTTER_STAGE_NO_CLEAR_ON_PAINT) != 0; } + +gboolean +_clutter_stage_get_pick_buffer_valid (ClutterStage *stage) +{ + return stage->priv->have_valid_pick_buffer; +} + +void +_clutter_stage_set_pick_buffer_valid (ClutterStage *stage, + gboolean valid) +{ + valid = !!valid; + + stage->priv->have_valid_pick_buffer = valid; +} + +void +_clutter_stage_increment_pick_counter (ClutterStage *stage) +{ + stage->priv->picks_per_frame += 1; +} + +void +_clutter_stage_unset_pick_counter (ClutterStage *stage) +{ + stage->priv->picks_per_frame = 0; +} + +guint +_clutter_stage_get_pick_counter (ClutterStage *stage) +{ + return stage->priv->picks_per_frame; +}