macos: add readonly IOSurfaceLock helper
authorChristian Hergert <christian@hergert.me>
Mon, 28 Feb 2022 09:29:22 +0000 (01:29 -0800)
committerChristian Hergert <chergert@redhat.com>
Wed, 16 Mar 2022 19:24:11 +0000 (12:24 -0700)
This can be used to lock a surface for reading to avoid causing the
surface contents to be invalidated. This is needed when reading back from
a front-buffer to the back-buffer as is needed when using Cairo surfaces
to implement something similar to BufferAge.

gdk/macos/gdkmacosbuffer-private.h
gdk/macos/gdkmacosbuffer.c

index 6be201147c90dabdbf286c3d674b024b307786dc..4b446a72124c102c7065961c4ef78525baa34072 100644 (file)
@@ -41,6 +41,8 @@ GdkMacosBuffer       *_gdk_macos_buffer_new              (int              width
 IOSurfaceRef          _gdk_macos_buffer_get_native       (GdkMacosBuffer  *self);
 void                  _gdk_macos_buffer_lock             (GdkMacosBuffer  *self);
 void                  _gdk_macos_buffer_unlock           (GdkMacosBuffer  *self);
+void                  _gdk_macos_buffer_read_lock        (GdkMacosBuffer  *self);
+void                  _gdk_macos_buffer_read_unlock      (GdkMacosBuffer  *self);
 guint                 _gdk_macos_buffer_get_width        (GdkMacosBuffer  *self);
 guint                 _gdk_macos_buffer_get_height       (GdkMacosBuffer  *self);
 guint                 _gdk_macos_buffer_get_stride       (GdkMacosBuffer  *self);
index ac99302ee45f8ec81b12f64354e4c0cd02b55062..46a050446126e8a96bdebfbe4c745ba1c14c84a4 100644 (file)
@@ -192,6 +192,45 @@ _gdk_macos_buffer_unlock (GdkMacosBuffer *self)
   IOSurfaceUnlock (self->surface, 0, NULL);
 }
 
+/**
+ * _gdk_macos_buffer_lock_readonly:
+ *
+ * Like _gdk_macos_buffer_lock() but uses the read-only flag to
+ * indicate we are not interested in retrieving the updates from
+ * the GPU before modifying the CPU-side cache.
+ *
+ * Must be used with _gdk_macos_buffer_unlock_readonly().
+ */
+void
+_gdk_macos_buffer_read_lock (GdkMacosBuffer *self)
+{
+  kern_return_t ret;
+
+  g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
+  g_return_if_fail (self->lock_count == 0);
+
+  self->lock_count++;
+
+  ret = IOSurfaceLock (self->surface, kIOSurfaceLockReadOnly, NULL);
+
+  g_return_if_fail (ret == KERN_SUCCESS);
+}
+
+void
+_gdk_macos_buffer_read_unlock (GdkMacosBuffer *self)
+{
+  kern_return_t ret;
+
+  g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
+  g_return_if_fail (self->lock_count == 1);
+
+  self->lock_count--;
+
+  ret = IOSurfaceUnlock (self->surface, kIOSurfaceLockReadOnly, NULL);
+
+  g_return_if_fail (ret == KERN_SUCCESS);
+}
+
 guint
 _gdk_macos_buffer_get_width (GdkMacosBuffer *self)
 {