From d9212263aacd5b6d6c37666432603f363820c23a Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Tue, 3 Dec 2019 23:53:56 +0100 Subject: [PATCH] app/headless: prepare OpenGL context on macOS The macOS backend uses a desktop OpenGL context, not a OpenGL ES context. The main difference is that sRGB have to be enabled and a vertex buffer must be bound. Do that and fix Window.Screenshot for scenes more complex than a glClear. Signed-off-by: Elias Naur --- app/headless/headless_darwin.go | 9 +++++++-- app/headless/headless_darwin.h | 1 + app/headless/headless_ios.m | 3 +++ app/headless/headless_macos.m | 10 +++++++++- app/headless/headless_test.go | 5 +++-- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/headless/headless_darwin.go b/app/headless/headless_darwin.go index ff09c99d..8efb1681 100644 --- a/app/headless/headless_darwin.go +++ b/app/headless/headless_darwin.go @@ -13,8 +13,9 @@ import "gioui.org/app/internal/gl" import "C" type nsContext struct { - c *gl.Functions - ctx C.CFTypeRef + c *gl.Functions + ctx C.CFTypeRef + prepared bool } func newContext() (context, error) { @@ -24,6 +25,10 @@ func newContext() (context, error) { func (c *nsContext) MakeCurrent() error { C.gio_headless_makeCurrentContext(c.ctx) + if !c.prepared { + C.gio_headless_prepareContext(c.ctx) + c.prepared = true + } return nil } diff --git a/app/headless/headless_darwin.h b/app/headless/headless_darwin.h index 248e5d76..227468d5 100644 --- a/app/headless/headless_darwin.h +++ b/app/headless/headless_darwin.h @@ -4,3 +4,4 @@ __attribute__ ((visibility ("hidden"))) CFTypeRef gio_headless_newContext(void); __attribute__ ((visibility ("hidden"))) void gio_headless_releaseContext(CFTypeRef ctxRef); __attribute__ ((visibility ("hidden"))) void gio_headless_clearCurrentContext(CFTypeRef ctxRef); __attribute__ ((visibility ("hidden"))) void gio_headless_makeCurrentContext(CFTypeRef ctxRef); +__attribute__ ((visibility ("hidden"))) void gio_headless_prepareContext(CFTypeRef ctxRef); diff --git a/app/headless/headless_ios.m b/app/headless/headless_ios.m index 90aa838c..3942b0ef 100644 --- a/app/headless/headless_ios.m +++ b/app/headless/headless_ios.m @@ -27,3 +27,6 @@ void gio_headless_makeCurrentContext(CFTypeRef ctxRef) { EAGLContext *ctx = (__bridge EAGLContext *)ctxRef; [EAGLContext setCurrentContext:ctx]; } + +void gio_headless_prepareContext(CFTypeRef ctxRef) { +} diff --git a/app/headless/headless_macos.m b/app/headless/headless_macos.m index d23f3ccb..6ca5eb17 100644 --- a/app/headless/headless_macos.m +++ b/app/headless/headless_macos.m @@ -5,6 +5,7 @@ @import AppKit; @import OpenGL; @import OpenGL.GL; +@import OpenGL.GL3; #include #include "headless_darwin.h" @@ -40,6 +41,13 @@ void gio_headless_clearCurrentContext(CFTypeRef ctxRef) { void gio_headless_makeCurrentContext(CFTypeRef ctxRef) { NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef; [ctx makeCurrentContext]; - glEnable(GL_FRAMEBUFFER_SRGB); CGLLockContext([ctx CGLContextObj]); } + +void gio_headless_prepareContext(CFTypeRef ctxRef) { + // Bind a default VBA to emulate OpenGL ES 2. + GLuint defVBA; + glGenVertexArrays(1, &defVBA); + glBindVertexArray(defVBA); + glEnable(GL_FRAMEBUFFER_SRGB); +} diff --git a/app/headless/headless_test.go b/app/headless/headless_test.go index 9fbd91af..8fb60f7e 100644 --- a/app/headless/headless_test.go +++ b/app/headless/headless_test.go @@ -22,9 +22,10 @@ func TestHeadless(t *testing.T) { col := color.RGBA{A: 0xff, R: 0xcc, G: 0xcc} var ops op.Ops paint.ColorOp{Color: col}.Add(&ops) + // Paint only part of the screen to avoid the glClear optimization. paint.PaintOp{Rect: f32.Rectangle{Max: f32.Point{ - X: float32(sz.X), - Y: float32(sz.Y), + X: float32(sz.X) - 100, + Y: float32(sz.Y) - 100, }}}.Add(&ops) w.Frame(&ops)