[gtk/wip/chergert/gdk-macos-gl-renderer] macos: setup native window and view for accelerated GL



commit 92ea076fa3835e2a581723883b60b6ec44f4e145
Author: Christian Hergert <chergert redhat com>
Date:   Tue Oct 27 15:54:25 2020 -0700

    macos: setup native window and view for accelerated GL
    
    When we don't want to render to the surface, we need to still setup
    a view and window for rendering to so that we get accelerated
    rendering.

 gdk/macos/gdkmacosglcontext-private.h |  3 +-
 gdk/macos/gdkmacosglcontext.c         | 86 ++++++++++++++++++++---------------
 2 files changed, 52 insertions(+), 37 deletions(-)
---
diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h
index 6a28262118..722e74cde1 100644
--- a/gdk/macos/gdkmacosglcontext-private.h
+++ b/gdk/macos/gdkmacosglcontext-private.h
@@ -41,7 +41,8 @@ struct _GdkMacosGLContext
   NSOpenGLContext *gl_context;
   G_GNUC_END_IGNORE_DEPRECATIONS
 
-  NSView *attached;
+  NSWindow *dummy_window;
+  NSView *dummy_view;
 
   guint is_attached : 1;
 };
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index 240c102bb3..15c36b6c26 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -114,21 +114,6 @@ gdk_macos_gl_context_real_realize (GdkGLContext  *context,
   if (!self->is_attached && shared != NULL)
     nsview = ensure_gl_view (self);
 
-  /* This can be called with a few modes:
-   * 
-   * 1) GL Paint Context => is_attached=TRUE is used to read back pixels
-   *    into Cairo using gdk_cairo_draw_from_gl().
-   *
-   * 2) GL Context => is_attached=(FALSE) shared=(Paint GL Context)
-   *    This is used by the GskGLRenderer for rendering to the surface.
-   *    But it is also used by GtkGLArea to create a context for the view.
-   *    which should not be rendered to the surface.
-   *
-   * 3) GL Context => is_attached=(FALSE) shared=NULL
-   *    This is used for the "shared data" context for things like glyph
-   *    and icon caches.
-   */
-
   if (shared != NULL)
     {
       if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
@@ -160,17 +145,17 @@ gdk_macos_gl_context_real_realize (GdkGLContext  *context,
     {
       NSRect frame = NSMakeRect (0, 0, 1, 1);
 
-      self->attached = [[GdkMacosGLView alloc] initWithFrame:frame pixelFormat:pixelFormat];
-      [(GdkMacosGLView *)self->attached setOpenGLContext:gl_context];
-    }
-  else
-    {
-      g_assert (GDK_IS_MACOS_GL_VIEW (nsview));
-
-      [(GdkMacosGLView *)nsview setOpenGLContext:gl_context];
-      [gl_context setView:nsview];
+      self->dummy_window = [[NSWindow alloc] initWithContentRect:frame
+                                                       styleMask:0
+                                                         backing:NSBackingStoreBuffered
+                                                           defer:NO
+                                                          screen:nil];
+      self->dummy_view = [[NSView alloc] initWithFrame:frame];
+      [self->dummy_window setContentView:self->dummy_view];
+      [gl_context setView:self->dummy_view];
     }
 
+  [gl_context update];
   [gl_context makeCurrentContext];
 
   GDK_NOTE (OPENGL,
@@ -185,9 +170,23 @@ static void
 gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
                                   cairo_region_t *painted)
 {
-  g_assert (GDK_IS_MACOS_GL_CONTEXT (context));
+  GdkMacosGLContext *self = (GdkMacosGLContext *)context;
+
+  g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
 
   GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->begin_frame (context, painted);
+
+  if (!self->is_attached)
+    {
+      GdkMacosSurface *surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (context));
+      NSView *nsview = _gdk_macos_surface_get_view (surface);
+
+      g_assert (self->gl_context != NULL);
+      g_assert (GDK_IS_MACOS_GL_VIEW (nsview));
+
+      [(GdkMacosGLView *)nsview setOpenGLContext:self->gl_context];
+      [self->gl_context setView:nsview];
+    }
 }
 
 static void
@@ -201,15 +200,16 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
   g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
   g_assert (self->gl_context != nil);
 
+  surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (context));
+  nsview = self->dummy_view ?
+           self->dummy_view :
+           _gdk_macos_surface_get_view (surface);
+
   GDK_DRAW_CONTEXT_CLASS (gdk_macos_gl_context_parent_class)->end_frame (context, painted);
 
-  [self->gl_context flushBuffer];
 
-  surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (context));
-  nsview = _gdk_macos_surface_get_view (surface);
 
-  if (nsview == [self->gl_context view])
-    [(GdkMacosGLView *)nsview invalidateRegion:painted];
+  [self->gl_context flushBuffer];
 }
 
 static void
@@ -220,13 +220,18 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
 
   g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
 
+  if (self->gl_context == nil)
+    return;
+
   surface = gdk_draw_context_get_surface (draw_context);
 
-  if (self->attached)
+  if (self->dummy_view != NULL)
     {
-      NSRect contentRect = NSMakeRect (0, 0, surface->width, surface->height);
-      [self->attached setFrame:contentRect];
+      GLint vals[2] = { surface->width, surface->height };
+      [self->gl_context setValues:vals forParameter:NSOpenGLContextParameterSurfaceBackingSize];
     }
+
+  [self->gl_context update];
 }
 
 static void
@@ -234,14 +239,23 @@ gdk_macos_gl_context_dispose (GObject *gobject)
 {
   GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (gobject);
 
-  if (self->attached != nil)
+  if (self->dummy_view != nil)
     {
-      NSView *nsview = g_steal_pointer (&self->attached);
+      NSView *nsview = g_steal_pointer (&self->dummy_view);
+
+      if (GDK_IS_MACOS_GL_VIEW (nsview))
+        [(GdkMacosGLView *)nsview setOpenGLContext:nil];
 
-      [(GdkMacosGLView *)nsview setOpenGLContext:nil];
       [nsview release];
     }
 
+  if (self->dummy_window != nil)
+    {
+      NSWindow *nswindow = g_steal_pointer (&self->dummy_window);
+
+      [nswindow release];
+    }
+
   if (self->gl_context != nil)
     {
       NSOpenGLContext *gl_context = g_steal_pointer (&self->gl_context);


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