From f896a72ea1c45d080e851a7f16f273d3ef6df92c Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 14 Sep 2021 09:00:16 +0200 Subject: [PATCH] app,gpu/internal/opengl: move glFlush to macOS context present A previous change[0] moved all OpenGL function calls to the internal opengl package, so that Gio can use desktop OpenGL and OpenGL ES (ANGLE) in the same program without confusing the function pointers. However the change also moved the glFlush that constitutes a buffer swap, or present, on macOS. Other platforms don't need the flush, so this change moves it back to macOS-specific code, in glContext.Present where it belongs. It also uses dlopen and dlsym to avoid symbol confusion between Apple's OpenGL framework and ANGLE's libGLESv2.dylib. The motivation is that we're getting rid of the desktop OpenGL backend on macOS in favor of Metal, and so should reduce the number of global special-cases catering to that platform. [0] https://gioui.org/commit/476d2269a Signed-off-by: Elias Naur --- app/gl_macos.go | 30 ++++++++++++++++++++++++++++-- gpu/internal/opengl/opengl.go | 2 -- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/app/gl_macos.go b/app/gl_macos.go index b6c5924d..dc34d058 100644 --- a/app/gl_macos.go +++ b/app/gl_macos.go @@ -16,6 +16,7 @@ import ( #include #include #include +#include __attribute__ ((visibility ("hidden"))) CFTypeRef gio_createGLContext(void); __attribute__ ((visibility ("hidden"))) void gio_setContextView(CFTypeRef ctx, CFTypeRef view); @@ -25,16 +26,38 @@ __attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ct __attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext(void); __attribute__ ((visibility ("hidden"))) void gio_lockContext(CFTypeRef ctxRef); __attribute__ ((visibility ("hidden"))) void gio_unlockContext(CFTypeRef ctxRef); + +typedef void (*PFN_glFlush)(void); + +static void glFlush(PFN_glFlush f) { + f(); +} */ import "C" +import "unsafe" + type glContext struct { c *gl.Functions ctx C.CFTypeRef view C.CFTypeRef + + glFlush C.PFN_glFlush } func newContext(w *window) (*glContext, error) { + clib := C.CString("/System/Library/Frameworks/OpenGL.framework/OpenGL") + defer C.free(unsafe.Pointer(clib)) + lib, err := C.dlopen(clib, C.RTLD_NOW|C.RTLD_LOCAL) + if err != nil { + return nil, err + } + csym := C.CString("glFlush") + defer C.free(unsafe.Pointer(csym)) + glFlush := C.PFN_glFlush(C.dlsym(lib, csym)) + if glFlush == nil { + return nil, errors.New("gl: missing symbol glFlush in the OpenGL framework") + } view := w.contextView() ctx := C.gio_createGLContext() if ctx == 0 { @@ -42,8 +65,9 @@ func newContext(w *window) (*glContext, error) { } C.gio_setContextView(ctx, view) c := &glContext{ - ctx: ctx, - view: view, + ctx: ctx, + view: view, + glFlush: glFlush, } return c, nil } @@ -65,6 +89,8 @@ func (c *glContext) Release() { } func (c *glContext) Present() error { + // Assume the caller already locked the context. + C.glFlush(c.glFlush) return nil } diff --git a/gpu/internal/opengl/opengl.go b/gpu/internal/opengl/opengl.go index 24ce81c5..73227b8d 100644 --- a/gpu/internal/opengl/opengl.go +++ b/gpu/internal/opengl/opengl.go @@ -285,8 +285,6 @@ func (b *Backend) EndFrame() { b.sRGBFBO.Blit() } b.restoreState(b.savedState) - // For single-buffered framebuffers such as on macOS. - b.funcs.Flush() } func (b *Backend) queryState() glState {