summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2013-11-18 00:18:32 -0500
committerEmmanuele Bassi <ebassi@gnome.org>2014-01-24 17:25:28 +0000
commitefddf53730a0714a28a567a988961a4ccfd01b9a (patch)
treed486c4b4017208bcfc3069fb15484883aa6bb4c7
parentcc82e1b55bd9598823495ec0da9078ff8f2fe2b6 (diff)
downloadclutter-efddf53730a0714a28a567a988961a4ccfd01b9a.tar.gz
stage: Remove the pick buffer caching
Since the journal is flushed on context switches, trying to use a cached buffer means that we will use glReadPixels when picking, which isn't what we want. Instead, always use a clipped draw, and remove the logic for caching the pick buffer. https://bugzilla.gnome.org/show_bug.cgi?id=712563 (cherry picked from commit a427c120c239a471024375277d5e03e9b8863835) Signed-off-by: Emmanuele Bassi <ebassi@gnome.org>
-rw-r--r--clutter/clutter-stage.c125
1 files changed, 15 insertions, 110 deletions
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
index ffc716e4d..9d634bc6f 100644
--- a/clutter/clutter-stage.c
+++ b/clutter/clutter-stage.c
@@ -125,16 +125,12 @@ struct _ClutterStagePrivate
ClutterStageHint stage_hints;
- gint picks_per_frame;
-
GArray *paint_volume_stack;
ClutterPlane current_clip_planes[4];
GList *pending_queue_redraws;
- ClutterPickMode pick_buffer_mode;
-
CoglFramebuffer *active_framebuffer;
gint sync_delay;
@@ -165,7 +161,6 @@ struct _ClutterStagePrivate
guint min_size_changed : 1;
guint dirty_viewport : 1;
guint dirty_projection : 1;
- guint have_valid_pick_buffer : 1;
guint accept_focus : 1;
guint motion_events_enabled : 1;
guint has_custom_perspective : 1;
@@ -1146,28 +1141,6 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
}
}
-static gboolean
-_clutter_stage_get_pick_buffer_valid (ClutterStage *stage, ClutterPickMode mode)
-{
- 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;
-}
-
-static void
-_clutter_stage_set_pick_buffer_valid (ClutterStage *stage,
- gboolean valid,
- ClutterPickMode mode)
-{
- g_return_if_fail (CLUTTER_IS_STAGE (stage));
-
- stage->priv->have_valid_pick_buffer = !!valid;
- stage->priv->pick_buffer_mode = mode;
-}
-
static void
clutter_stage_do_redraw (ClutterStage *stage)
{
@@ -1195,9 +1168,6 @@ clutter_stage_do_redraw (ClutterStage *stage)
_clutter_actor_get_debug_name (actor),
stage);
- _clutter_stage_set_pick_buffer_valid (stage, FALSE, -1);
- priv->picks_per_frame = 0;
-
_clutter_backend_ensure_context (backend, stage);
if (_clutter_context_get_show_fps ())
@@ -1464,7 +1434,8 @@ _clutter_stage_do_pick (ClutterStage *stage,
gboolean dither_enabled_save;
CoglFramebuffer *fb;
ClutterActor *actor;
- gboolean is_clipped;
+ gint dirty_x;
+ gint dirty_y;
gint read_x;
gint read_y;
int window_scale;
@@ -1519,64 +1490,25 @@ _clutter_stage_do_pick (ClutterStage *stage,
clutter_stage_ensure_current (stage);
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
- /* 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 (_clutter_stage_get_pick_buffer_valid (stage, mode))
- {
- CLUTTER_TIMER_START (_clutter_uprof_context, pick_read);
- cogl_read_pixels (x * window_scale,
- y * window_scale,
- 1, 1,
- COGL_READ_PIXELS_COLOR_BUFFER,
- COGL_PIXEL_FORMAT_RGBA_8888_PRE,
- pixel);
- CLUTTER_TIMER_STOP (_clutter_uprof_context, pick_read);
-
- CLUTTER_NOTE (PICK, "Reusing pick buffer from previous render to fetch "
- "actor at %i,%i", x, y);
-
- goto check_pixel;
- }
-
- priv->picks_per_frame++;
-
_clutter_backend_ensure_context (context->backend, stage);
/* needed for when a context switch happens */
_clutter_stage_maybe_setup_viewport (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 (priv->picks_per_frame < 2)
- {
- gint dirty_x;
- gint dirty_y;
+ _clutter_stage_window_get_dirty_pixel (priv->impl, &dirty_x, &dirty_y);
- _clutter_stage_window_get_dirty_pixel (priv->impl, &dirty_x, &dirty_y);
+ if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
+ cogl_clip_push_window_rectangle (dirty_x * window_scale, dirty_y * window_scale, 1, 1);
- if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
- cogl_clip_push_window_rectangle (dirty_x * window_scale, dirty_y * window_scale, 1, 1);
+ cogl_set_viewport (priv->viewport[0] * window_scale - x * window_scale + dirty_x * window_scale,
+ priv->viewport[1] * window_scale - y * window_scale + dirty_y * window_scale,
+ priv->viewport[2] * window_scale,
+ priv->viewport[3] * window_scale);
- cogl_set_viewport (priv->viewport[0] * window_scale - x * window_scale + dirty_x * window_scale,
- priv->viewport[1] * window_scale - y * window_scale + dirty_y * window_scale,
- priv->viewport[2] * window_scale,
- priv->viewport[3] * window_scale);
-
- read_x = dirty_x * window_scale;
- read_y = dirty_y * window_scale;
- is_clipped = TRUE;
- }
- else
- {
- read_x = x * window_scale;
- read_y = y * window_scale;
- is_clipped = FALSE;
- }
+ read_x = dirty_x * window_scale;
+ read_y = dirty_y * window_scale;
- CLUTTER_NOTE (PICK, "Performing %s pick at %i,%i",
- is_clipped ? "clipped" : "full", x, y);
+ CLUTTER_NOTE (PICK, "Performing pick at %i,%i", x, y);
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
CLUTTER_TIMER_START (_clutter_uprof_context, pick_clear);
@@ -1630,25 +1562,11 @@ _clutter_stage_do_pick (ClutterStage *stage,
/* Restore whether GL_DITHER was enabled */
cogl_framebuffer_set_dither_enabled (fb, dither_enabled_save);
- if (is_clipped)
- {
- if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
- cogl_clip_pop ();
-
- _clutter_stage_dirty_viewport (stage);
+ if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
+ cogl_clip_pop ();
- _clutter_stage_set_pick_buffer_valid (stage, FALSE, -1);
- }
- else
- {
- /* Notify the backend that we have trashed the contents of
- * the back buffer... */
- _clutter_stage_window_dirty_back_buffer (priv->impl);
-
- _clutter_stage_set_pick_buffer_valid (stage, TRUE, mode);
- }
+ _clutter_stage_dirty_viewport (stage);
-check_pixel:
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
{
actor = CLUTTER_ACTOR (stage);
@@ -2389,9 +2307,6 @@ clutter_stage_init (ClutterStage *self)
geom.width,
geom.height);
- _clutter_stage_set_pick_buffer_valid (self, FALSE, CLUTTER_PICK_ALL);
- priv->picks_per_frame = 0;
-
priv->paint_volume_stack =
g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume));
@@ -4139,16 +4054,6 @@ _clutter_stage_queue_actor_redraw (ClutterStage *stage,
}
#endif /* CLUTTER_ENABLE_DEBUG */
- /* We have an optimization in _clutter_stage_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, -1);
-
if (entry)
{
/* Ignore all requests to queue a redraw for an actor if a full