From 50ede837df8bdeae1c8460ef965adfe8912b4b7d Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Thu, 1 Jul 2021 20:35:47 -0500 Subject: [PATCH 1/4] x/mobile/gl: use EGL to determine the version of OpenGL ES --- gl/egl.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ gl/work.go | 14 +++++++------- 2 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 gl/egl.go diff --git a/gl/egl.go b/gl/egl.go new file mode 100644 index 000000000..1223ba4f1 --- /dev/null +++ b/gl/egl.go @@ -0,0 +1,49 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux +// +build linux + +package gl + +// #include +// #cgo LDFLAGS: -lEGL +import "C" + +func init() { + display := C.eglGetDisplay(C.EGL_DEFAULT_DISPLAY) + + C.eglInitialize(display, nil, nil) + + attributes := []C.EGLint{ + C.EGL_RED_SIZE, 1, + C.EGL_GREEN_SIZE, 1, + C.EGL_BLUE_SIZE, 1, + C.EGL_NONE, + } + + var ( + config C.EGLConfig + count C.EGLint + ) + C.eglChooseConfig(display, &attributes[0], &config, 1, &count) + + C.eglBindAPI(C.EGL_OPENGL_ES_API) + + attributes = []C.EGLint{ + C.EGL_CONTEXT_CLIENT_VERSION, 3, + C.EGL_NONE, + } + + context := C.eglCreateContext(display, config, C.EGLContext(C.EGL_NO_CONTEXT), &attributes[0]) + if context == nil { + version = "GL_ES_2_0" + + return + } + + C.eglDestroyContext(display, context) + + version = "GL_ES_3_0" +} diff --git a/gl/work.go b/gl/work.go index 73b566d9d..d5424ee85 100644 --- a/gl/work.go +++ b/gl/work.go @@ -84,16 +84,19 @@ func NewContext() (Context, Worker) { work: make(chan call, workbufLen), retvalue: make(chan C.uintptr_t), } - if C.GLES_VERSION == "GL_ES_2_0" { + if version == "GL_ES_2_0" { return glctx, glctx } return context3{glctx}, glctx } +// version is determined at runtime on platforms that support EGL. +var version = C.GLES_VERSION + // Version returns a GL ES version string, either "GL_ES_2_0" or "GL_ES_3_0". // Future versions of the gl package may return "GL_ES_3_1". func Version() string { - return C.GLES_VERSION + return version } func (ctx *context) enqueue(c call) uintptr { @@ -148,11 +151,8 @@ func (ctx *context) DoWork() { } } -func init() { - if unsafe.Sizeof(C.GLint(0)) != unsafe.Sizeof(int32(0)) { - panic("GLint is not an int32") - } -} +// GLint should be the same size as int32 +var _ [unsafe.Sizeof(C.GLint(0))]struct{} = [unsafe.Sizeof(int32(0))]struct{}{} // cString creates C string off the Go heap. // ret is a *char. From 865f9d670926c839e2823c7dfa298ce970d12ccc Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 9 Jul 2021 16:08:47 -0500 Subject: [PATCH 2/4] Update comment to remove GL_ES_3_1 mention --- gl/work.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gl/work.go b/gl/work.go index d5424ee85..663b6b747 100644 --- a/gl/work.go +++ b/gl/work.go @@ -93,8 +93,7 @@ func NewContext() (Context, Worker) { // version is determined at runtime on platforms that support EGL. var version = C.GLES_VERSION -// Version returns a GL ES version string, either "GL_ES_2_0" or "GL_ES_3_0". -// Future versions of the gl package may return "GL_ES_3_1". +// Version returns a GL ES Version string such as "GL_ES_2_0" or "GL_ES_3_0". func Version() string { return version } From daa7304706cba35e6ddeca416a40d8e84adb357a Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Fri, 9 Jul 2021 16:22:21 -0500 Subject: [PATCH 3/4] bail out of init early if an error is encountered for maximum correctness call eglTerminate before init returns. if another init on the same OS thread has already created a context, eglTerminate is a no-op until the context is destroyed. otherwise, this allows scenarios where a program that imports x/mobile/gl might want to call eglInitialize on a different display. --- gl/egl.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gl/egl.go b/gl/egl.go index 1223ba4f1..6742e90e5 100644 --- a/gl/egl.go +++ b/gl/egl.go @@ -14,7 +14,10 @@ import "C" func init() { display := C.eglGetDisplay(C.EGL_DEFAULT_DISPLAY) - C.eglInitialize(display, nil, nil) + if C.eglInitialize(display, nil, nil) == C.EGL_FALSE { + return + } + defer C.eglTerminate(display) attributes := []C.EGLint{ C.EGL_RED_SIZE, 1, @@ -27,7 +30,9 @@ func init() { config C.EGLConfig count C.EGLint ) - C.eglChooseConfig(display, &attributes[0], &config, 1, &count) + if C.eglChooseConfig(display, &attributes[0], &config, 1, &count) == C.EGL_FALSE { + return + } C.eglBindAPI(C.EGL_OPENGL_ES_API) From c24693c3bd064edb3f78cd06ddb840baa44cf514 Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 7 Aug 2021 16:04:22 -0500 Subject: [PATCH 4/4] add (unexported) constants for version numbers --- gl/egl.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gl/egl.go b/gl/egl.go index 6742e90e5..cbf3d5917 100644 --- a/gl/egl.go +++ b/gl/egl.go @@ -11,6 +11,11 @@ package gl // #cgo LDFLAGS: -lEGL import "C" +const ( + versionES2 = "GL_ES_2_0" + versionES3 = "GL_ES_3_0" +) + func init() { display := C.eglGetDisplay(C.EGL_DEFAULT_DISPLAY) @@ -43,12 +48,12 @@ func init() { context := C.eglCreateContext(display, config, C.EGLContext(C.EGL_NO_CONTEXT), &attributes[0]) if context == nil { - version = "GL_ES_2_0" + version = versionES2 return } C.eglDestroyContext(display, context) - version = "GL_ES_3_0" + version = versionES3 }