[mutter] wayland/cursor: Keep a private use count and reference to active buffer



commit 7173937a7d5f0bc0fdb1a980bf40f58e2aee6b96
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Mar 16 14:58:16 2016 +0800

    wayland/cursor: Keep a private use count and reference to active buffer
    
    In order for the native cursor renderer to be able to create a hw
    cursor in response to wl_pointer.set_cursor(), keep a private use-count
    and reference to the active buffer, stopping it from being released
    until it is consumed, replaced, or the surface is destroyed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=762828

 src/wayland/meta-wayland-pointer.c |   50 +++++++++++++++++++++++++++++++++++-
 1 files changed, 49 insertions(+), 1 deletions(-)
---
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index 173d7d0..aad9aaa 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -80,6 +80,8 @@ struct _MetaWaylandSurfaceRoleCursor
   int hot_x;
   int hot_y;
   MetaCursorSprite *cursor_sprite;
+
+  MetaWaylandBuffer *buffer;
 };
 
 G_DEFINE_TYPE (MetaWaylandSurfaceRoleCursor,
@@ -977,14 +979,18 @@ update_cursor_sprite_texture (MetaWaylandSurface *surface)
                                       cursor_role->hot_x * surface->scale,
                                       cursor_role->hot_y * surface->scale);
 
-      if (surface->buffer_ref.use_count > 0)
+      if (cursor_role->buffer)
         {
           struct wl_resource *buffer_resource;
 
+          g_assert (cursor_role->buffer == buffer);
           buffer_resource = buffer->resource;
           meta_cursor_renderer_realize_cursor_from_wl_buffer (cursor_renderer,
                                                               cursor_sprite,
                                                               buffer_resource);
+
+          meta_wayland_surface_unref_buffer_use_count (surface);
+          g_clear_object (&cursor_role->buffer);
         }
     }
   else
@@ -1260,18 +1266,53 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer)
 static void
 cursor_surface_role_assigned (MetaWaylandSurfaceRole *surface_role)
 {
+  MetaWaylandSurfaceRoleCursor *cursor_role =
+    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (surface_role);
+  MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+
+  if (buffer)
+    {
+      g_set_object (&cursor_role->buffer, buffer);
+      meta_wayland_surface_ref_buffer_use_count (surface);
+    }
 
   meta_wayland_surface_queue_pending_frame_callbacks (surface);
 }
 
 static void
+cursor_surface_role_pre_commit (MetaWaylandSurfaceRole  *surface_role,
+                                MetaWaylandPendingState *pending)
+{
+  MetaWaylandSurfaceRoleCursor *cursor_role =
+    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
+  MetaWaylandSurface *surface =
+    meta_wayland_surface_role_get_surface (surface_role);
+
+  if (pending->newly_attached && cursor_role->buffer)
+    {
+      meta_wayland_surface_unref_buffer_use_count (surface);
+      g_clear_object (&cursor_role->buffer);
+    }
+}
+
+static void
 cursor_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
                             MetaWaylandPendingState *pending)
 {
+  MetaWaylandSurfaceRoleCursor *cursor_role =
+    META_WAYLAND_SURFACE_ROLE_CURSOR (surface_role);
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (surface_role);
+  MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
+
+  if (pending->newly_attached)
+    {
+      g_set_object (&cursor_role->buffer, buffer);
+      if (cursor_role->buffer)
+        meta_wayland_surface_ref_buffer_use_count (surface);
+    }
 
   meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
 
@@ -1326,6 +1367,12 @@ cursor_surface_role_dispose (GObject *object)
 
   g_clear_object (&cursor_role->cursor_sprite);
 
+  if (cursor_role->buffer)
+    {
+      meta_wayland_surface_unref_buffer_use_count (surface);
+      g_clear_object (&cursor_role->buffer);
+    }
+
   G_OBJECT_CLASS (meta_wayland_surface_role_cursor_parent_class)->dispose (object);
 }
 
@@ -1342,6 +1389,7 @@ meta_wayland_surface_role_cursor_class_init (MetaWaylandSurfaceRoleCursorClass *
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   surface_role_class->assigned = cursor_surface_role_assigned;
+  surface_role_class->pre_commit = cursor_surface_role_pre_commit;
   surface_role_class->commit = cursor_surface_role_commit;
   surface_role_class->is_on_output = cursor_surface_role_is_on_output;
 


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