[clutter/clutter-1.16] stage: Remove the pick buffer caching



commit efddf53730a0714a28a567a988961a4ccfd01b9a
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Nov 18 00:18:32 2013 -0500

    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>

 clutter/clutter-stage.c |  125 ++++++-----------------------------------------
 1 files changed, 15 insertions(+), 110 deletions(-)
---
diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c
index ffc716e..9d634bc 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]