[mutter] wayland: change accessible boolean to use_count counter



commit bed82427c6b8d00ec95434ef1006f08a6722ceae
Author: Ray Strode <rstrode redhat com>
Date:   Thu Feb 18 10:33:50 2016 -0500

    wayland: change accessible boolean to use_count counter
    
    Since a buffer can be used by multiple surfaces at once,
    we need to release the buffer only after all surfaces
    are finished with it.  Currently we track whether or
    not to release the buffer based on the accessible boolean.
    This commit changes it to a counter to accomodate multiple
    users.
    
    Also, each surface needs to know whether not it is done with
    the buffer, so this commit adds a buffer_used boolean to the
    surface state.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=761613

 src/wayland/meta-wayland-buffer.c  |   30 +++++++++++++-----------------
 src/wayland/meta-wayland-buffer.h  |    7 +++----
 src/wayland/meta-wayland-surface.c |   27 ++++++++++++++++++++++++---
 src/wayland/meta-wayland-surface.h |    1 +
 4 files changed, 41 insertions(+), 24 deletions(-)
---
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index bb0e8d2..11db632 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -51,32 +51,30 @@ void
 meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
 {
   buffer->ref_count--;
+
   if (buffer->ref_count == 0)
     {
-      g_clear_pointer (&buffer->texture, cogl_object_unref);
+      g_warn_if_fail (buffer->use_count == 0);
 
-      if (buffer->accessible)
-        meta_wayland_buffer_release_control (buffer);
+      g_clear_pointer (&buffer->texture, cogl_object_unref);
     }
 }
 
 void
-meta_wayland_buffer_take_control (MetaWaylandBuffer *buffer)
+meta_wayland_buffer_ref_use_count (MetaWaylandBuffer *buffer)
 {
-  if (buffer->accessible)
-    meta_fatal ("buffer control taken twice");
-
-  buffer->accessible = TRUE;
+  buffer->use_count++;
 }
 
 void
-meta_wayland_buffer_release_control (MetaWaylandBuffer *buffer)
+meta_wayland_buffer_unref_use_count (MetaWaylandBuffer *buffer)
 {
-  if (!buffer->accessible)
-    meta_fatal ("buffer released when not in control");
+  g_return_if_fail (buffer->use_count != 0);
+
+  buffer->use_count--;
 
-  wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
-  buffer->accessible = FALSE;
+  if (buffer->use_count == 0)
+    wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
 }
 
 MetaWaylandBuffer *
@@ -114,8 +112,7 @@ meta_wayland_buffer_ensure_texture (MetaWaylandBuffer *buffer)
   CoglTexture *texture;
   struct wl_shm_buffer *shm_buffer;
 
-  if (!buffer->accessible)
-    meta_warning ("attempted to process damage on uncommitted buffer");
+  g_return_val_if_fail (buffer->use_count != 0, NULL);
 
   if (buffer->texture)
     goto out;
@@ -150,8 +147,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
 {
   struct wl_shm_buffer *shm_buffer;
 
-  if (!buffer->accessible)
-    meta_warning ("attempted to process damage on uncommitted buffer");
+  g_return_if_fail (buffer->use_count != 0);
 
   shm_buffer = wl_shm_buffer_get (buffer->resource);
 
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
index 9f6a5bf..fda534b 100644
--- a/src/wayland/meta-wayland-buffer.h
+++ b/src/wayland/meta-wayland-buffer.h
@@ -39,15 +39,14 @@ struct _MetaWaylandBuffer
 
   CoglTexture *texture;
   uint32_t ref_count;
-
-  uint32_t accessible : 1;
+  uint32_t use_count;
 };
 
 MetaWaylandBuffer *     meta_wayland_buffer_from_resource       (struct wl_resource    *resource);
 void                    meta_wayland_buffer_ref                 (MetaWaylandBuffer     *buffer);
 void                    meta_wayland_buffer_unref               (MetaWaylandBuffer     *buffer);
-void                    meta_wayland_buffer_take_control        (MetaWaylandBuffer     *buffer);
-void                    meta_wayland_buffer_release_control     (MetaWaylandBuffer     *buffer);
+void                    meta_wayland_buffer_ref_use_count       (MetaWaylandBuffer     *buffer);
+void                    meta_wayland_buffer_unref_use_count     (MetaWaylandBuffer     *buffer);
 CoglTexture *           meta_wayland_buffer_ensure_texture      (MetaWaylandBuffer     *buffer);
 void                    meta_wayland_buffer_process_damage      (MetaWaylandBuffer     *buffer,
                                                                  cairo_region_t        *region);
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index fc884d9..e54da49 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -175,6 +175,25 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
 }
 
 static void
+surface_use_buffer (MetaWaylandSurface *surface)
+{
+  g_return_if_fail (!surface->using_buffer);
+
+  meta_wayland_buffer_ref_use_count (surface->buffer);
+  surface->using_buffer = TRUE;
+}
+
+static void
+surface_stop_using_buffer (MetaWaylandSurface *surface)
+{
+  if (!surface->using_buffer)
+    return;
+
+  meta_wayland_buffer_unref_use_count (surface->buffer);
+  surface->using_buffer = FALSE;
+}
+
+static void
 surface_set_buffer (MetaWaylandSurface *surface,
                     MetaWaylandBuffer  *buffer)
 {
@@ -184,6 +203,8 @@ surface_set_buffer (MetaWaylandSurface *surface,
   if (surface->buffer)
     {
       wl_list_remove (&surface->buffer_destroy_listener.link);
+
+      surface_stop_using_buffer (surface);
       meta_wayland_buffer_unref (surface->buffer);
     }
 
@@ -657,11 +678,11 @@ apply_pending_state (MetaWaylandSurface      *surface,
 
       surface_set_buffer (surface, pending->buffer);
 
-      if (pending->buffer)
+      if (pending->buffer && !surface->using_buffer)
         {
           struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (pending->buffer->resource);
 
-          meta_wayland_buffer_take_control (pending->buffer);
+          surface_use_buffer (surface);
           CoglTexture *texture = meta_wayland_buffer_ensure_texture (pending->buffer);
           meta_surface_actor_wayland_set_texture (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor), 
texture);
 
@@ -679,7 +700,7 @@ apply_pending_state (MetaWaylandSurface      *surface,
     surface_process_damage (surface, pending->damage);
 
   if (release_new_buffer)
-    meta_wayland_buffer_release_control (pending->buffer);
+    surface_stop_using_buffer (surface);
 
   surface->offset_x += pending->dx;
   surface->offset_y += pending->dy;
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 7200bbf..4a2c244 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -152,6 +152,7 @@ struct _MetaWaylandSurface
   MetaWaylandSurfaceRole *role;
   MetaWindow *window;
   MetaWaylandBuffer *buffer;
+  gboolean using_buffer;
   struct wl_listener buffer_destroy_listener;
   cairo_region_t *input_region;
   cairo_region_t *opaque_region;


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