[gtk/wip/chergert/macos-iosurface] macos: start on abstraction for IOSurface




commit 28c59ddce90da4df967e28c4b8663b78250690c2
Author: Christian Hergert <christian hergert me>
Date:   Fri Feb 4 17:24:13 2022 -0800

    macos: start on abstraction for IOSurface
    
    The goal here ultimately is to determine if we can use IOSurface to
    render to instead of directly using NSOpenGLContext with the ultimate
    hope that we could tile NSView in the NSWindow for some opaque and
    some transparent regions.
    
    If not, we still might be able to use it for doing tiled rendering.

 gdk/macos/gdkmacosbuffer-private.h  |  40 ++++++++++
 gdk/macos/gdkmacosbuffer.c          | 142 ++++++++++++++++++++++++++++++++++++
 gdk/macos/gdkmacossurface-private.h |   4 +
 gdk/macos/gdkmacossurface.c         |  24 +++++-
 gdk/macos/meson.build               |   2 +
 5 files changed, 211 insertions(+), 1 deletion(-)
---
diff --git a/gdk/macos/gdkmacosbuffer-private.h b/gdk/macos/gdkmacosbuffer-private.h
new file mode 100644
index 0000000000..a7663d8556
--- /dev/null
+++ b/gdk/macos/gdkmacosbuffer-private.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef __GDK_MACOS_BUFFER_PRIVATE_H__
+#define __GDK_MACOS_BUFFER_PRIVATE_H__
+
+#include "gdkmacosdisplay.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_MACOS_BUFFER (gdk_macos_buffer_get_type())
+
+G_DECLARE_FINAL_TYPE (GdkMacosBuffer, gdk_macos_buffer, GDK, MACOS_BUFFER, GObject)
+
+GdkMacosBuffer *_gdk_macos_buffer_new    (GdkMacosDisplay *display,
+                                          int              width,
+                                          int              height,
+                                          int              bytes_per_pixel);
+void            _gdk_macos_buffer_lock   (GdkMacosBuffer *self);
+void            _gdk_macos_buffer_unlock (GdkMacosBuffer *self);
+
+G_END_DECLS
+
+#endif /* __GDK_MACOS_BUFFER_PRIVATE_H__ */
diff --git a/gdk/macos/gdkmacosbuffer.c b/gdk/macos/gdkmacosbuffer.c
new file mode 100644
index 0000000000..8584478c24
--- /dev/null
+++ b/gdk/macos/gdkmacosbuffer.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <IOSurface/IOSurface.h>
+#include <Foundation/Foundation.h>
+#include <OpenGL/CGLIOSurface.h>
+#include <QuartzCore/QuartzCore.h>
+
+#include "gdkmacosbuffer-private.h"
+
+struct _GdkMacosBuffer
+{
+  GObject parent_instance;
+  IOSurfaceRef surface;
+};
+
+G_DEFINE_TYPE (GdkMacosBuffer, gdk_macos_buffer, G_TYPE_OBJECT)
+
+static void
+gdk_macos_buffer_dispose (GObject *object)
+{
+  GdkMacosBuffer *self = (GdkMacosBuffer *)object;
+  
+  if (self->surface != NULL)
+    {
+      CFRelease (self->surface);
+      self->surface = NULL;
+    }
+  
+  G_OBJECT_CLASS (gdk_macos_buffer_parent_class)->dispose (object);
+}
+
+static void
+gdk_macos_buffer_class_init (GdkMacosBufferClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  object_class->dispose = gdk_macos_buffer_dispose;
+}
+
+static void
+gdk_macos_buffer_init (GdkMacosBuffer *self)
+{
+}
+
+static void
+add_int (CFMutableDictionaryRef dict,
+         const CFStringRef      key,
+         int                    value)
+{
+  CFNumberRef number = CFNumberCreate (NULL, kCFNumberIntType, &value);
+  CFDictionaryAddValue (dict, key, number);
+  CFRelease (number);
+}
+
+static IOSurfaceRef
+create_surface (int width,
+                int height,
+                int bytes_per_pixel)
+{
+  CFMutableDictionaryRef props;
+  IOSurfaceRef ret;
+  size_t bytes_per_row;
+  size_t total_bytes;
+
+  props = CFDictionaryCreateMutable (kCFAllocatorDefault,
+                                     16,
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+  if (props == NULL)
+    return NULL;
+
+  add_int (props, kIOSurfaceWidth, width);
+  add_int (props, kIOSurfaceHeight, height);
+  add_int (props, kIOSurfaceBytesPerElement, bytes_per_pixel);
+  
+  bytes_per_row = IOSurfaceAlignProperty (kIOSurfaceBytesPerRow, width * bytes_per_pixel);
+  add_int (props, kIOSurfaceBytesPerRow, bytes_per_row);
+  
+  total_bytes = IOSurfaceAlignProperty (kIOSurfaceAllocSize, height * bytes_per_row);
+  add_int (props, kIOSurfaceAllocSize, total_bytes);
+  
+  add_int (props, kIOSurfacePixelFormat, (int)kCVPixelFormatType_32BGRA);
+
+  ret = IOSurfaceCreate (props);
+
+  CFRelease (props);
+
+  return ret;
+}
+
+GdkMacosBuffer *
+_gdk_macos_buffer_new (GdkMacosDisplay *display,
+                       int              width,
+                       int              height,
+                       int              bytes_per_pixel)
+{
+  GdkMacosBuffer *self;
+
+  g_return_val_if_fail (GDK_IS_MACOS_DISPLAY (display), NULL);
+
+  self = g_object_new (GDK_TYPE_MACOS_BUFFER, NULL);
+  self->surface = create_surface (width, height, bytes_per_pixel);
+
+  if (self->surface == NULL)
+    {
+      g_object_unref (self);
+      return NULL;
+    }
+
+  return self;
+}
+
+void
+_gdk_macos_buffer_lock (GdkMacosBuffer *self)
+{
+  g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
+}
+
+void
+_gdk_macos_buffer_unlock (GdkMacosBuffer *self)
+{
+  g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
+}
diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h
index ccb8a83179..76cf853c01 100644
--- a/gdk/macos/gdkmacossurface-private.h
+++ b/gdk/macos/gdkmacossurface-private.h
@@ -25,6 +25,7 @@
 
 #include "gdksurfaceprivate.h"
 
+#include "gdkmacosbuffer-private.h"
 #include "gdkmacosdisplay.h"
 #include "gdkmacossurface.h"
 
@@ -40,6 +41,9 @@ struct _GdkMacosSurface
 {
   GdkSurface parent_instance;
 
+  GdkMacosBuffer *back;
+  GdkMacosBuffer *front;
+
   GList main;
   GList sorted;
   GList frame;
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index c5cf05edf8..26e73faad4 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -861,6 +861,25 @@ _gdk_macos_surface_synthesize_null_key (GdkMacosSurface *self)
   _gdk_event_queue_append (display, event);
 }
 
+static void
+gdk_macos_surface_update_buffers (GdkMacosSurface *self)
+{
+  GdkMacosBuffer *front;
+  GdkDisplay *display;
+
+  g_assert (GDK_IS_MACOS_SURFACE (self));
+
+  display = gdk_surface_get_display (GDK_SURFACE (self));
+  front = _gdk_macos_buffer_new (GDK_MACOS_DISPLAY (display),
+                                 GDK_SURFACE (self)->width,
+                                 GDK_SURFACE (self)->height,
+                                 4);
+
+  g_print ("Front: %p\n", front);
+
+  g_object_unref (front);
+}
+
 void
 _gdk_macos_surface_move (GdkMacosSurface *self,
                          int              x,
@@ -927,7 +946,10 @@ _gdk_macos_surface_move_resize (GdkMacosSurface *self,
   [self->window setFrame:frame_rect display:YES];
 
   if (size_changed)
-    gdk_surface_invalidate_rect (surface, NULL);
+    {
+      gdk_macos_surface_update_buffers (self);
+      gdk_surface_invalidate_rect (surface, NULL);
+    }
 }
 
 gboolean
diff --git a/gdk/macos/meson.build b/gdk/macos/meson.build
index 3a10dbf944..e6e8dd798f 100644
--- a/gdk/macos/meson.build
+++ b/gdk/macos/meson.build
@@ -2,6 +2,7 @@ gdk_macos_sources = files([
   'edgesnapping.c',
 
   'gdkdisplaylinksource.c',
+  'gdkmacosbuffer.c',
   'gdkmacoscairocontext.c',
   'gdkmacosclipboard.c',
   'gdkmacoscursor.c',
@@ -46,6 +47,7 @@ gdk_macos_frameworks = [
   'CoreVideo',
   'CoreServices',
   'Foundation',
+  'IOSurface',
   'OpenGL',
   'QuartzCore',
 ]


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