[arch-commits] Commit in mutter/trunk (4 files)

Jan Steffens heftig at archlinux.org
Thu Sep 12 21:06:46 UTC 2019


    Date: Thursday, September 12, 2019 @ 21:06:45
  Author: heftig
Revision: 362344

3.34.0-1

Modified:
  mutter/trunk/PKGBUILD
Deleted:
  mutter/trunk/0001-Add-point-polygon-testing-API.patch
  mutter/trunk/0001-Remove-GLX-threaded-swap-wait.patch
  mutter/trunk/0002-Geometric-OpenGL-less-picking.patch

------------------------------------------+
 0001-Add-point-polygon-testing-API.patch |  282 ----
 0001-Remove-GLX-threaded-swap-wait.patch |  467 -------
 0002-Geometric-OpenGL-less-picking.patch | 1714 -----------------------------
 PKGBUILD                                 |   39 
 4 files changed, 6 insertions(+), 2496 deletions(-)

Deleted: 0001-Add-point-polygon-testing-API.patch
===================================================================
--- 0001-Add-point-polygon-testing-API.patch	2019-09-12 20:57:17 UTC (rev 362343)
+++ 0001-Add-point-polygon-testing-API.patch	2019-09-12 21:06:45 UTC (rev 362344)
@@ -1,282 +0,0 @@
-From 37be90384d807c811785f51b5566e8b3b4db3ed3 Mon Sep 17 00:00:00 2001
-From: Daniel van Vugt <daniel.van.vugt at canonical.com>
-Date: Thu, 18 Jul 2019 16:56:41 +0800
-Subject: [PATCH 1/2] clutter-types: Add ClutterPoint polygon testing API
-
-https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
----
- clutter/clutter/clutter-base-types.c | 113 +++++++++++++++++++++++++++
- clutter/clutter/clutter-types.h      |   8 ++
- clutter/tests/conform/meson.build    |   1 +
- clutter/tests/conform/point.c        | 104 ++++++++++++++++++++++++
- 4 files changed, 226 insertions(+)
- create mode 100644 clutter/tests/conform/point.c
-
-diff --git a/clutter/clutter/clutter-base-types.c b/clutter/clutter/clutter-base-types.c
-index aeb25c90e..0d98c4814 100644
---- a/clutter/clutter/clutter-base-types.c
-+++ b/clutter/clutter/clutter-base-types.c
-@@ -570,6 +570,119 @@ G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterPoint, clutter_point,
-                                clutter_point_free,
-                                CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_point_progress))
- 
-+static int
-+clutter_point_compare_line (const ClutterPoint *p,
-+                            const ClutterPoint *a,
-+                            const ClutterPoint *b)
-+{
-+  /*
-+   * Given two vectors ab and ap:
-+   *   ab = (x1, y1, 0)
-+   *   ap = (x2, y2, 0)
-+   * their cross product is a vector:
-+   *   ab x ap = (0, 0, x1 * y2 - y1 * x2)
-+   */
-+  float x1 = b->x - a->x;
-+  float y1 = b->y - a->y;
-+  float x2 = p->x - a->x;
-+  float y2 = p->y - a->y;
-+  float cross_z = x1 * y2 - y1 * x2;
-+
-+  /*
-+   * The cross product is also proportional to the sine of the angle between
-+   * the vectors, so its sign tells us the sign of the angle between the two
-+   * vectors. That is whether p is left of or right of line ab.
-+   */
-+  if (cross_z > 0.f)
-+    return +1;
-+  else if (cross_z < 0.f)
-+    return -1;
-+  else
-+    return 0;
-+}
-+
-+static int
-+clutter_point_compare_polygon (const ClutterPoint *point,
-+                               const ClutterPoint *vertices,
-+                               unsigned int        nvertices)
-+{
-+  unsigned int i;
-+  int first_side = 0;
-+  gboolean on_an_edge = FALSE;
-+
-+  g_return_val_if_fail (nvertices >= 3, +1);
-+
-+  for (i = 0; i < nvertices; i++)
-+    {
-+      int side = clutter_point_compare_line (point,
-+                                             &vertices[i],
-+                                             &vertices[(i + 1) % nvertices]);
-+
-+      if (side)
-+        {
-+          if (!first_side)
-+            first_side = side;
-+          else if (side != first_side)
-+            return +1;  /* outside */
-+        }
-+      else
-+        {
-+          on_an_edge = TRUE;
-+        }
-+    }
-+
-+  if (first_side)
-+    {
-+      return on_an_edge ? 0 : -1;  /* on an edge or completely inside */
-+    }
-+  else
-+    {
-+      /* The point was neither inside nor outside any edges so we have an empty
-+       * polygon. Therefore if the vertices match the point we'll at least call
-+       * that touching. Otherwise the point is outside.
-+       */
-+      return point->x == vertices[0].x && point->y == vertices[0].y ? 0 : +1;
-+    }
-+}
-+
-+/**
-+ * clutter_point_inside_polygon:
-+ * @point: a #ClutterPoint to test
-+ * @vertices: array of vertices of the polygon
-+ * @nvertices: number of vertices in array @vertices
-+ *
-+ * Determines whether a point is inside the convex polygon provided, and not
-+ * on any of its edges or vertices.
-+ *
-+ * Return value: true if @point is inside the polygon
-+ */
-+gboolean
-+clutter_point_inside_polygon (const ClutterPoint *point,
-+                              const ClutterPoint *vertices,
-+                              unsigned int        nvertices)
-+{
-+  return clutter_point_compare_polygon (point, vertices, nvertices) < 0;
-+}
-+
-+/**
-+ * clutter_point_touches_polygon:
-+ * @point: a #ClutterPoint to test
-+ * @vertices: array of vertices of the polygon
-+ * @nvertices: number of vertices in array @vertices
-+ *
-+ * Determines whether a point is on the convex polygon provided, including
-+ * on any of its edges or vertices.
-+ *
-+ * Return value: true if @point is on the polygon
-+ */
-+gboolean
-+clutter_point_touches_polygon (const ClutterPoint *point,
-+                               const ClutterPoint *vertices,
-+                               unsigned int        nvertices)
-+{
-+  return clutter_point_compare_polygon (point, vertices, nvertices) <= 0;
-+}
-+
- 

- 
- /*
-diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h
-index 0f0fb1c2a..e3683184b 100644
---- a/clutter/clutter/clutter-types.h
-+++ b/clutter/clutter/clutter-types.h
-@@ -200,6 +200,14 @@ float                   clutter_point_distance  (const ClutterPoint *a,
-                                                  const ClutterPoint *b,
-                                                  float              *x_distance,
-                                                  float              *y_distance);
-+CLUTTER_EXPORT
-+gboolean clutter_point_inside_polygon           (const ClutterPoint *point,
-+                                                 const ClutterPoint *vertices,
-+                                                 unsigned int        nvertices);
-+CLUTTER_EXPORT
-+gboolean clutter_point_touches_polygon          (const ClutterPoint *point,
-+                                                 const ClutterPoint *vertices,
-+                                                 unsigned int        nvertices);
- 
- /**
-  * ClutterSize:
-diff --git a/clutter/tests/conform/meson.build b/clutter/tests/conform/meson.build
-index a9f2d7e20..916f5c342 100644
---- a/clutter/tests/conform/meson.build
-+++ b/clutter/tests/conform/meson.build
-@@ -36,6 +36,7 @@ clutter_conform_tests_general_tests = [
-   'interval',
-   'script-parser',
-   'units',
-+  'point',
- ]
- 
- clutter_conform_tests_deprecated_tests = [
-diff --git a/clutter/tests/conform/point.c b/clutter/tests/conform/point.c
-new file mode 100644
-index 000000000..a95a3e440
---- /dev/null
-+++ b/clutter/tests/conform/point.c
-@@ -0,0 +1,104 @@
-+#include <clutter/clutter.h>
-+
-+static void
-+point_on_nonempty_polygon (void)
-+{
-+  int p;
-+  static const ClutterPoint vertices[4] =
-+    {
-+      {1.f, 2.f},
-+      {6.f, 3.f},
-+      {7.f, 6.f},
-+      {0.f, 5.f}
-+    };
-+  static const ClutterPoint points_inside[] =
-+    {
-+      {2.f, 3.f},
-+      {1.f, 4.f},
-+      {5.f, 5.f},
-+      {4.f, 3.f},
-+    };
-+  static const ClutterPoint points_outside[] =
-+    {
-+      {3.f, 1.f},
-+      {7.f, 4.f},
-+      {4.f, 6.f},
-+      {99.f, -77.f},
-+      {-1.f, 3.f},
-+      {-8.f, -8.f},
-+      {11.f, 4.f},
-+      {-7.f, 4.f},
-+    };
-+  static const ClutterPoint points_touching[] =
-+    {
-+      {1.f, 2.f},
-+      {3.5f, 2.5f},
-+      {6.f, 3.f},
-+      {6.5f, 4.5f},
-+      {7.f, 6.f},
-+      {3.5f, 5.5f},
-+      {0.f, 5.f}
-+    };
-+
-+  for (p = 0; p < G_N_ELEMENTS (points_inside); p++)
-+    {
-+      const ClutterPoint *point = points_inside + p;
-+
-+      g_assert_true (clutter_point_inside_polygon (point, vertices, 4));
-+      g_assert_true (clutter_point_touches_polygon (point, vertices, 4));
-+    }
-+
-+  for (p = 0; p < G_N_ELEMENTS (points_outside); p++)
-+    {
-+      const ClutterPoint *point = points_outside + p;
-+
-+      g_assert_false (clutter_point_inside_polygon (point, vertices, 4));
-+      g_assert_false (clutter_point_touches_polygon (point, vertices, 4));
-+    }
-+
-+  for (p = 0; p < G_N_ELEMENTS (points_touching); p++)
-+    {
-+      const ClutterPoint *point = points_touching + p;
-+
-+      g_assert_false (clutter_point_inside_polygon (point, vertices, 4));
-+      g_assert_true (clutter_point_touches_polygon (point, vertices, 4));
-+    }
-+}
-+
-+static void
-+point_on_empty_polygon (void)
-+{
-+  int p;
-+  static const ClutterPoint vertices[4] =
-+    {
-+      {5.f, 6.f},
-+      {5.f, 6.f},
-+      {5.f, 6.f},
-+      {5.f, 6.f},
-+    };
-+  static const ClutterPoint points_outside[] =
-+    {
-+      {3.f, 1.f},
-+      {7.f, 4.f},
-+      {4.f, 6.f},
-+      {99.f, -77.f},
-+      {-1.f, 3.f},
-+      {-8.f, -8.f},
-+    };
-+
-+  for (p = 0; p < G_N_ELEMENTS (points_outside); p++)
-+    {
-+      const ClutterPoint *point = points_outside + p;
-+
-+      g_assert_false (clutter_point_inside_polygon (point, vertices, 4));
-+      g_assert_false (clutter_point_touches_polygon (point, vertices, 4));
-+    }
-+
-+  g_assert_false (clutter_point_inside_polygon (&vertices[0], vertices, 4));
-+  g_assert_true (clutter_point_touches_polygon (&vertices[0], vertices, 4));
-+}
-+
-+CLUTTER_TEST_SUITE (
-+  CLUTTER_TEST_UNIT ("/point/on_nonempty_polygon", point_on_nonempty_polygon)
-+  CLUTTER_TEST_UNIT ("/point/on_empty_polygon", point_on_empty_polygon)
-+)
--- 
-2.23.0
-

Deleted: 0001-Remove-GLX-threaded-swap-wait.patch
===================================================================
--- 0001-Remove-GLX-threaded-swap-wait.patch	2019-09-12 20:57:17 UTC (rev 362343)
+++ 0001-Remove-GLX-threaded-swap-wait.patch	2019-09-12 21:06:45 UTC (rev 362344)
@@ -1,467 +0,0 @@
-From 0ff4d5ed3423c3eeb7e7e597c571148fc98834cf Mon Sep 17 00:00:00 2001
-From: Daniel van Vugt <daniel.van.vugt at canonical.com>
-Date: Fri, 31 May 2019 14:59:22 +0800
-Subject: [PATCH] cogl: Remove GLX "threaded swap wait" used on Nvidia
-
-The single purpose of "threaded swap wait" was to provide the value:
-`u.presentation_time = get_monotonic_time_ns ();` for use by
-`clutter-stage-cogl`.
-
-Until recently (before !363), all backends were required to provide
-a nonzero value for `presentation_time` or else suffer falling back
-to poor-performing throttling methods in `master_clock_next_frame_delay`.
-So we needed "threaded swap wait" to support the Nvidia driver.
-
-This is no longer true. The fallbacks don't exist any more and
-`clutter_stage_cogl_schedule_update` now always succeeds even in the
-absence of a `presentation_time` (since !363).
-
-The drawbacks to keeping "threaded swap wait" are:
-
-  * `u.presentation_time = get_monotonic_time_ns ();` is a guess and not
-    an accurate hardware presentation time.
-  * It required blocking the main loop on every frame in
-    `_cogl_winsys_wait_for_gpu` due to `glFinish`. Any OpenGL programmer
-    will tell you calling `glFinish` is a bad idea because it kills CPU-GPU
-    parallelism. In my case, it was blocking the main loop for 1-3ms on
-    every mutter frame. It's easy to imagine slower (or higher resolution)
-    Nvidia systems would lose an even larger chunk of their frame interval
-    blocked in that function. This significantly crippled frame rates on
-    Nvidia systems.
-
-The benefit to keeping "threaded swap wait" is:
-
-  * Its guess of `presentation_time` is likely a better guess by a few
-    milliseconds than the guess that `clutter_stage_cogl_schedule_update`
-    will make in its place.
-
-So "threaded swap wait" provided better sub-frame phase accuracy, but at
-the expense of frame rates. And as soon as it starts causing frame drops,
-that one and only benefit is lost. There is no reason to keep it.
-
-And in case you are wondering, the documentation for "threaded swap wait"
-is now wrong (since !363):
-
-  > The advantage of enabling this is that it will allow your main loop
-  > to do other work while waiting for the system to be ready to draw
-  > the next frame, instead of blocking in glXSwapBuffers()."
-
-At the time (before !363) it was true that "threaded swap wait" avoided
-swap interval throttling that would occur as a result of
-`master_clock_next_frame_delay` blindly returning zero and over-queuing
-frames. That code no longer exists. And ironically the implementation of
-"threaded swap wait" necessitates the same kind of blocking (to a lesser
-extent) that it was designed to avoid. We can eliminate all blocking
-however by deleting "threaded swap wait", which is now safe since !363.
-
-https://gitlab.gnome.org/GNOME/mutter/merge_requests/602
----
- cogl/cogl/cogl-private.h             |   3 -
- cogl/cogl/cogl-renderer-private.h    |   1 -
- cogl/cogl/cogl-renderer.c            |  11 --
- cogl/cogl/cogl-xlib-renderer.h       |  30 ----
- cogl/cogl/winsys/cogl-winsys-glx.c   | 240 +--------------------------
- src/backends/x11/meta-backend-x11.c  |   6 -
- src/backends/x11/meta-renderer-x11.c |   8 -
- 7 files changed, 2 insertions(+), 297 deletions(-)
-
-diff --git a/cogl/cogl/cogl-private.h b/cogl/cogl/cogl-private.h
-index 9f918b851..db0f08df0 100644
---- a/cogl/cogl/cogl-private.h
-+++ b/cogl/cogl/cogl-private.h
-@@ -76,9 +76,6 @@ typedef enum
-   COGL_PRIVATE_FEATURE_GL_PROGRAMMABLE,
-   COGL_PRIVATE_FEATURE_GL_EMBEDDED,
-   COGL_PRIVATE_FEATURE_GL_WEB,
--  /* This is currently only implemented for GLX, but isn't actually
--   * that winsys dependent */
--  COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
- 
-   COGL_N_PRIVATE_FEATURES
- } CoglPrivateFeature;
-diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h
-index a308801a7..cc8f94bf1 100644
---- a/cogl/cogl/cogl-renderer-private.h
-+++ b/cogl/cogl/cogl-renderer-private.h
-@@ -71,7 +71,6 @@ struct _CoglRenderer
-   Display *foreign_xdpy;
-   gboolean xlib_enable_event_retrieval;
-   gboolean xlib_want_reset_on_video_memory_purge;
--  gboolean xlib_enable_threaded_swap_wait;
- #endif
- 
-   CoglDriver driver;
-diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c
-index 854aa1fdd..bdc9762e8 100644
---- a/cogl/cogl/cogl-renderer.c
-+++ b/cogl/cogl/cogl-renderer.c
-@@ -270,17 +270,6 @@ cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
- 
-   renderer->xlib_want_reset_on_video_memory_purge = enable;
- }
--
--void
--cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
--						   gboolean enable)
--{
--  _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
--  /* NB: Renderers are considered immutable once connected */
--  _COGL_RETURN_IF_FAIL (!renderer->connected);
--
--  renderer->xlib_enable_threaded_swap_wait = enable;
--}
- #endif /* COGL_HAS_XLIB_SUPPORT */
- 
- gboolean
-diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h
-index 3a3c08d64..e8fe43a51 100644
---- a/cogl/cogl/cogl-xlib-renderer.h
-+++ b/cogl/cogl/cogl-xlib-renderer.h
-@@ -167,36 +167,6 @@ void
- cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
-                                                 gboolean enable);
- 
--/**
-- * cogl_xlib_renderer_set_threaded_swap_wait_enabled: (skip)
-- * @renderer: a #CoglRenderer
-- * @enable: The new value
-- *
-- * Sets whether Cogl is allowed to use a separate threaded to wait for the
-- * completion of glXSwapBuffers() and call the frame callback for the
-- * corresponding #CoglOnscreen. This is a way of emulating the
-- * INTEL_swap_event extension, and will only ever be used if
-- * INTEL_swap_event is not present; it will also only be used for
-- * specific white-listed drivers that are known to work correctly with
-- * multiple contexts sharing state between threads.
-- *
-- * The advantage of enabling this is that it will allow your main loop
-- * to do other work while waiting for the system to be ready to draw
-- * the next frame, instead of blocking in glXSwapBuffers(). A disadvantage
-- * is that the driver will be prevented from buffering up multiple frames
-- * even if it thinks that it would be advantageous. In general, this
-- * will work best for something like a system compositor that is doing
-- * simple drawing but handling lots of other complex tasks.
-- * 
-- * If you enable this, you must call XInitThreads() before any other
-- * X11 calls in your program. (See the documentation for XInitThreads())
-- *
-- * Stability: unstable
-- */
--void
--cogl_xlib_renderer_set_threaded_swap_wait_enabled (CoglRenderer *renderer,
--						   gboolean enable);
--
- /**
-  * cogl_xlib_renderer_get_display: (skip)
-  */
-diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
-index 235cfe81f..89e60a539 100644
---- a/cogl/cogl/winsys/cogl-winsys-glx.c
-+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
-@@ -895,29 +895,6 @@ update_winsys_features (CoglContext *context, CoglError **error)
-                       COGL_FEATURE_ID_PRESENTATION_TIME,
-                       TRUE);
-     }
--  else
--    {
--      CoglGpuInfo *info = &context->gpu;
--      if (glx_display->have_vblank_counter &&
--	  context->display->renderer->xlib_enable_threaded_swap_wait &&
--	  info->vendor == COGL_GPU_INFO_VENDOR_NVIDIA)
--        {
--          COGL_FLAGS_SET (context->winsys_features,
--                          COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT, TRUE);
--          COGL_FLAGS_SET (context->winsys_features,
--                          COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT, TRUE);
--          /* TODO: remove this deprecated feature */
--          COGL_FLAGS_SET (context->features,
--                          COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
--                          TRUE);
--          COGL_FLAGS_SET (context->features,
--                          COGL_FEATURE_ID_PRESENTATION_TIME,
--                          TRUE);
--          COGL_FLAGS_SET (context->private_features,
--                          COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT,
--                          TRUE);
--        }
--    }
- 
-   /* We'll manually handle queueing dirty events in response to
-    * Expose events from X */
-@@ -1514,8 +1491,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
-     }
- 
- #ifdef GLX_INTEL_swap_event
--  if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT) &&
--      !_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
-+  if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT))
-     {
-       GLXDrawable drawable =
-         glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
-@@ -1810,199 +1786,6 @@ set_frame_info_output (CoglOnscreen *onscreen,
-     }
- }
- 
--static gpointer
--threaded_swap_wait (gpointer data)
--{
--  CoglOnscreen *onscreen = data;
--
--  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
--
--  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
--  CoglContext *context = framebuffer->context;
--  CoglDisplay *display = context->display;
--  CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (display->renderer);
--  CoglGLXDisplay *glx_display = display->winsys;
--  CoglGLXRenderer *glx_renderer = display->renderer->winsys;
--  GLXDrawable dummy_drawable;
--
--  if (glx_display->dummy_glxwin)
--    dummy_drawable = glx_display->dummy_glxwin;
--  else
--    dummy_drawable = glx_display->dummy_xwin;
--
--  glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
--                                       dummy_drawable,
--                                       dummy_drawable,
--                                       glx_onscreen->swap_wait_context);
--
--  g_mutex_lock (&glx_onscreen->swap_wait_mutex);
--
--  while (TRUE)
--    {
--      gpointer queue_element;
--      uint32_t vblank_counter;
--
--      while (!glx_onscreen->closing_down && glx_onscreen->swap_wait_queue->length == 0)
--         g_cond_wait (&glx_onscreen->swap_wait_cond, &glx_onscreen->swap_wait_mutex);
--
--      if (glx_onscreen->closing_down)
--         break;
--
--      queue_element = g_queue_pop_tail (glx_onscreen->swap_wait_queue);
--      vblank_counter = GPOINTER_TO_UINT(queue_element);
--
--      g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
--      glx_renderer->glXWaitVideoSync (2,
--                                      (vblank_counter + 1) % 2,
--                                      &vblank_counter);
--      g_mutex_lock (&glx_onscreen->swap_wait_mutex);
--
--      if (!glx_onscreen->closing_down)
--         {
--           int bytes_written = 0;
--
--           union {
--             char bytes[8];
--             int64_t presentation_time;
--           } u;
--
--           u.presentation_time = get_monotonic_time_ns ();
--
--           while (bytes_written < 8)
--             {
--               int res = write (glx_onscreen->swap_wait_pipe[1], u.bytes + bytes_written, 8 - bytes_written);
--               if (res == -1)
--                 {
--                   if (errno != EINTR)
--                     g_error ("Error writing to swap notification pipe: %s\n",
--                              g_strerror (errno));
--                 }
--               else
--                 {
--                   bytes_written += res;
--                 }
--             }
--         }
--    }
--
--  g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
--
--  glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
--                                       None,
--                                       None,
--                                       NULL);
--
--  return NULL;
--}
--
--static int64_t
--threaded_swap_wait_pipe_prepare (void *user_data)
--{
--  return -1;
--}
--
--static void
--threaded_swap_wait_pipe_dispatch (void *user_data, int revents)
--{
--  CoglOnscreen *onscreen = user_data;
--  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
--
--  CoglFrameInfo *info;
--
--  if ((revents & COGL_POLL_FD_EVENT_IN))
--    {
--      int bytes_read = 0;
--
--      union {
--         char bytes[8];
--         int64_t presentation_time;
--      } u;
--
--      while (bytes_read < 8)
--         {
--           int res = read (glx_onscreen->swap_wait_pipe[0], u.bytes + bytes_read, 8 - bytes_read);
--           if (res == -1)
--             {
--               if (errno != EINTR)
--                 g_error ("Error reading from swap notification pipe: %s\n",
--                          g_strerror (errno));
--             }
--           else
--             {
--               bytes_read += res;
--             }
--         }
--
--      set_sync_pending (onscreen);
--      set_complete_pending (onscreen);
--
--      info = g_queue_peek_head (&onscreen->pending_frame_infos);
--      info->presentation_time = u.presentation_time;
--    }
--}
--
--static void
--start_threaded_swap_wait (CoglOnscreen *onscreen,
--                           uint32_t      vblank_counter)
--{
--  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
--  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
--  CoglContext *context = framebuffer->context;
--
--  if (glx_onscreen->swap_wait_thread == NULL)
--    {
--      CoglDisplay *display = context->display;
--      CoglGLXRenderer *glx_renderer = display->renderer->winsys;
--      CoglGLXDisplay *glx_display = display->winsys;
--      CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
--      CoglXlibRenderer *xlib_renderer =
--        _cogl_xlib_renderer_get_data (display->renderer);
--
--      GLXDrawable drawable =
--        glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
--      int i;
--
--      ensure_ust_type (display->renderer, drawable);
--      
--      if ((pipe (glx_onscreen->swap_wait_pipe) == -1))
--        g_error ("Couldn't create pipe for swap notification: %s\n",
--                 g_strerror (errno));
--
--      for (i = 0; i < 2; i++)
--	{
--	  if (fcntl(glx_onscreen->swap_wait_pipe[i], F_SETFD,
--		    fcntl(glx_onscreen->swap_wait_pipe[i], F_GETFD, 0) | FD_CLOEXEC) == -1)
--	    g_error ("Couldn't set swap notification pipe CLOEXEC: %s\n",
--		     g_strerror (errno));
--	}
--
--      _cogl_poll_renderer_add_fd (display->renderer,
--                                  glx_onscreen->swap_wait_pipe[0],
--                                  COGL_POLL_FD_EVENT_IN,
--                                  threaded_swap_wait_pipe_prepare,
--                                  threaded_swap_wait_pipe_dispatch,
--                                  onscreen);
--
--      glx_onscreen->swap_wait_queue = g_queue_new ();
--      g_mutex_init (&glx_onscreen->swap_wait_mutex);
--      g_cond_init (&glx_onscreen->swap_wait_cond);
--      glx_onscreen->swap_wait_context =
--         glx_renderer->glXCreateNewContext (xlib_renderer->xdpy,
--                                            glx_display->fbconfig,
--                                            GLX_RGBA_TYPE,
--                                            glx_display->glx_context,
--                                            True);
--      glx_onscreen->swap_wait_thread = g_thread_new ("cogl_glx_swap_wait",
--                                                     threaded_swap_wait,
--                                                     onscreen);
--    }
--
--  g_mutex_lock (&glx_onscreen->swap_wait_mutex);
--  g_queue_push_head (glx_onscreen->swap_wait_queue, GUINT_TO_POINTER(vblank_counter));
--  g_cond_signal (&glx_onscreen->swap_wait_cond);
--  g_mutex_unlock (&glx_onscreen->swap_wait_mutex);
--}
--
- static void
- _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
-                                    const int *user_rectangles,
-@@ -2238,26 +2021,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
- 
-   have_counter = glx_display->have_vblank_counter;
- 
--  if (glx_renderer->glXSwapInterval)
--    {
--      if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_THREADED_SWAP_WAIT))
--        {
--          /* If we didn't wait for the GPU here, then it's easy to get the case
--           * where there is a VBlank between the point where we get the vsync counter
--           * and the point where the GPU is ready to actually perform the glXSwapBuffers(),
--           * and the swap wait terminates at the first VBlank rather than the one
--           * where the swap buffers happens. Calling glFinish() here makes this a
--           * rare race since the GPU is already ready to swap when we call glXSwapBuffers().
--           * The glFinish() also prevents any serious damage if the rare race happens,
--           * since it will wait for the preceding glXSwapBuffers() and prevent us from
--           * getting premanently ahead. (For NVIDIA drivers, glFinish() after glXSwapBuffers()
--           * waits for the buffer swap to happen.)
--           */
--          _cogl_winsys_wait_for_gpu (onscreen);
--          start_threaded_swap_wait (onscreen, _cogl_winsys_get_vsync_counter (context));
--        }
--    }
--  else
-+  if (!glx_renderer->glXSwapInterval)
-     {
-       gboolean can_wait = have_counter || glx_display->can_vblank_wait;
- 
-diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
-index c10365f9d..7bade4844 100644
---- a/src/backends/x11/meta-backend-x11.c
-+++ b/src/backends/x11/meta-backend-x11.c
-@@ -786,12 +786,6 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
- static void
- meta_backend_x11_init (MetaBackendX11 *x11)
- {
--  /* XInitThreads() is needed to use the "threaded swap wait" functionality
--   * in Cogl - see meta_renderer_x11_create_cogl_renderer(). We call it here
--   * to hopefully call it before any other use of XLib.
--   */
--  XInitThreads();
--
-   /* We do X11 event retrieval ourselves */
-   clutter_x11_disable_event_retrieval ();
- }
-diff --git a/src/backends/x11/meta-renderer-x11.c b/src/backends/x11/meta-renderer-x11.c
-index a501416e7..96beb4eb8 100644
---- a/src/backends/x11/meta-renderer-x11.c
-+++ b/src/backends/x11/meta-renderer-x11.c
-@@ -85,14 +85,6 @@ meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer)
-   cogl_xlib_renderer_set_foreign_display (cogl_renderer, xdisplay);
-   cogl_xlib_renderer_request_reset_on_video_memory_purge (cogl_renderer, TRUE);
- 
--  /* Set up things so that if the INTEL_swap_event extension is not present,
--   * but the driver is known to have good thread support, we use an extra
--   * thread and call glXWaitVideoSync() in the thread. This allows idles
--   * to work properly, even when Mutter is constantly redrawing new frames;
--   * otherwise, without INTEL_swap_event, we'll just block in glXSwapBuffers().
--   */
--  cogl_xlib_renderer_set_threaded_swap_wait_enabled (cogl_renderer, TRUE);
--
-   return cogl_renderer;
- }
- 
--- 
-2.22.0
-

Deleted: 0002-Geometric-OpenGL-less-picking.patch
===================================================================
--- 0002-Geometric-OpenGL-less-picking.patch	2019-09-12 20:57:17 UTC (rev 362343)
+++ 0002-Geometric-OpenGL-less-picking.patch	2019-09-12 21:06:45 UTC (rev 362344)
@@ -1,1714 +0,0 @@
-From 6a18d760ed05b87af7aae43f1963eb32bc1d81e7 Mon Sep 17 00:00:00 2001
-From: Daniel van Vugt <daniel.van.vugt at canonical.com>
-Date: Thu, 2 Aug 2018 19:03:30 +0800
-Subject: [PATCH 2/2] Geometric (OpenGL-less) picking
-
-Cherry picked from commit b9170a69314739638db7f471b87ba55a906bdf03.
-
-Redesign picking to avoid using OpenGL. Previously picking involved
-several GL operations per mouse movement, but now the GPU/GL isn't
-used at all.
-
-By avoiding OpenGL and the graphics driver we also reduce CPU usage.
-Despite reimplementing the logic on the CPU, it still takes less CPU
-time than going through GL did.
-
-This new approach also dramatically reduces the number of picking paint
-cycles required for cursor movement since the pickability of the entire
-screen is calculated and cached. The cache is only invalidated when the
-screen contents change so for typical desktop usage where the screen is
-mostly idle, cursor movement doesn't incur anywhere near as many paint
-cycles as it used to.
-
-CPU usage on an Intel i7-7700, tested with two different GPUs/drivers:
-
-  |         |     Intel | Nvidia |
-  | ------: | --------: | -----: |
-  | Moving the mouse:            |
-  | Before  |       10% |    10% |
-  | After   |        6% |     6% |
-  | Moving a window:             |
-  | Before  |       23% |    81% |
-  | After   |       19% |    40% |
-
-Closes: https://gitlab.gnome.org/GNOME/mutter/issues/154,
-        https://gitlab.gnome.org/GNOME/mutter/issues/691
-
-Helps significantly with: https://gitlab.gnome.org/GNOME/mutter/issues/283,
-                          https://gitlab.gnome.org/GNOME/mutter/issues/590,
-                          https://gitlab.gnome.org/GNOME/mutter/issues/700
-
-https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
----
- clutter/clutter/clutter-actor-private.h      |   2 -
- clutter/clutter/clutter-actor.c              | 254 +++++++----
- clutter/clutter/clutter-actor.h              |   4 +
- clutter/clutter/clutter-debug.h              |   3 +-
- clutter/clutter/clutter-main.c               | 120 -----
- clutter/clutter/clutter-private.h            |   5 -
- clutter/clutter/clutter-stage-private.h      |  16 +-
- clutter/clutter/clutter-stage-window.c       |  18 -
- clutter/clutter/clutter-stage-window.h       |   8 -
- clutter/clutter/clutter-stage.c              | 433 +++++++++++--------
- clutter/clutter/cogl/clutter-stage-cogl.c    |  50 ---
- clutter/clutter/deprecated/clutter-texture.c |  93 +---
- clutter/tests/conform/actor-pick.c           |  99 +----
- clutter/tests/conform/meson.build            |   1 -
- clutter/tests/conform/texture.c              |  84 ----
- src/compositor/meta-surface-actor.c          |  27 +-
- 16 files changed, 434 insertions(+), 783 deletions(-)
- delete mode 100644 clutter/tests/conform/texture.c
-
-diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h
-index c44f6342f..9bf1a3049 100644
---- a/clutter/clutter/clutter-actor-private.h
-+++ b/clutter/clutter/clutter-actor-private.h
-@@ -297,8 +297,6 @@ const gchar *                   _clutter_actor_get_debug_name
- void                            _clutter_actor_push_clone_paint                         (void);
- void                            _clutter_actor_pop_clone_paint                          (void);
- 
--guint32                         _clutter_actor_get_pick_id                              (ClutterActor *self);
--
- void                            _clutter_actor_shader_pre_paint                         (ClutterActor *actor,
-                                                                                          gboolean      repeat);
- void                            _clutter_actor_shader_post_paint                        (ClutterActor *actor);
-diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
-index a7fecb830..5feae6574 100644
---- a/clutter/clutter/clutter-actor.c
-+++ b/clutter/clutter/clutter-actor.c
-@@ -729,8 +729,6 @@ struct _ClutterActorPrivate
- 
-   gchar *name; /* a non-unique name, used for debugging */
- 
--  gint32 pick_id; /* per-stage unique id, used for picking */
--
-   /* a back-pointer to the Pango context that we can use
-    * to create pre-configured PangoLayout
-    */
-@@ -1282,6 +1280,129 @@ clutter_actor_verify_map_state (ClutterActor *self)
- 
- #endif /* CLUTTER_ENABLE_DEBUG */
- 
-+static gboolean
-+_clutter_actor_transform_local_box_to_stage (ClutterActor          *self,
-+                                             const ClutterActorBox *box,
-+                                             ClutterPoint           vertices[4])
-+{
-+  ClutterActor *stage = _clutter_actor_get_stage_internal (self);
-+  CoglMatrix stage_transform, inv_stage_transform;
-+  CoglMatrix modelview, transform_to_stage;
-+  int v;
-+
-+  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
-+  g_return_val_if_fail (box != NULL, FALSE);
-+
-+  g_return_val_if_fail (stage != NULL, FALSE);
-+  g_return_val_if_fail (box->x1 <= box->x2, FALSE);
-+  g_return_val_if_fail (box->y1 <= box->y2, FALSE);
-+
-+  /* Below is generally equivalent to:
-+   *
-+   * _clutter_actor_get_relative_transformation_matrix (self,
-+   *                                                    stage,
-+   *                                                    &transform_to_stage);
-+   *
-+   * but we do it the hard way here instead so as to accurately include any
-+   * cogl transformations that an actor's paint function might have added in.
-+   * Those additional transformations are only known to cogl matrices and not
-+   * known to the clutter getter like above. So this way we more accurately
-+   * represent what's really getting painted.
-+   */
-+  clutter_actor_get_transform (stage, &stage_transform);
-+  if (!cogl_matrix_get_inverse (&stage_transform, &inv_stage_transform))
-+    return FALSE;
-+  cogl_get_modelview_matrix (&modelview);
-+  cogl_matrix_multiply (&transform_to_stage, &inv_stage_transform, &modelview);
-+
-+  vertices[0].x = box->x1;
-+  vertices[0].y = box->y1;
-+
-+  vertices[1].x = box->x2;
-+  vertices[1].y = box->y1;
-+
-+  vertices[2].x = box->x2;
-+  vertices[2].y = box->y2;
-+
-+  vertices[3].x = box->x1;
-+  vertices[3].y = box->y2;
-+
-+  for (v = 0; v < 4; v++)
-+    {
-+      gfloat z = 0.f;
-+      gfloat w = 1.f;
-+
-+      cogl_matrix_transform_point (&transform_to_stage,
-+                                   &vertices[v].x,
-+                                   &vertices[v].y,
-+                                   &z,
-+                                   &w);
-+    }
-+
-+  return TRUE;
-+}
-+
-+/**
-+ * clutter_actor_pick_box:
-+ * @self: The #ClutterActor being "pick" painted.
-+ * @box: A rectangle in the actor's own local coordinates.
-+ *
-+ * Logs (does a virtual paint of) a rectangle for picking. Note that @box is
-+ * in the actor's own local coordinates, so is usually {0,0,width,height}
-+ * to include the whole actor. That is unless the actor has a shaped input
-+ * region in which case you may wish to log the (multiple) smaller rectangles
-+ * that make up the input region.
-+ */
-+void
-+clutter_actor_pick_box (ClutterActor          *self,
-+                        const ClutterActorBox *box)
-+{
-+  ClutterActor *stage;
-+  ClutterPoint vertices[4];
-+
-+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
-+  g_return_if_fail (box != NULL);
-+
-+  /* An empty box to a "pick" paint means to paint nothing at all. */
-+  if (box->x1 >= box->x2 || box->y1 >= box->y2)
-+    return;
-+
-+  stage = _clutter_actor_get_stage_internal (self);
-+
-+  if (_clutter_actor_transform_local_box_to_stage (self, box, vertices))
-+    _clutter_stage_log_pick (CLUTTER_STAGE (stage), vertices, self);
-+}
-+
-+static gboolean
-+_clutter_actor_push_pick_clip (ClutterActor          *self,
-+                               const ClutterActorBox *clip)
-+{
-+  ClutterActor *stage;
-+  ClutterPoint vertices[4];
-+
-+  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
-+  g_return_val_if_fail (clip != NULL, FALSE);
-+
-+  stage = _clutter_actor_get_stage_internal (self);
-+
-+  if (!_clutter_actor_transform_local_box_to_stage (self, clip, vertices))
-+    return FALSE;
-+
-+  _clutter_stage_push_pick_clip (CLUTTER_STAGE (stage), vertices);
-+  return TRUE;
-+}
-+
-+static void
-+_clutter_actor_pop_pick_clip (ClutterActor *self)
-+{
-+  ClutterActor *stage;
-+
-+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
-+
-+  stage = _clutter_actor_get_stage_internal (self);
-+  _clutter_stage_pop_pick_clip (CLUTTER_STAGE (stage));
-+}
-+
- static void
- clutter_actor_set_mapped (ClutterActor *self,
-                           gboolean      mapped)
-@@ -1510,8 +1631,7 @@ clutter_actor_update_map_state (ClutterActor  *self,
- static void
- clutter_actor_real_map (ClutterActor *self)
- {
--  ClutterActorPrivate *priv = self->priv;
--  ClutterActor *stage, *iter;
-+  ClutterActor *iter;
- 
-   g_assert (!CLUTTER_ACTOR_IS_MAPPED (self));
- 
-@@ -1522,13 +1642,6 @@ clutter_actor_real_map (ClutterActor *self)
- 
-   self->priv->needs_paint_volume_update = TRUE;
- 
--  stage = _clutter_actor_get_stage_internal (self);
--  priv->pick_id = _clutter_stage_acquire_pick_id (CLUTTER_STAGE (stage), self);
--
--  CLUTTER_NOTE (ACTOR, "Pick id '%d' for actor '%s'",
--                priv->pick_id,
--                _clutter_actor_get_debug_name (self));
--
-   clutter_actor_ensure_resource_scale (self);
- 
-   /* notify on parent mapped before potentially mapping
-@@ -1633,11 +1746,6 @@ clutter_actor_real_unmap (ClutterActor *self)
- 
-       stage = CLUTTER_STAGE (_clutter_actor_get_stage_internal (self));
- 
--      if (stage != NULL)
--        _clutter_stage_release_pick_id (stage, priv->pick_id);
--
--      priv->pick_id = -1;
--
-       if (stage != NULL &&
-           clutter_stage_get_key_focus (stage) == self)
-         {
-@@ -2256,46 +2364,14 @@ static void
- clutter_actor_real_pick (ClutterActor       *self,
- 			 const ClutterColor *color)
- {
--  CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
--
--  /* the default implementation is just to paint a rectangle
--   * with the same size of the actor using the passed color
--   */
-   if (clutter_actor_should_pick_paint (self))
-     {
--      static CoglPipeline *default_pick_pipeline = NULL;
--      ClutterActorBox box = { 0, };
--      CoglPipeline *pick_pipeline;
--      float width, height;
--
--      if (G_UNLIKELY (default_pick_pipeline == NULL))
--        {
--          CoglContext *ctx =
--            clutter_backend_get_cogl_context (clutter_get_default_backend ());
--
--          default_pick_pipeline = cogl_pipeline_new (ctx);
--        }
--
--      g_assert (default_pick_pipeline != NULL);
--      pick_pipeline = cogl_pipeline_copy (default_pick_pipeline);
--
--      clutter_actor_get_allocation_box (self, &box);
--
--      width = box.x2 - box.x1;
--      height = box.y2 - box.y1;
--
--      cogl_pipeline_set_color4ub (pick_pipeline,
--                                  color->red,
--                                  color->green,
--                                  color->blue,
--                                  color->alpha);
-+      ClutterActorBox box = {0,
-+                             0,
-+                             clutter_actor_get_width (self),
-+                             clutter_actor_get_height (self)};
- 
--      cogl_framebuffer_draw_rectangle (framebuffer,
--                                       pick_pipeline,
--                                       0, 0,
--                                       width, height);
--
--      cogl_object_unref (pick_pipeline);
-+      clutter_actor_pick_box (self, &box);
-     }
- 
-   /* XXX - this thoroughly sucks, but we need to maintain compatibility
-@@ -3586,15 +3662,6 @@ _clutter_actor_update_last_paint_volume (ClutterActor *self)
-   priv->last_paint_volume_valid = TRUE;
- }
- 
--guint32
--_clutter_actor_get_pick_id (ClutterActor *self)
--{
--  if (self->priv->pick_id < 0)
--    return 0;
--
--  return self->priv->pick_id;
--}
--
- /* This is the same as clutter_actor_add_effect except that it doesn't
-    queue a redraw and it doesn't notify on the effect property */
- static void
-@@ -3826,6 +3893,7 @@ clutter_actor_paint (ClutterActor *self)
- {
-   ClutterActorPrivate *priv;
-   ClutterPickMode pick_mode;
-+  ClutterActorBox clip;
-   gboolean clip_set = FALSE;
-   ClutterStage *stage;
- 
-@@ -3919,24 +3987,38 @@ clutter_actor_paint (ClutterActor *self)
- 
-   if (priv->has_clip)
-     {
--      CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
--      cogl_framebuffer_push_rectangle_clip (fb,
--                                            priv->clip.origin.x,
--                                            priv->clip.origin.y,
--                                            priv->clip.origin.x + priv->clip.size.width,
--                                            priv->clip.origin.y + priv->clip.size.height);
-+      clip.x1 = priv->clip.origin.x;
-+      clip.y1 = priv->clip.origin.y;
-+      clip.x2 = priv->clip.origin.x + priv->clip.size.width;
-+      clip.y2 = priv->clip.origin.y + priv->clip.size.height;
-       clip_set = TRUE;
-     }
-   else if (priv->clip_to_allocation)
-     {
--      CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
--      gfloat width, height;
-+      clip.x1 = 0.f;
-+      clip.y1 = 0.f;
-+      clip.x2 = priv->allocation.x2 - priv->allocation.x1;
-+      clip.y2 = priv->allocation.y2 - priv->allocation.y1;
-+      clip_set = TRUE;
-+    }
- 
--      width  = priv->allocation.x2 - priv->allocation.x1;
--      height = priv->allocation.y2 - priv->allocation.y1;
-+  if (clip_set)
-+    {
-+      if (pick_mode == CLUTTER_PICK_NONE)
-+        {
-+          CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
- 
--      cogl_framebuffer_push_rectangle_clip (fb, 0, 0, width, height);
--      clip_set = TRUE;
-+          cogl_framebuffer_push_rectangle_clip (fb,
-+                                                clip.x1,
-+                                                clip.y1,
-+                                                clip.x2,
-+                                                clip.y2);
-+        }
-+      else
-+        {
-+          if (!_clutter_actor_push_pick_clip (self, &clip))
-+            clip_set = FALSE;
-+        }
-     }
- 
-   if (pick_mode == CLUTTER_PICK_NONE)
-@@ -4017,9 +4099,16 @@ clutter_actor_paint (ClutterActor *self)
- done:
-   if (clip_set)
-     {
--      CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
-+      if (pick_mode == CLUTTER_PICK_NONE)
-+        {
-+          CoglFramebuffer *fb = _clutter_stage_get_active_framebuffer (stage);
- 
--      cogl_framebuffer_pop_clip (fb);
-+          cogl_framebuffer_pop_clip (fb);
-+        }
-+      else
-+        {
-+          _clutter_actor_pop_pick_clip (self);
-+        }
-     }
- 
-   cogl_pop_matrix ();
-@@ -4090,11 +4179,12 @@ clutter_actor_continue_paint (ClutterActor *self)
-         {
-           ClutterColor col = { 0, };
- 
--          _clutter_id_to_color (_clutter_actor_get_pick_id (self), &col);
--
--          /* Actor will then paint silhouette of itself in supplied
--           * color.  See clutter_stage_get_actor_at_pos() for where
--           * picking is enabled.
-+          /* The actor will log a silhouette of itself to the stage pick log.
-+           * Note that the picking color is no longer used as the "log" instead
-+           * keeps a weak pointer to the actor itself. But we keep the color
-+           * parameter for now so as to maintain ABI compatibility. The color
-+           * parameter can be removed when someone feels like breaking the ABI
-+           * along with gnome-shell.
-            *
-            * XXX:2.0 - Call the pick() virtual directly
-            */
-@@ -8602,8 +8692,6 @@ clutter_actor_init (ClutterActor *self)
- 
-   self->priv = priv = clutter_actor_get_instance_private (self);
- 
--  priv->pick_id = -1;
--
-   priv->opacity = 0xff;
-   priv->show_on_set_parent = TRUE;
-   priv->resource_scale = -1.0f;
-diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h
-index 7d2168af1..b1abff86d 100644
---- a/clutter/clutter/clutter-actor.h
-+++ b/clutter/clutter/clutter-actor.h
-@@ -902,6 +902,10 @@ void                            clutter_actor_bind_model_with_properties
-                                                                                  const char                 *first_model_property,
-                                                                                  ...);
- 
-+CLUTTER_EXPORT
-+void clutter_actor_pick_box (ClutterActor          *self,
-+                             const ClutterActorBox *box);
-+
- G_END_DECLS
- 
- #endif /* __CLUTTER_ACTOR_H__ */
-diff --git a/clutter/clutter/clutter-debug.h b/clutter/clutter/clutter-debug.h
-index 2462385f6..3744c648f 100644
---- a/clutter/clutter/clutter-debug.h
-+++ b/clutter/clutter/clutter-debug.h
-@@ -29,8 +29,7 @@ typedef enum
- 
- typedef enum
- {
--  CLUTTER_DEBUG_NOP_PICKING         = 1 << 0,
--  CLUTTER_DEBUG_DUMP_PICK_BUFFERS   = 1 << 1
-+  CLUTTER_DEBUG_NOP_PICKING         = 1 << 0
- } ClutterPickDebugFlag;
- 
- typedef enum
-diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c
-index 71ec0d80c..c2ec82697 100644
---- a/clutter/clutter/clutter-main.c
-+++ b/clutter/clutter/clutter-main.c
-@@ -130,7 +130,6 @@ static const GDebugKey clutter_debug_keys[] = {
- 
- static const GDebugKey clutter_pick_debug_keys[] = {
-   { "nop-picking", CLUTTER_DEBUG_NOP_PICKING },
--  { "dump-pick-buffers", CLUTTER_DEBUG_DUMP_PICK_BUFFERS },
- };
- 
- static const GDebugKey clutter_paint_debug_keys[] = {
-@@ -532,125 +531,6 @@ clutter_get_motion_events_enabled (void)
-   return _clutter_context_get_motion_events_enabled ();
- }
- 
--void
--_clutter_id_to_color (guint         id_,
--                      ClutterColor *col)
--{
--  ClutterMainContext *ctx;
--  gint red, green, blue;
--
--  ctx = _clutter_context_get_default ();
--
--  if (ctx->fb_g_mask == 0)
--    {
--      /* Figure out framebuffer masks used for pick */
--      cogl_get_bitmasks (&ctx->fb_r_mask,
--			 &ctx->fb_g_mask,
--			 &ctx->fb_b_mask, NULL);
--
--      ctx->fb_r_mask_used = ctx->fb_r_mask;
--      ctx->fb_g_mask_used = ctx->fb_g_mask;
--      ctx->fb_b_mask_used = ctx->fb_b_mask;
--
--      /* XXX - describe what "fuzzy picking" is */
--      if (clutter_use_fuzzy_picking)
--	{
--	  ctx->fb_r_mask_used--;
--	  ctx->fb_g_mask_used--;
--	  ctx->fb_b_mask_used--;
--	}
--    }
--
--  /* compute the numbers we'll store in the components */
--  red   = (id_ >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used))
--        & (0xff >> (8-ctx->fb_r_mask_used));
--  green = (id_ >> ctx->fb_b_mask_used)
--        & (0xff >> (8-ctx->fb_g_mask_used));
--  blue  = (id_)
--        & (0xff >> (8-ctx->fb_b_mask_used));
--
--  /* shift left bits a bit and add one, this circumvents
--   * at least some potential rounding errors in GL/GLES
--   * driver / hw implementation.
--   */
--  if (ctx->fb_r_mask_used != ctx->fb_r_mask)
--    red = red * 2;
--  if (ctx->fb_g_mask_used != ctx->fb_g_mask)
--    green = green * 2;
--  if (ctx->fb_b_mask_used != ctx->fb_b_mask)
--    blue  = blue  * 2;
--
--  /* shift up to be full 8bit values */
--  red   = (red   << (8 - ctx->fb_r_mask)) | (0x7f >> (ctx->fb_r_mask_used));
--  green = (green << (8 - ctx->fb_g_mask)) | (0x7f >> (ctx->fb_g_mask_used));
--  blue  = (blue  << (8 - ctx->fb_b_mask)) | (0x7f >> (ctx->fb_b_mask_used));
--
--  col->red   = red;
--  col->green = green;
--  col->blue  = blue;
--  col->alpha = 0xff;
--
--  /* XXX: We rotate the nibbles of the colors here so that there is a
--   * visible variation between colors of sequential actor identifiers;
--   * otherwise pick buffers dumped to an image will pretty much just look
--   * black.
--   */
--  if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
--    {
--      col->red   = (col->red << 4)   | (col->red >> 4);
--      col->green = (col->green << 4) | (col->green >> 4);
--      col->blue  = (col->blue << 4)  | (col->blue >> 4);
--    }
--}
--
--guint
--_clutter_pixel_to_id (guchar pixel[4])
--{
--  ClutterMainContext *ctx;
--  gint red, green, blue;
--  guint retval;
--
--  ctx = _clutter_context_get_default ();
--
--  /* reduce the pixel components to the number of bits actually used of the
--   * 8bits.
--   */
--  if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
--    {
--      guchar tmp;
--
--      /* XXX: In _clutter_id_to_color we rotated the nibbles of the colors so
--       * that there is a visible variation between colors of sequential actor
--       * identifiers (otherwise pick buffers dumped to an image will pretty
--       * much just look black.) Here we reverse that rotation.
--       */
--      tmp = ((pixel[0] << 4) | (pixel[0] >> 4));
--      red = tmp >> (8 - ctx->fb_r_mask);
--      tmp = ((pixel[1] << 4) | (pixel[1] >> 4));
--      green = tmp >> (8 - ctx->fb_g_mask);
--      tmp = ((pixel[2] << 4) | (pixel[2] >> 4));
--      blue = tmp >> (8 - ctx->fb_b_mask);
--    }
--  else
--    {
--      red   = pixel[0] >> (8 - ctx->fb_r_mask);
--      green = pixel[1] >> (8 - ctx->fb_g_mask);
--      blue  = pixel[2] >> (8 - ctx->fb_b_mask);
--    }
--
--  /* divide potentially by two if 'fuzzy' */
--  red   = red   >> (ctx->fb_r_mask - ctx->fb_r_mask_used);
--  green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used);
--  blue  = blue  >> (ctx->fb_b_mask - ctx->fb_b_mask_used);
--
--  /* combine the correct per component values into the final id */
--  retval = blue
--         + (green <<  ctx->fb_b_mask_used)
--         + (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used));
--
--  return retval;
--}
--
- static CoglPangoFontMap *
- clutter_context_get_pango_fontmap (void)
- {
-diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
-index a5cd1fa19..47bef4ac2 100644
---- a/clutter/clutter/clutter-private.h
-+++ b/clutter/clutter/clutter-private.h
-@@ -210,11 +210,6 @@ gboolean      _clutter_feature_init (GError **error);
- gboolean        _clutter_diagnostic_enabled     (void);
- void            _clutter_diagnostic_message     (const char *fmt, ...) G_GNUC_PRINTF (1, 2);
- 
--/* Picking code */
--guint           _clutter_pixel_to_id            (guchar        pixel[4]);
--void            _clutter_id_to_color            (guint         id,
--                                                 ClutterColor *col);
--
- void            _clutter_set_sync_to_vblank     (gboolean      sync_to_vblank);
- 
- /* use this function as the accumulator if you have a signal with
-diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
-index 4799c29e1..f8591ddcb 100644
---- a/clutter/clutter/clutter-stage-private.h
-+++ b/clutter/clutter/clutter-stage-private.h
-@@ -74,6 +74,15 @@ gint64    _clutter_stage_get_update_time                  (ClutterStage *stage);
- void     _clutter_stage_clear_update_time                 (ClutterStage *stage);
- gboolean _clutter_stage_has_full_redraw_queued            (ClutterStage *stage);
- 
-+void _clutter_stage_log_pick (ClutterStage       *stage,
-+                              const ClutterPoint  vertices[4],
-+                              ClutterActor       *actor);
-+
-+void _clutter_stage_push_pick_clip (ClutterStage       *stage,
-+                                    const ClutterPoint  vertices[4]);
-+
-+void _clutter_stage_pop_pick_clip (ClutterStage *stage);
-+
- ClutterActor *_clutter_stage_do_pick (ClutterStage    *stage,
-                                       gint             x,
-                                       gint             y,
-@@ -92,13 +101,6 @@ void                          _clutter_stage_queue_redraw_entry_invalidate (Clut
- 
- CoglFramebuffer *_clutter_stage_get_active_framebuffer (ClutterStage *stage);
- 
--gint32          _clutter_stage_acquire_pick_id          (ClutterStage *stage,
--                                                         ClutterActor *actor);
--void            _clutter_stage_release_pick_id          (ClutterStage *stage,
--                                                         gint32        pick_id);
--ClutterActor *  _clutter_stage_get_actor_by_pick_id     (ClutterStage *stage,
--                                                         gint32        pick_id);
--
- void            _clutter_stage_add_pointer_drag_actor    (ClutterStage       *stage,
-                                                           ClutterInputDevice *device,
-                                                           ClutterActor       *actor);
-diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
-index e8fa976a7..4c4ef9d64 100644
---- a/clutter/clutter/clutter-stage-window.c
-+++ b/clutter/clutter/clutter-stage-window.c
-@@ -293,24 +293,6 @@ _clutter_stage_window_redraw (ClutterStageWindow *window)
-     iface->redraw (window);
- }
- 
--
--void
--_clutter_stage_window_get_dirty_pixel (ClutterStageWindow *window,
--                                       ClutterStageView   *view,
--                                       int *x, int *y)
--{
--  ClutterStageWindowInterface *iface;
--
--  *x = 0;
--  *y = 0;
--
--  g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
--
--  iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
--  if (iface->get_dirty_pixel)
--    iface->get_dirty_pixel (window, view, x, y);
--}
--
- gboolean
- _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
- {
-diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
-index 6c3601745..aa0c5f71c 100644
---- a/clutter/clutter/clutter-stage-window.h
-+++ b/clutter/clutter/clutter-stage-window.h
-@@ -68,10 +68,6 @@ struct _ClutterStageWindowInterface
- 
-   void              (* redraw)                  (ClutterStageWindow *stage_window);
- 
--  void              (* get_dirty_pixel)         (ClutterStageWindow *stage_window,
--                                                 ClutterStageView   *view,
--                                                 int *x, int *y);
--
-   gboolean          (* can_clip_redraws)        (ClutterStageWindow *stage_window);
- 
-   GList            *(* get_views)               (ClutterStageWindow *stage_window);
-@@ -119,10 +115,6 @@ void              _clutter_stage_window_set_accept_focus        (ClutterStageWin
- 
- void              _clutter_stage_window_redraw                  (ClutterStageWindow *window);
- 
--void              _clutter_stage_window_get_dirty_pixel         (ClutterStageWindow *window,
--                                                                 ClutterStageView   *view,
--                                                                 int *x, int *y);
--
- gboolean          _clutter_stage_window_can_clip_redraws        (ClutterStageWindow *window);
- 
- GList *           _clutter_stage_window_get_views               (ClutterStageWindow *window);
-diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
-index 1eea5b305..bd0ac9ed2 100644
---- a/clutter/clutter/clutter-stage.c
-+++ b/clutter/clutter/clutter-stage.c
-@@ -103,6 +103,23 @@ struct _ClutterStageQueueRedrawEntry
-   ClutterPaintVolume clip;
- };
- 
-+struct _PickRecord
-+{
-+  ClutterPoint vertex[4];
-+  ClutterActor *actor;
-+  int clip_stack_top;
-+};
-+
-+typedef struct _PickRecord PickRecord;
-+
-+struct _PickClipRecord
-+{
-+  int prev;
-+  ClutterPoint vertex[4];
-+};
-+
-+typedef struct _PickClipRecord PickClipRecord;
-+
- struct _ClutterStagePrivate
- {
-   /* the stage implementation */
-@@ -136,7 +153,11 @@ struct _ClutterStagePrivate
-   GTimer *fps_timer;
-   gint32 timer_n_frames;
- 
--  ClutterIDPool *pick_id_pool;
-+  GArray *pick_stack;
-+  GArray *pick_clip_stack;
-+  int pick_clip_stack_top;
-+  gboolean pick_stack_frozen;
-+  ClutterPickMode cached_pick_mode;
- 
- #ifdef CLUTTER_ENABLE_DEBUG
-   gulong redraw_count;
-@@ -322,6 +343,177 @@ clutter_stage_get_preferred_height (ClutterActor *self,
-     *natural_height_p = geom.height;
- }
- 
-+/* In order to keep weak pointers valid between frames we need them to not
-+ * move in memory, so the stack is marked as "frozen".
-+ */
-+static void
-+_clutter_stage_freeze_pick_stack (ClutterStage *stage)
-+{
-+  ClutterStagePrivate *priv = stage->priv;
-+  int i;
-+
-+  if (priv->pick_stack_frozen)
-+    return;
-+
-+  for (i = 0; i < priv->pick_stack->len; i++)
-+    {
-+      PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
-+
-+      if (rec->actor)
-+        g_object_add_weak_pointer (G_OBJECT (rec->actor),
-+                                   (gpointer) &rec->actor);
-+    }
-+
-+  priv->pick_stack_frozen = TRUE;
-+}
-+
-+static void
-+_clutter_stage_thaw_pick_stack (ClutterStage *stage)
-+{
-+  ClutterStagePrivate *priv = stage->priv;
-+  int i;
-+
-+  if (!priv->pick_stack_frozen)
-+    return;
-+
-+  for (i = 0; i < priv->pick_stack->len; i++)
-+    {
-+      PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
-+
-+      if (rec->actor)
-+        g_object_remove_weak_pointer (G_OBJECT (rec->actor),
-+                                      (gpointer) &rec->actor);
-+    }
-+
-+  priv->pick_stack_frozen = FALSE;
-+}
-+
-+static void
-+_clutter_stage_clear_pick_stack (ClutterStage *stage)
-+{
-+  ClutterStagePrivate *priv = stage->priv;
-+
-+  _clutter_stage_thaw_pick_stack (stage);
-+  g_array_set_size (priv->pick_stack, 0);
-+  g_array_set_size (priv->pick_clip_stack, 0);
-+  priv->pick_clip_stack_top = -1;
-+  priv->cached_pick_mode = CLUTTER_PICK_NONE;
-+}
-+
-+void
-+_clutter_stage_log_pick (ClutterStage       *stage,
-+                         const ClutterPoint  vertices[4],
-+                         ClutterActor       *actor)
-+{
-+  ClutterStagePrivate *priv;
-+  PickRecord rec;
-+
-+  g_return_if_fail (CLUTTER_IS_STAGE (stage));
-+  g_return_if_fail (actor != NULL);
-+
-+  priv = stage->priv;
-+
-+  g_assert (!priv->pick_stack_frozen);
-+
-+  memcpy (rec.vertex, vertices, 4 * sizeof (ClutterPoint));
-+  rec.actor = actor;
-+  rec.clip_stack_top = priv->pick_clip_stack_top;
-+
-+  g_array_append_val (priv->pick_stack, rec);
-+}
-+
-+void
-+_clutter_stage_push_pick_clip (ClutterStage       *stage,
-+                               const ClutterPoint  vertices[4])
-+{
-+  ClutterStagePrivate *priv;
-+  PickClipRecord clip;
-+
-+  g_return_if_fail (CLUTTER_IS_STAGE (stage));
-+
-+  priv = stage->priv;
-+
-+  g_assert (!priv->pick_stack_frozen);
-+
-+  clip.prev = priv->pick_clip_stack_top;
-+  memcpy (clip.vertex, vertices, 4 * sizeof (ClutterPoint));
-+
-+  g_array_append_val (priv->pick_clip_stack, clip);
-+  priv->pick_clip_stack_top = priv->pick_clip_stack->len - 1;
-+}
-+
-+void
-+_clutter_stage_pop_pick_clip (ClutterStage *stage)
-+{
-+  ClutterStagePrivate *priv;
-+  const PickClipRecord *top;
-+
-+  g_return_if_fail (CLUTTER_IS_STAGE (stage));
-+
-+  priv = stage->priv;
-+
-+  g_assert (!priv->pick_stack_frozen);
-+  g_assert (priv->pick_clip_stack_top >= 0);
-+
-+  /* Individual elements of pick_clip_stack are not freed. This is so they
-+   * can be shared as part of a tree of different stacks used by different
-+   * actors in the pick_stack. The whole pick_clip_stack does however get
-+   * freed later in _clutter_stage_clear_pick_stack.
-+   */
-+
-+  top = &g_array_index (priv->pick_clip_stack,
-+                        PickClipRecord,
-+                        priv->pick_clip_stack_top);
-+
-+  priv->pick_clip_stack_top = top->prev;
-+}
-+
-+static gboolean
-+pick_record_contains_pixel (ClutterStage       *stage,
-+                            const PickRecord   *rec,
-+                            int                 x,
-+                            int                 y)
-+{
-+  ClutterStagePrivate *priv;
-+  int clip_index;
-+
-+  /* We test the centre point of the pixel so that we can use
-+   * clutter_point_inside_polygon and avoid any ambiguity about the boundaries
-+   * of pixel-aligned actors. If we were to use point (x,y) instead (which is
-+   * the top-left corner of the pixel) then we'd need to use
-+   * clutter_point_touches_polygon.
-+   */
-+  const ClutterPoint point = { x + 0.5f, y + 0.5f };
-+
-+  if (!clutter_point_inside_polygon (&point, rec->vertex, 4))
-+    return FALSE;
-+
-+  priv = stage->priv;
-+
-+  /* pick_clip_stack is actually a graph containing one or more trees. And the
-+   * clip_stack_top for a given PickRecord is the path from a leaf of such a
-+   * tree to its root. It's still a stack though, from the point of view of the
-+   * code that built it and the code that traverses it here.
-+   *
-+   * Allowing multiple stacks to overlap and merge into trees saves us time and
-+   * memory.
-+   */
-+  clip_index = rec->clip_stack_top;
-+  while (clip_index >= 0)
-+    {
-+      const PickClipRecord *clip = &g_array_index (priv->pick_clip_stack,
-+                                                   PickClipRecord,
-+                                                   clip_index);
-+
-+      if (!clutter_point_inside_polygon (&point, clip->vertex, 4))
-+        return FALSE;
-+
-+      clip_index = clip->prev;
-+    }
-+
-+  return TRUE;
-+}
-+
- static inline void
- queue_full_redraw (ClutterStage *stage)
- {
-@@ -632,6 +824,12 @@ clutter_stage_do_paint_view (ClutterStage                *stage,
-   float viewport[4];
-   cairo_rectangle_int_t geom;
- 
-+  /* Any mode of painting/picking invalidates the pick cache, unless we're
-+   * in the middle of building it. So we reset the cached flag but don't
-+   * completely clear the pick stack...
-+   */
-+  priv->cached_pick_mode = CLUTTER_PICK_NONE;
-+
-   _clutter_stage_window_get_geometry (priv->impl, &geom);
- 
-   viewport[0] = priv->viewport[0];
-@@ -1397,40 +1595,6 @@ clutter_stage_get_redraw_clip_bounds (ClutterStage          *stage,
-     }
- }
- 
--static void
--read_pixels_to_file (CoglFramebuffer *fb,
--                     char            *filename_stem,
--                     int              x,
--                     int              y,
--                     int              width,
--                     int              height)
--{
--  guint8 *data;
--  cairo_surface_t *surface;
--  static int read_count = 0;
--  char *filename = g_strdup_printf ("%s-%05d.png",
--                                    filename_stem,
--                                    read_count);
--
--  data = g_malloc (4 * width * height);
--  cogl_framebuffer_read_pixels (fb,
--                                x, y, width, height,
--                                CLUTTER_CAIRO_FORMAT_ARGB32,
--                                data);
--
--  surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_RGB24,
--                                                 width, height,
--                                                 width * 4);
--
--  cairo_surface_write_to_png (surface, filename);
--  cairo_surface_destroy (surface);
--
--  g_free (data);
--  g_free (filename);
--
--  read_count++;
--}
--
- static ClutterActor *
- _clutter_stage_do_pick_on_view (ClutterStage     *stage,
-                                 gint              x,
-@@ -1438,140 +1602,47 @@ _clutter_stage_do_pick_on_view (ClutterStage     *stage,
-                                 ClutterPickMode   mode,
-                                 ClutterStageView *view)
- {
--  ClutterActor *actor = CLUTTER_ACTOR (stage);
-+  ClutterMainContext *context = _clutter_context_get_default ();
-+  int i;
-   ClutterStagePrivate *priv = stage->priv;
-   CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
--  cairo_rectangle_int_t view_layout;
--  ClutterMainContext *context;
--  guchar pixel[4] = { 0xff, 0xff, 0xff, 0xff };
--  CoglColor stage_pick_id;
--  gboolean dither_enabled_save;
--  ClutterActor *retval;
--  gint dirty_x;
--  gint dirty_y;
--  gint read_x;
--  gint read_y;
--  float fb_width, fb_height;
--  float fb_scale;
--  float viewport_offset_x;
--  float viewport_offset_y;
--
--  priv = stage->priv;
--
--  context = _clutter_context_get_default ();
--  fb_scale = clutter_stage_view_get_scale (view);
--  clutter_stage_view_get_layout (view, &view_layout);
--
--  fb_width = view_layout.width * fb_scale;
--  fb_height = view_layout.height * fb_scale;
--  cogl_push_framebuffer (fb);
- 
--  /* needed for when a context switch happens */
--  _clutter_stage_maybe_setup_viewport (stage, view);
--
--  /* FIXME: For some reason leaving the cogl clip stack empty causes the
--   * picking to not work at all, so setting it the whole framebuffer content
--   * for now. */
--  cogl_framebuffer_push_scissor_clip (fb, 0, 0,
--                                      view_layout.width * fb_scale,
--                                      view_layout.height * fb_scale);
--
--  _clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
--
--  if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
--    {
--      CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
--                    (int) (dirty_x * fb_scale),
--                    (int) (dirty_y * fb_scale));
--      cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
--    }
-+  /* We are not reentrant right now. If this proves to be a problem then we
-+   * would need to keep a stack of pick_stack's, or something... :(
-+   */
-+  g_assert (context->pick_mode == CLUTTER_PICK_NONE);
- 
--  viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
--  viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
--  CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
--                priv->viewport[0] * fb_scale - viewport_offset_x,
--                priv->viewport[1] * fb_scale - viewport_offset_y,
--                priv->viewport[2] * fb_scale,
--                priv->viewport[3] * fb_scale);
--  cogl_framebuffer_set_viewport (fb,
--                                 priv->viewport[0] * fb_scale - viewport_offset_x,
--                                 priv->viewport[1] * fb_scale - viewport_offset_y,
--                                 priv->viewport[2] * fb_scale,
--                                 priv->viewport[3] * fb_scale);
--
--  read_x = dirty_x * fb_scale;
--  read_y = dirty_y * fb_scale;
--
--  CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %f",
--                x, y,
--                view_layout.width, view_layout.height,
--                view_layout.x, view_layout.y, fb_scale);
--
--  cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
--  cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH, &stage_pick_id);
--
--  /* Disable dithering (if any) when doing the painting in pick mode */
--  dither_enabled_save = cogl_framebuffer_get_dither_enabled (fb);
--  cogl_framebuffer_set_dither_enabled (fb, FALSE);
--
--  /* Render the entire scence in pick mode - just single colored silhouette's
--   * are drawn offscreen (as we never swap buffers)
--  */
--  context->pick_mode = mode;
--
--  clutter_stage_do_paint_view (stage, view, NULL);
--  context->pick_mode = CLUTTER_PICK_NONE;
--
--  /* Read the color of the screen co-ords pixel. RGBA_8888_PRE is used
--     even though we don't care about the alpha component because under
--     GLES this is the only format that is guaranteed to work so Cogl
--     will end up having to do a conversion if any other format is
--     used. The format is requested as pre-multiplied because Cogl
--     assumes that all pixels in the framebuffer are premultiplied so
--     it avoids a conversion. */
--  cogl_framebuffer_read_pixels (fb,
--                                read_x, read_y, 1, 1,
--                                COGL_PIXEL_FORMAT_RGBA_8888_PRE,
--                                pixel);
--
--  if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS))
-+  if (mode != priv->cached_pick_mode)
-     {
--      char *file_name =
--        g_strdup_printf ("pick-buffer-%s-view-x-%d",
--                         _clutter_actor_get_debug_name (actor),
--                         view_layout.x);
--
--      read_pixels_to_file (fb, file_name, 0, 0, fb_width, fb_height);
-+      _clutter_stage_clear_pick_stack (stage);
- 
--      g_free (file_name);
-+      /* We don't render to the fb, but have to set one to stop the cogl matrix
-+       * operations from crashing in paint functions. Because the matrices are
-+       * stored relative to the current fb.
-+       */
-+      cogl_push_framebuffer (fb);
-+      context->pick_mode = mode;
-+      clutter_stage_do_paint_view (stage, view, NULL);
-+      context->pick_mode = CLUTTER_PICK_NONE;
-+      priv->cached_pick_mode = mode;
-+      cogl_pop_framebuffer ();
-+
-+      _clutter_stage_freeze_pick_stack (stage);
-     }
- 
--  /* Restore whether GL_DITHER was enabled */
--  cogl_framebuffer_set_dither_enabled (fb, dither_enabled_save);
--
--  if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
--    cogl_framebuffer_pop_clip (fb);
--
--  cogl_framebuffer_pop_clip (fb);
--
--  _clutter_stage_dirty_viewport (stage);
--
--  if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
--    retval = actor;
--  else
-+  /* Search all "painted" pickable actors from front to back. A linear search
-+   * is required, and also performs fine since there is typically only
-+   * on the order of dozens of actors in the list (on screen) at a time.
-+   */
-+  for (i = priv->pick_stack->len - 1; i >= 0; i--)
-     {
--      guint32 id_ = _clutter_pixel_to_id (pixel);
-+      const PickRecord *rec = &g_array_index (priv->pick_stack, PickRecord, i);
- 
--      retval = _clutter_stage_get_actor_by_pick_id (stage, id_);
--      CLUTTER_NOTE (PICK, "Picking actor %s with id %u (pixel: 0x%x%x%x%x",
--                    G_OBJECT_TYPE_NAME (retval),
--                    id_,
--                    pixel[0], pixel[1], pixel[2], pixel[3]);
-+      if (rec->actor && pick_record_contains_pixel (stage, rec, x, y))
-+        return rec->actor;
-     }
- 
--  cogl_pop_framebuffer ();
--
--  return retval;
-+  return CLUTTER_ACTOR (stage);
- }
- 
- static ClutterStageView *
-@@ -1884,7 +1955,9 @@ clutter_stage_finalize (GObject *object)
- 
-   g_array_free (priv->paint_volume_stack, TRUE);
- 
--  _clutter_id_pool_free (priv->pick_id_pool);
-+  _clutter_stage_clear_pick_stack (stage);
-+  g_array_free (priv->pick_clip_stack, TRUE);
-+  g_array_free (priv->pick_stack, TRUE);
- 
-   if (priv->fps_timer != NULL)
-     g_timer_destroy (priv->fps_timer);
-@@ -2384,7 +2457,10 @@ clutter_stage_init (ClutterStage *self)
-   priv->paint_volume_stack =
-     g_array_new (FALSE, FALSE, sizeof (ClutterPaintVolume));
- 
--  priv->pick_id_pool = _clutter_id_pool_new (256);
-+  priv->pick_stack = g_array_new (FALSE, FALSE, sizeof (PickRecord));
-+  priv->pick_clip_stack = g_array_new (FALSE, FALSE, sizeof (PickClipRecord));
-+  priv->pick_clip_stack_top = -1;
-+  priv->cached_pick_mode = CLUTTER_PICK_NONE;
- }
- 
- /**
-@@ -4208,6 +4284,12 @@ _clutter_stage_queue_actor_redraw (ClutterStage                 *stage,
-   CLUTTER_NOTE (CLIPPING, "stage_queue_actor_redraw (actor=%s, clip=%p): ",
-                 _clutter_actor_get_debug_name (actor), clip);
- 
-+  /* Queuing a redraw or clip change invalidates the pick cache, unless we're
-+   * in the middle of building it. So we reset the cached flag but don't
-+   * completely clear the pick stack...
-+   */
-+  priv->cached_pick_mode = CLUTTER_PICK_NONE;
-+
-   if (!priv->redraw_pending)
-     {
-       ClutterMasterClock *master_clock;
-@@ -4468,39 +4550,6 @@ _clutter_stage_get_active_framebuffer (ClutterStage *stage)
-   return stage->priv->active_framebuffer;
- }
- 
--gint32
--_clutter_stage_acquire_pick_id (ClutterStage *stage,
--                                ClutterActor *actor)
--{
--  ClutterStagePrivate *priv = stage->priv;
--
--  g_assert (priv->pick_id_pool != NULL);
--
--  return _clutter_id_pool_add (priv->pick_id_pool, actor);
--}
--
--void
--_clutter_stage_release_pick_id (ClutterStage *stage,
--                                gint32        pick_id)
--{
--  ClutterStagePrivate *priv = stage->priv;
--
--  g_assert (priv->pick_id_pool != NULL);
--
--  _clutter_id_pool_remove (priv->pick_id_pool, pick_id);
--}
--
--ClutterActor *
--_clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
--                                     gint32        pick_id)
--{
--  ClutterStagePrivate *priv = stage->priv;
--
--  g_assert (priv->pick_id_pool != NULL);
--
--  return _clutter_id_pool_lookup (priv->pick_id_pool, pick_id);
--}
--
- void
- _clutter_stage_add_pointer_drag_actor (ClutterStage       *stage,
-                                        ClutterInputDevice *device,
-diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
-index 4f8d6a650..f957d9840 100644
---- a/clutter/clutter/cogl/clutter-stage-cogl.c
-+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
-@@ -983,55 +983,6 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
-   stage_cogl->frame_count++;
- }
- 
--static void
--clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
--                                    ClutterStageView   *view,
--                                    int                *x,
--                                    int                *y)
--{
--  CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
--  gboolean has_buffer_age =
--    cogl_is_onscreen (framebuffer) &&
--    is_buffer_age_enabled ();
--  float fb_scale;
--  gboolean scale_is_fractional;
--
--  fb_scale = clutter_stage_view_get_scale (view);
--  if (fb_scale != floorf (fb_scale))
--    scale_is_fractional = TRUE;
--  else
--    scale_is_fractional = FALSE;
--
--  /*
--   * Buffer damage is tracked in the framebuffer coordinate space
--   * using the damage history. When fractional scaling is used, a
--   * coordinate on the stage might not correspond to the exact position of any
--   * physical pixel, which causes issues when painting using the pick mode.
--   *
--   * For now, always use the (0, 0) pixel for picking when using fractional
--   * framebuffer scaling.
--   */
--  if (!has_buffer_age || scale_is_fractional)
--    {
--      *x = 0;
--      *y = 0;
--    }
--  else
--    {
--      ClutterStageViewCogl *view_cogl = CLUTTER_STAGE_VIEW_COGL (view);
--      ClutterStageViewCoglPrivate *view_priv =
--        clutter_stage_view_cogl_get_instance_private (view_cogl);
--      cairo_rectangle_int_t view_layout;
--      cairo_rectangle_int_t *fb_damage;
--
--      clutter_stage_view_get_layout (view, &view_layout);
--
--      fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
--      *x = fb_damage->x / fb_scale;
--      *y = fb_damage->y / fb_scale;
--    }
--}
--
- static void
- clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
- {
-@@ -1049,7 +1000,6 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
-   iface->ignoring_redraw_clips = clutter_stage_cogl_ignoring_redraw_clips;
-   iface->get_redraw_clip_bounds = clutter_stage_cogl_get_redraw_clip_bounds;
-   iface->redraw = clutter_stage_cogl_redraw;
--  iface->get_dirty_pixel = clutter_stage_cogl_get_dirty_pixel;
- }
- 
- static void
-diff --git a/clutter/clutter/deprecated/clutter-texture.c b/clutter/clutter/deprecated/clutter-texture.c
-index bea239f45..2c677b8a4 100644
---- a/clutter/clutter/deprecated/clutter-texture.c
-+++ b/clutter/clutter/deprecated/clutter-texture.c
-@@ -572,83 +572,6 @@ gen_texcoords_and_draw_cogl_rectangle (ClutterActor    *self,
-                                             0, 0, t_w, t_h);
- }
- 
--static CoglPipeline *
--create_pick_pipeline (ClutterActor *self)
--{
--  ClutterTexture *texture = CLUTTER_TEXTURE (self);
--  ClutterTexturePrivate *priv = texture->priv;
--  CoglPipeline *pick_pipeline = cogl_pipeline_copy (texture_template_pipeline);
--  GError *error = NULL;
--
--  if (!cogl_pipeline_set_layer_combine (pick_pipeline, 0,
--                                        "RGBA = "
--                                        "  MODULATE (CONSTANT, TEXTURE[A])",
--                                        &error))
--    {
--      if (!priv->seen_create_pick_pipeline_warning)
--        g_warning ("Error setting up texture combine for shaped "
--                   "texture picking: %s", error->message);
--      priv->seen_create_pick_pipeline_warning = TRUE;
--      g_error_free (error);
--      cogl_object_unref (pick_pipeline);
--      return NULL;
--    }
--
--  cogl_pipeline_set_blend (pick_pipeline,
--                           "RGBA = ADD (SRC_COLOR[RGBA], 0)",
--                           NULL);
--
--  cogl_pipeline_set_alpha_test_function (pick_pipeline,
--                                         COGL_PIPELINE_ALPHA_FUNC_EQUAL,
--                                         1.0);
--
--  return pick_pipeline;
--}
--
--static void
--clutter_texture_pick (ClutterActor       *self,
--                      const ClutterColor *color)
--{
--  ClutterTexture *texture = CLUTTER_TEXTURE (self);
--  ClutterTexturePrivate *priv = texture->priv;
--  CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
--
--  if (!clutter_actor_should_pick_paint (self))
--    return;
--
--  if (G_LIKELY (priv->pick_with_alpha_supported) && priv->pick_with_alpha)
--    {
--      CoglColor pick_color;
--
--      if (priv->pick_pipeline == NULL)
--        priv->pick_pipeline = create_pick_pipeline (self);
--
--      if (priv->pick_pipeline == NULL)
--        {
--          priv->pick_with_alpha_supported = FALSE;
--          CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self,
--                                                                    color);
--          return;
--        }
--
--      if (priv->fbo_handle != NULL)
--        update_fbo (self);
--
--      cogl_color_init_from_4ub (&pick_color,
--                                color->red,
--                                color->green,
--                                color->blue,
--                                0xff);
--      cogl_pipeline_set_layer_combine_constant (priv->pick_pipeline,
--                                                0, &pick_color);
--      cogl_pipeline_set_layer_texture (priv->pick_pipeline, 0,
--                                       clutter_texture_get_cogl_texture (texture));
--      gen_texcoords_and_draw_cogl_rectangle (self, priv->pick_pipeline, framebuffer);
--    }
--  else
--    CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->pick (self, color);
--}
--
- static void
- clutter_texture_paint (ClutterActor *self)
- {
-@@ -767,12 +690,6 @@ clutter_texture_dispose (GObject *object)
-       priv->pipeline = NULL;
-     }
- 
--  if (priv->pick_pipeline != NULL)
--    {
--      cogl_object_unref (priv->pick_pipeline);
--      priv->pick_pipeline = NULL;
--    }
--
-   G_OBJECT_CLASS (clutter_texture_parent_class)->dispose (object);
- }
- 
-@@ -944,7 +861,6 @@ clutter_texture_class_init (ClutterTextureClass *klass)
-   GParamSpec *pspec;
- 
-   actor_class->paint            = clutter_texture_paint;
--  actor_class->pick             = clutter_texture_pick;
-   actor_class->get_paint_volume = clutter_texture_get_paint_volume;
-   actor_class->realize          = clutter_texture_realize;
-   actor_class->unrealize        = clutter_texture_unrealize;
-@@ -1263,11 +1179,9 @@ clutter_texture_init (ClutterTexture *self)
-   priv->repeat_y          = FALSE;
-   priv->sync_actor_size   = TRUE;
-   priv->fbo_handle        = NULL;
--  priv->pick_pipeline     = NULL;
-   priv->keep_aspect_ratio = FALSE;
-   priv->pick_with_alpha   = FALSE;
-   priv->pick_with_alpha_supported = TRUE;
--  priv->seen_create_pick_pipeline_warning = FALSE;
- 
-   if (G_UNLIKELY (texture_template_pipeline == NULL))
-     {
-@@ -3052,13 +2966,8 @@ clutter_texture_set_pick_with_alpha (ClutterTexture *texture,
-   if (priv->pick_with_alpha == pick_with_alpha)
-     return;
- 
--  if (!pick_with_alpha && priv->pick_pipeline != NULL)
--    {
--      cogl_object_unref (priv->pick_pipeline);
--      priv->pick_pipeline = NULL;
--    }
-+  g_assert (!pick_with_alpha);  /* No longer supported */
- 
--  /* NB: the pick pipeline is created lazily when we first pick */
-   priv->pick_with_alpha = pick_with_alpha;
- 
-   /* NB: actors are expected to call clutter_actor_queue_redraw when
-diff --git a/clutter/tests/conform/actor-pick.c b/clutter/tests/conform/actor-pick.c
-index 969b4920a..2bf5954c7 100644
---- a/clutter/tests/conform/actor-pick.c
-+++ b/clutter/tests/conform/actor-pick.c
-@@ -5,7 +5,6 @@
- #define STAGE_HEIGHT 480
- #define ACTORS_X 12
- #define ACTORS_Y 16
--#define SHIFT_STEP STAGE_WIDTH / ACTORS_X
- 
- typedef struct _State State;
- 
-@@ -20,84 +19,11 @@ struct _State
-   gboolean pass;
- };
- 
--struct _ShiftEffect
--{
--  ClutterShaderEffect parent_instance;
--};
--
--struct _ShiftEffectClass
--{
--  ClutterShaderEffectClass parent_class;
--};
--
--typedef struct _ShiftEffect       ShiftEffect;
--typedef struct _ShiftEffectClass  ShiftEffectClass;
--
--#define TYPE_SHIFT_EFFECT        (shift_effect_get_type ())
--
--GType shift_effect_get_type (void);
--
--G_DEFINE_TYPE (ShiftEffect,
--               shift_effect,
--               CLUTTER_TYPE_SHADER_EFFECT);
--
--static void
--shader_paint (ClutterEffect           *effect,
--              ClutterEffectPaintFlags  flags)
--{
--  ClutterShaderEffect *shader = CLUTTER_SHADER_EFFECT (effect);
--  float tex_width;
--  ClutterActor *actor =
--    clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
--
--  if (g_test_verbose ())
--    g_debug ("shader_paint");
--
--  clutter_shader_effect_set_shader_source (shader,
--    "uniform sampler2D tex;\n"
--    "uniform float step;\n"
--    "void main (void)\n"
--    "{\n"
--    "  cogl_color_out = texture2D(tex, vec2 (cogl_tex_coord_in[0].s + step,\n"
--    "                                        cogl_tex_coord_in[0].t));\n"
--    "}\n");
--
--  tex_width = clutter_actor_get_width (actor);
--
--  clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0);
--  clutter_shader_effect_set_uniform (shader, "step", G_TYPE_FLOAT, 1,
--                                     SHIFT_STEP / tex_width);
--
--  CLUTTER_EFFECT_CLASS (shift_effect_parent_class)->paint (effect, flags);
--}
--
--static void
--shader_pick (ClutterEffect           *effect,
--             ClutterEffectPaintFlags  flags)
--{
--  shader_paint (effect, flags);
--}
--
--static void
--shift_effect_class_init (ShiftEffectClass *klass)
--{
--  ClutterEffectClass *shader_class = CLUTTER_EFFECT_CLASS (klass);
--
--  shader_class->paint = shader_paint;
--  shader_class->pick = shader_pick;
--}
--
--static void
--shift_effect_init (ShiftEffect *self)
--{
--}
--
- static const char *test_passes[] = {
-   "No covering actor",
-   "Invisible covering actor",
-   "Clipped covering actor",
-   "Blur effect",
--  "Shift effect",
- };
- 
- static gboolean
-@@ -165,30 +91,10 @@ on_timeout (gpointer data)
-           if (g_test_verbose ())
-             g_print ("With blur effect:\n");
-         }
--      else if (test_num == 4)
--        {
--          if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
--            continue;
--
--          clutter_actor_hide (over_actor);
--          clutter_actor_remove_effect_by_name (CLUTTER_ACTOR (state->stage),
--                                               "blur");
--
--          clutter_actor_add_effect_with_name (CLUTTER_ACTOR (state->stage),
--                                              "shift",
--                                              g_object_new (TYPE_SHIFT_EFFECT,
--                                                            NULL));
--
--          if (g_test_verbose ())
--            g_print ("With shift effect:\n");
--        }
- 
-       for (y = 0; y < ACTORS_Y; y++)
-         {
--          if (test_num == 4)
--            x = 1;
--          else
--            x = 0;
-+          x = 0;
- 
-           for (; x < ACTORS_X; x++)
-             {
-@@ -198,9 +104,6 @@ on_timeout (gpointer data)
- 
-               pick_x = x * state->actor_width + state->actor_width / 2;
- 
--              if (test_num == 4)
--                pick_x -= SHIFT_STEP;
--
-               actor =
-                 clutter_stage_get_actor_at_pos (CLUTTER_STAGE (state->stage),
-                                                 CLUTTER_PICK_ALL,
-diff --git a/clutter/tests/conform/meson.build b/clutter/tests/conform/meson.build
-index 916f5c342..e747c9b79 100644
---- a/clutter/tests/conform/meson.build
-+++ b/clutter/tests/conform/meson.build
-@@ -43,7 +43,6 @@ clutter_conform_tests_deprecated_tests = [
-   'behaviours',
-   'group',
-   'rectangle',
--  'texture',
- ]
- 
- clutter_conform_tests = []
-diff --git a/clutter/tests/conform/texture.c b/clutter/tests/conform/texture.c
-deleted file mode 100644
-index 392fd5c47..000000000
---- a/clutter/tests/conform/texture.c
-+++ /dev/null
-@@ -1,84 +0,0 @@
--#define CLUTTER_DISABLE_DEPRECATION_WARNINGS
--#include <clutter/clutter.h>
--#include <string.h>
--
--static CoglHandle
--make_texture (void)
--{
--  guint32 *data = g_malloc (100 * 100 * 4);
--  int x;
--  int y;
--
--  for (y = 0; y < 100; y ++)
--    for (x = 0; x < 100; x++)
--      {
--        if (x < 50 && y < 50)
--          data[y * 100 + x] = 0xff00ff00;
--        else
--          data[y * 100 + x] = 0xff00ffff;
--      }
--  return cogl_texture_new_from_data (100,
--                                     100,
--                                     COGL_TEXTURE_NONE,
--                                     COGL_PIXEL_FORMAT_ARGB_8888,
--                                     COGL_PIXEL_FORMAT_ARGB_8888,
--                                     400,
--                                     (guchar *)data);
--}
--
--static void
--texture_pick_with_alpha (void)
--{
--  ClutterTexture *tex = CLUTTER_TEXTURE (clutter_texture_new ());
--  ClutterStage *stage = CLUTTER_STAGE (clutter_test_get_stage ());
--  ClutterActor *actor;
--
--  clutter_texture_set_cogl_texture (tex, make_texture ());
--
--  clutter_actor_add_child (CLUTTER_ACTOR (stage), CLUTTER_ACTOR (tex));
--
--  clutter_actor_show (CLUTTER_ACTOR (stage));
--
--  if (g_test_verbose ())
--    {
--      g_print ("\nstage = %p\n", stage);
--      g_print ("texture = %p\n\n", tex);
--    }
--
--  clutter_texture_set_pick_with_alpha (tex, TRUE);
--  if (g_test_verbose ())
--    g_print ("Testing with pick-with-alpha enabled:\n");
--
--  /* This should fall through and hit the stage: */
--  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 10);
--  if (g_test_verbose ())
--    g_print ("actor @ (10, 10) = %p\n", actor);
--  g_assert (actor == CLUTTER_ACTOR (stage));
--
--  /* The rest should hit the texture */
--  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 90, 10);
--  if (g_test_verbose ())
--    g_print ("actor @ (90, 10) = %p\n", actor);
--  g_assert (actor == CLUTTER_ACTOR (tex));
--  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 90, 90);
--  if (g_test_verbose ())
--    g_print ("actor @ (90, 90) = %p\n", actor);
--  g_assert (actor == CLUTTER_ACTOR (tex));
--  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 90);
--  if (g_test_verbose ())
--    g_print ("actor @ (10, 90) = %p\n", actor);
--  g_assert (actor == CLUTTER_ACTOR (tex));
--
--  clutter_texture_set_pick_with_alpha (tex, FALSE);
--  if (g_test_verbose ())
--    g_print ("Testing with pick-with-alpha disabled:\n");
--
--  actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_ALL, 10, 10);
--  if (g_test_verbose ())
--    g_print ("actor @ (10, 10) = %p\n", actor);
--  g_assert (actor == CLUTTER_ACTOR (tex));
--}
--
--CLUTTER_TEST_SUITE (
--  CLUTTER_TEST_UNIT ("/texture/pick-with-alpha", texture_pick_with_alpha)
--)
-diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
-index ca4ca19a9..814199145 100644
---- a/src/compositor/meta-surface-actor.c
-+++ b/src/compositor/meta-surface-actor.c
-@@ -70,38 +70,23 @@ meta_surface_actor_pick (ClutterActor       *actor,
-   else
-     {
-       int n_rects;
--      float *rectangles;
-       int i;
--      CoglPipeline *pipeline;
--      CoglContext *ctx;
--      CoglFramebuffer *fb;
--      CoglColor cogl_color;
- 
-       n_rects = cairo_region_num_rectangles (priv->input_region);
--      rectangles = g_alloca (sizeof (float) * 4 * n_rects);
- 
-       for (i = 0; i < n_rects; i++)
-         {
-           cairo_rectangle_int_t rect;
--          int pos = i * 4;
-+          ClutterActorBox box;
- 
-           cairo_region_get_rectangle (priv->input_region, i, &rect);
- 
--          rectangles[pos + 0] = rect.x;
--          rectangles[pos + 1] = rect.y;
--          rectangles[pos + 2] = rect.x + rect.width;
--          rectangles[pos + 3] = rect.y + rect.height;
-+          box.x1 = rect.x;
-+          box.y1 = rect.y;
-+          box.x2 = rect.x + rect.width;
-+          box.y2 = rect.y + rect.height;
-+          clutter_actor_pick_box (actor, &box);
-         }
--
--      ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
--      fb = cogl_get_draw_framebuffer ();
--
--      cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
--
--      pipeline = cogl_pipeline_new (ctx);
--      cogl_pipeline_set_color (pipeline, &cogl_color);
--      cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects);
--      cogl_object_unref (pipeline);
-     }
- 
-   clutter_actor_iter_init (&iter, actor);
--- 
-2.23.0
-

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2019-09-12 20:57:17 UTC (rev 362343)
+++ PKGBUILD	2019-09-12 21:06:45 UTC (rev 362344)
@@ -3,7 +3,7 @@
 # Contributor: Michael Kanis <mkanis_at_gmx_dot_de>
 
 pkgname=mutter
-pkgver=3.32.2+43+gb7f158811
+pkgver=3.34.0
 pkgrel=1
 pkgdesc="A window manager for GNOME"
 url="https://gitlab.gnome.org/GNOME/mutter"
@@ -12,19 +12,13 @@
 depends=(dconf gobject-introspection-runtime gsettings-desktop-schemas libcanberra
          startup-notification zenity libsm gnome-desktop upower libxkbcommon-x11
          gnome-settings-daemon libgudev libinput pipewire xorg-server-xwayland)
-makedepends=(gobject-introspection git egl-wayland meson xorg-server)
+makedepends=(gobject-introspection git egl-wayland meson xorg-server sysprof)
 checkdepends=(xorg-server-xvfb)
 groups=(gnome)
 install=mutter.install
-_commit=b7f158811934d8e4d9dd0be28ad8e1746ceac46c  # gnome-3-32
-source=("git+https://gitlab.gnome.org/GNOME/mutter.git#commit=$_commit"
-        0001-Remove-GLX-threaded-swap-wait.patch
-        0001-Add-point-polygon-testing-API.patch
-        0002-Geometric-OpenGL-less-picking.patch)
-sha256sums=('SKIP'
-            '92c0dd3a1df455722c7bfb205eab7c72ee21055d64f397bea5a8332431f3fee7'
-            '12c69bdc0836b47d5d6eba0f5b0118035aa08330388a05fcee367025adb31f21'
-            'a6643593071ab171866dd6fdb30e65826a753a134832a8e1ec05b2b515d599e5')
+_commit=8cdcf529e9acd95e903f699acfbde7f75213ebec  # tags/3.34.0^0
+source=("git+https://gitlab.gnome.org/GNOME/mutter.git#commit=$_commit")
+sha256sums=('SKIP')
 
 pkgver() {
   cd $pkgname
@@ -34,29 +28,8 @@
 prepare() {
   cd $pkgname
 
-  # rt-scheduler feature (needs CAP_SYS_NICE)
-  git cherry-pick -n dae2c1d420ed272710ac55b7a00f6787e5c0e762  # !460
-
-  # high-priority EGL contexts (needs CAP_SYS_NICE)
-  git cherry-pick -n 3f29b47809a038b45528dfccd4089721c97965df  # !454
-  git cherry-pick -n 7df86fb24646f8a19a47e54b86424048ec08e715  # !454
-
-  # reduce lag
-  git cherry-pick -n 45244852acc214a7a9d01dc96896ad0c079b437c  # !520
-  git cherry-pick -n 4faeb12731b81ce617042973155cc4b5737e1133  # !281
-
   # reduce overhead moving cursor or windows
-  git cherry-pick -n 01e20a6ba9e0cfa22e864c01b3395ba9568b061a  # !568
-  git cherry-pick -n a20a0d7a4563366d2cd29c32a1b95a59121e7bf5  # !283
-  git apply -3 ../0001-Remove-GLX-threaded-swap-wait.patch     # !602
-  git apply -3 ../0001-Add-point-polygon-testing-API.patch     # !189
-  git apply -3 ../0002-Geometric-OpenGL-less-picking.patch     # !189
-
-  # fix background corruption on nvidia
-  git cherry-pick -n a5265365dd268e15a461a58000a10b122d0bccba  # !600
-
-  # required to build gala
-  git cherry-pick -n bd7704f9e17e9554ad663386ef4fce1e16a56f08  # !640
+  #git cherry-pick -n a20a0d7a4563366d2cd29c32a1b95a59121e7bf5  # !283
 }
 
 build() {



More information about the arch-commits mailing list