[gtk/wip/chergert/gdk-macos-gl-renderer: 10/26] macos: wip on making GL renderer more compliant
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/gdk-macos-gl-renderer: 10/26] macos: wip on making GL renderer more compliant
- Date: Thu, 29 Oct 2020 00:12:12 +0000 (UTC)
commit 5c5bcb7b6ff00f904cd44ffbc52de70fd7726222
Author: Christian Hergert <chergert redhat com>
Date: Thu Oct 22 16:47:40 2020 -0700
macos: wip on making GL renderer more compliant
gdk/macos/GdkMacosGLView.c | 36 +++---
gdk/macos/gdkmacosglcontext-private.h | 12 +-
gdk/macos/gdkmacosglcontext.c | 215 +++++++++++++++++++++-------------
3 files changed, 161 insertions(+), 102 deletions(-)
---
diff --git a/gdk/macos/GdkMacosGLView.c b/gdk/macos/GdkMacosGLView.c
index 4485bacca5..cab8c66638 100644
--- a/gdk/macos/GdkMacosGLView.c
+++ b/gdk/macos/GdkMacosGLView.c
@@ -35,11 +35,17 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+(NSOpenGLPixelFormat *)defaultPixelFormat
{
static const NSOpenGLPixelFormatAttribute attrs[] = {
- NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core,
+ NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAColorSize, 24,
+ NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 32,
NSOpenGLPFAStencilSize, 8,
+ NSOpenGLPFAAllowOfflineRenderers,
+ NSOpenGLPFAMultisample,
+ NSOpenGLPFASampleBuffers, 1,
+ NSOpenGLPFASamples, 8,
(NSOpenGLPixelFormatAttribute)nil
};
@@ -106,19 +112,6 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
[context setView: self];
}
--(void)viewDidMoveToWindow
-{
- [super viewDidMoveToWindow];
-
- if ([self window] == nil)
- {
- [[self openGLContext] clearDrawable];
- return;
- }
-
- [[self openGLContext] setView: self];
-}
-
-(void)update
{
[[self openGLContext] update];
@@ -130,13 +123,24 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-(void)clearGLContext
{
+ if (_openGLContext != nil)
+ [_openGLContext clearDrawable];
+
_openGLContext = nil;
}
-(void)setOpenGLContext:(NSOpenGLContext*)context
{
- [context setView:self];
- _openGLContext = context;
+ if (_openGLContext != context)
+ {
+ if (_openGLContext != nil)
+ [_openGLContext clearDrawable];
+
+ _openGLContext = context;
+
+ if (_openGLContext != nil)
+ [_openGLContext setView:self];
+ }
}
-(NSOpenGLContext *)openGLContext
diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h
index a7417026fb..6a28262118 100644
--- a/gdk/macos/gdkmacosglcontext-private.h
+++ b/gdk/macos/gdkmacosglcontext-private.h
@@ -37,13 +37,13 @@ struct _GdkMacosGLContext
{
GdkGLContext parent_instance;
- guint is_attached : 1;
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ NSOpenGLContext *gl_context;
+ G_GNUC_END_IGNORE_DEPRECATIONS
+
+ NSView *attached;
- struct {
- int width;
- int height;
- guint needed : 1;
- } resize;
+ guint is_attached : 1;
};
struct _GdkMacosGLContextClass
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index d56e0b435f..e5ab1e2fa2 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -39,16 +39,9 @@ static NSOpenGLContext *
get_ns_open_gl_context (GdkMacosGLContext *self,
GError **error)
{
- NSOpenGLContext *gl_context = nil;
- GdkSurface *surface;
- NSView *nsview;
-
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
- if (!(surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self))) ||
- !(nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface))) ||
- !GDK_IS_MACOS_GL_VIEW (nsview) ||
- !(gl_context = [(GdkMacosGLView *)nsview openGLContext]))
+ if (self->gl_context == nil)
{
g_set_error_literal (error,
GDK_GL_ERROR,
@@ -57,7 +50,36 @@ get_ns_open_gl_context (GdkMacosGLContext *self,
return NULL;
}
- return gl_context;
+ return self->gl_context;
+}
+
+static NSView *
+ensure_gl_view (GdkMacosGLContext *self)
+{
+ GdkMacosSurface *surface;
+ NSWindow *nswindow;
+ NSView *nsview;
+
+ g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
+
+ surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self)));
+ nsview = _gdk_macos_surface_get_view (surface);
+ nswindow = _gdk_macos_surface_get_native (surface);
+
+ if (!GDK_IS_MACOS_GL_VIEW (nsview))
+ {
+ NSRect frame;
+
+ frame = [[nswindow contentView] bounds];
+ nsview = [[GdkMacosGLView alloc] initWithFrame:frame pixelFormat:pixelFormat];
+ [nsview setWantsBestResolutionOpenGLSurface:YES];
+ [nsview setPostsFrameChangedNotifications: YES];
+ [nsview setNeedsDisplay:YES];
+ [nswindow setContentView:nsview];
+ [nsview release];
+ }
+
+ return [nswindow contentView];
}
static gboolean
@@ -67,71 +89,94 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
GdkSurface *surface;
NSView *nsview;
+ NSOpenGLContext *shared_gl_context = nil;
+ NSOpenGLContext *gl_context;
+ GdkGLContext *shared;
+ GdkGLContext *shared_data;
+ GLint sync_to_framerate = 1;
+ GLint opaque = 0;
+ GLint validate = 0;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
+ if (self->gl_context != nil)
+ return TRUE;
+
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
nsview = _gdk_macos_surface_get_view (GDK_MACOS_SURFACE (surface));
-
- if (!GDK_IS_MACOS_GL_VIEW (nsview))
+ shared = gdk_gl_context_get_shared_context (context);
+ shared_data = gdk_surface_get_shared_data_gl_context (surface);
+
+ /* If we are not attached and have a shared context, then we are
+ * trying to draw to our NSView (which must be a GL view). Ensure
+ * that we have that up front to save some checking later.
+ */
+ 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)
{
- NSOpenGLContext *shared_gl_context = nil;
- NSOpenGLContext *gl_context;
- GdkMacosGLView *gl_view;
- GdkGLContext *shared;
- NSWindow *nswindow;
- NSRect contentRect;
- GLint sync_to_framerate = 1;
- GLint opaque = 0;
-
- if ((shared = gdk_gl_context_get_shared_context (context)))
- {
- if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
- return FALSE;
- }
-
- if (shared == NULL)
- {
- GdkGLContext *shared_data = gdk_surface_get_shared_data_gl_context (surface);
+ if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
+ return FALSE;
+ }
+ else
+ {
+ if (shared_data != NULL)
+ shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), NULL);
+ }
- if (shared_data != NULL)
- shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), NULL);
- }
+ gl_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
+ shareContext:shared_gl_context];
- nswindow = _gdk_macos_surface_get_native (GDK_MACOS_SURFACE (surface));
- gl_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
- shareContext:shared_gl_context];
+ if (gl_context == nil)
+ {
+ g_set_error_literal (error,
+ GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ "Failed to create NSOpenGLContext");
+ return FALSE;
+ }
- if (gl_context == nil)
- {
- g_set_error_literal (error,
- GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- "Failed to create NSOpenGLContext");
- return FALSE;
- }
+ [gl_context setValues:&sync_to_framerate forParameter:NSOpenGLCPSwapInterval];
+ [gl_context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
+ [gl_context setValues:&validate forParameter:NSOpenGLContextParameterStateValidation];
- [gl_context setValues:&sync_to_framerate forParameter:NSOpenGLCPSwapInterval];
- [gl_context setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
+ if (self->is_attached || shared == NULL)
+ {
+ NSRect frame = NSMakeRect (0, 0, 1, 1);
- GDK_NOTE (OPENGL,
- g_print ("Created NSOpenGLContext[%p]\n", gl_context));
+ self->attached = [[GdkMacosGLView alloc] initWithFrame:frame pixelFormat:pixelFormat];
+ [(GdkMacosGLView *)self->attached setOpenGLContext:gl_context];
+ }
+ else
+ {
+ g_assert (GDK_IS_MACOS_GL_VIEW (nsview));
- contentRect = [[nswindow contentView] bounds];
- gl_view = [[GdkMacosGLView alloc] initWithFrame:contentRect
- pixelFormat:pixelFormat];
- [nswindow setContentView:gl_view];
- [gl_view setOpenGLContext:gl_context];
- [gl_view setWantsBestResolutionOpenGLSurface:YES];
- [gl_view setPostsFrameChangedNotifications: YES];
- [gl_view setNeedsDisplay:YES];
+ [(GdkMacosGLView *)nsview setOpenGLContext:gl_context];
+ [gl_context setView:nsview];
+ }
- [gl_context makeCurrentContext];
+ [gl_context makeCurrentContext];
- [gl_view release];
- }
+ GDK_NOTE (OPENGL,
+ g_print ("Created NSOpenGLContext[%p]\n", gl_context));
- g_assert (get_ns_open_gl_context (self, NULL) != NULL);
+ self->gl_context = g_steal_pointer (&gl_context);
return TRUE;
}
@@ -150,21 +195,19 @@ gdk_macos_gl_context_end_frame (GdkDrawContext *context,
cairo_region_t *painted)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
- NSOpenGLContext *gl_context;
+ GdkMacosSurface *surface;
+ NSView *nsview;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
+ g_assert (self->gl_context != nil);
- if ((gl_context = get_ns_open_gl_context (self, NULL)))
- {
- GdkMacosSurface *surface;
- NSView *nsview;
+ [self->gl_context flushBuffer];
- surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (context));
- nsview = _gdk_macos_surface_get_view (surface);
- [(GdkMacosGLView *)nsview invalidateRegion:painted];
+ surface = GDK_MACOS_SURFACE (gdk_draw_context_get_surface (context));
+ nsview = _gdk_macos_surface_get_view (surface);
- [gl_context flushBuffer];
- }
+ if (nsview == [self->gl_context view])
+ [(GdkMacosGLView *)nsview invalidateRegion:painted];
}
static void
@@ -177,19 +220,33 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
surface = gdk_draw_context_get_surface (draw_context);
- self->resize.needed = TRUE;
- self->resize.width = surface->width;
- self->resize.height = surface->height;
+ if (self->attached)
+ {
+ NSRect contentRect = NSMakeRect (0, 0, surface->width, surface->height);
+ [self->attached setFrame:contentRect];
+ }
}
static void
gdk_macos_gl_context_dispose (GObject *gobject)
{
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (gobject);
- NSOpenGLContext *gl_context;
- if ((gl_context = get_ns_open_gl_context (self, NULL)))
- [gl_context clearDrawable];
+ if (self->attached != nil)
+ {
+ NSView *nsview = g_steal_pointer (&self->attached);
+
+ [(GdkMacosGLView *)nsview setOpenGLContext:nil];
+ [nsview release];
+ }
+
+ if (self->gl_context != nil)
+ {
+ NSOpenGLContext *gl_context = g_steal_pointer (&self->gl_context);
+
+ [gl_context clearDrawable];
+ [gl_context release];
+ }
G_OBJECT_CLASS (gdk_macos_gl_context_parent_class)->dispose (gobject);
}
@@ -245,7 +302,7 @@ _gdk_macos_gl_context_new (GdkMacosSurface *surface,
"shared-context", share,
NULL);
- context->is_attached = attached;
+ context->is_attached = !!attached;
return GDK_GL_CONTEXT (context);
}
@@ -253,13 +310,11 @@ _gdk_macos_gl_context_new (GdkMacosSurface *surface,
gboolean
_gdk_macos_gl_context_make_current (GdkMacosGLContext *self)
{
- NSOpenGLContext *gl_context;
-
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
- if ((gl_context = get_ns_open_gl_context (self, NULL)))
+ if (self->gl_context != nil)
{
- [gl_context makeCurrentContext];
+ [self->gl_context makeCurrentContext];
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]