Discard the current pick buffer...

if we are asked to pick with a different mode.

http://bugzilla.clutter-project.org/show_bug.cgi?id=2385
This commit is contained in:
Tomeu Vizoso 2010-10-27 19:02:47 +02:00 committed by Neil Roberts
parent b4588b57df
commit 373140c830
4 changed files with 31 additions and 11 deletions

View File

@ -236,7 +236,7 @@ _clutter_do_redraw (ClutterStage *stage)
ctx = _clutter_context_get_default (); ctx = _clutter_context_get_default ();
_clutter_stage_set_pick_buffer_valid (stage, FALSE); _clutter_stage_set_pick_buffer_valid (stage, FALSE, -1);
_clutter_stage_reset_picks_per_frame_counter (stage); _clutter_stage_reset_picks_per_frame_counter (stage);
_clutter_backend_ensure_context (ctx->backend, stage); _clutter_backend_ensure_context (ctx->backend, stage);
@ -576,7 +576,7 @@ _clutter_do_pick (ClutterStage *stage,
/* It's possible that we currently have a static scene and have renderered a /* 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 * full, unclipped pick buffer. If so we can simply continue to read from
* this cached buffer until the scene next changes. */ * this cached buffer until the scene next changes. */
if (_clutter_stage_get_pick_buffer_valid (stage)) if (_clutter_stage_get_pick_buffer_valid (stage, mode))
{ {
CLUTTER_TIMER_START (_clutter_uprof_context, pick_read); CLUTTER_TIMER_START (_clutter_uprof_context, pick_read);
cogl_read_pixels (x, y, 1, 1, cogl_read_pixels (x, y, 1, 1,
@ -653,9 +653,11 @@ _clutter_do_pick (ClutterStage *stage,
if (G_LIKELY (!(clutter_pick_debug_flags & if (G_LIKELY (!(clutter_pick_debug_flags &
CLUTTER_DEBUG_DUMP_PICK_BUFFERS))) CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
cogl_clip_pop (); cogl_clip_pop ();
_clutter_stage_set_pick_buffer_valid (stage, FALSE, -1);
} }
else else
_clutter_stage_set_pick_buffer_valid (stage, TRUE); _clutter_stage_set_pick_buffer_valid (stage, TRUE, mode);
/* Make sure Cogl flushes any batched geometry to the GPU driver */ /* Make sure Cogl flushes any batched geometry to the GPU driver */
cogl_flush (); cogl_flush ();

View File

@ -62,9 +62,11 @@ void _clutter_stage_process_queued_events (ClutterStage *stage);
void _clutter_stage_update_input_devices (ClutterStage *stage); void _clutter_stage_update_input_devices (ClutterStage *stage);
int _clutter_stage_get_pending_swaps (ClutterStage *stage); int _clutter_stage_get_pending_swaps (ClutterStage *stage);
gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage); gboolean _clutter_stage_has_full_redraw_queued (ClutterStage *stage);
void _clutter_stage_set_pick_buffer_valid (ClutterStage *stage, void _clutter_stage_set_pick_buffer_valid (ClutterStage *stage,
gboolean valid); gboolean valid,
gboolean _clutter_stage_get_pick_buffer_valid (ClutterStage *stage); ClutterPickMode mode);
gboolean _clutter_stage_get_pick_buffer_valid (ClutterStage *stage,
ClutterPickMode mode);
void _clutter_stage_increment_picks_per_frame_counter (ClutterStage *stage); void _clutter_stage_increment_picks_per_frame_counter (ClutterStage *stage);
void _clutter_stage_reset_picks_per_frame_counter (ClutterStage *stage); void _clutter_stage_reset_picks_per_frame_counter (ClutterStage *stage);
guint _clutter_stage_get_picks_per_frame_counter (ClutterStage *stage); guint _clutter_stage_get_picks_per_frame_counter (ClutterStage *stage);

View File

@ -133,6 +133,8 @@ struct _ClutterStagePrivate
GList *pending_queue_redraws; GList *pending_queue_redraws;
ClutterPickMode pick_buffer_mode;
guint relayout_pending : 1; guint relayout_pending : 1;
guint redraw_pending : 1; guint redraw_pending : 1;
guint is_fullscreen : 1; guint is_fullscreen : 1;
@ -1587,7 +1589,7 @@ clutter_stage_init (ClutterStage *self)
_clutter_stage_window_get_geometry (priv->impl, &geom); _clutter_stage_window_get_geometry (priv->impl, &geom);
_clutter_stage_set_viewport (self, 0, 0, geom.width, geom.height); _clutter_stage_set_viewport (self, 0, 0, geom.width, geom.height);
_clutter_stage_set_pick_buffer_valid (self, FALSE); _clutter_stage_set_pick_buffer_valid (self, FALSE, CLUTTER_PICK_ALL);
_clutter_stage_reset_picks_per_frame_counter (self); _clutter_stage_reset_picks_per_frame_counter (self);
priv->paint_volume_stack = priv->paint_volume_stack =
@ -3053,20 +3055,25 @@ clutter_stage_get_no_clear_hint (ClutterStage *stage)
} }
gboolean gboolean
_clutter_stage_get_pick_buffer_valid (ClutterStage *stage) _clutter_stage_get_pick_buffer_valid (ClutterStage *stage, ClutterPickMode mode)
{ {
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE);
if (stage->priv->pick_buffer_mode != mode)
return FALSE;
return stage->priv->have_valid_pick_buffer; return stage->priv->have_valid_pick_buffer;
} }
void void
_clutter_stage_set_pick_buffer_valid (ClutterStage *stage, _clutter_stage_set_pick_buffer_valid (ClutterStage *stage,
gboolean valid) gboolean valid,
ClutterPickMode mode)
{ {
g_return_if_fail (CLUTTER_IS_STAGE (stage)); g_return_if_fail (CLUTTER_IS_STAGE (stage));
stage->priv->have_valid_pick_buffer = !!valid; stage->priv->have_valid_pick_buffer = !!valid;
stage->priv->pick_buffer_mode = mode;
} }
void void
@ -3172,7 +3179,7 @@ _clutter_stage_queue_actor_redraw (ClutterStage *stage,
* state changes that affects painting *or* picking so we can use * state changes that affects painting *or* picking so we can use
* this point to invalidate any currently cached pick buffer. * this point to invalidate any currently cached pick buffer.
*/ */
_clutter_stage_set_pick_buffer_valid (stage, FALSE); _clutter_stage_set_pick_buffer_valid (stage, FALSE, -1);
if (entry) if (entry)
{ {

View File

@ -25,6 +25,15 @@ on_timeout (State *state)
int y, x; int y, x;
ClutterActor *over_actor = NULL; ClutterActor *over_actor = NULL;
/* This will cause an unclipped pick redraw that will get buffered.
We'll check below that this buffer is discarded because we also need
to pick non-reactive actors */
clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
CLUTTER_PICK_REACTIVE, 10, 10);
clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
CLUTTER_PICK_REACTIVE, 10, 10);
for (test_num = 0; test_num < 3; test_num++) for (test_num = 0; test_num < 3; test_num++)
{ {
if (test_num == 0) if (test_num == 0)