From 9df3c76aa22f9cf851bcaf51d3f2cc534b0dc36b Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sun, 1 Dec 2019 23:39:02 +0100 Subject: [PATCH] app/internal/egl: don't exit if EGL dlls fails to load We want a useful error instead of a hard exit for headless windows. Signed-off-by: Elias Naur --- app/internal/egl/egl.go | 3 +++ app/internal/egl/egl_unix.go | 4 ++++ app/internal/egl/egl_windows.go | 33 ++++++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/app/internal/egl/egl.go b/app/internal/egl/egl.go index ec295eb0..580c9beb 100644 --- a/app/internal/egl/egl.go +++ b/app/internal/egl/egl.go @@ -87,6 +87,9 @@ func (c *Context) Present() error { } func NewContext(disp NativeDisplayType) (*Context, error) { + if err := loadEGL(); err != nil { + return nil, err + } eglDisp := eglGetDisplay(disp) if eglDisp == nilEGLDisplay { return nil, fmt.Errorf("eglGetDisplay failed: 0x%x", eglGetError()) diff --git a/app/internal/egl/egl_unix.go b/app/internal/egl/egl_unix.go index b023882d..9f07a6a5 100644 --- a/app/internal/egl/egl_unix.go +++ b/app/internal/egl/egl_unix.go @@ -26,6 +26,10 @@ type ( NativeWindowType = C.EGLNativeWindowType ) +func loadEGL() error { + return nil +} + func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) { var cfg C.EGLConfig var ncfg C.EGLint diff --git a/app/internal/egl/egl_windows.go b/app/internal/egl/egl_windows.go index 93e35e4e..c587cb62 100644 --- a/app/internal/egl/egl_windows.go +++ b/app/internal/egl/egl_windows.go @@ -3,8 +3,9 @@ package egl import ( - "os" + "fmt" "runtime" + "sync" "unsafe" syscall "golang.org/x/sys/windows" @@ -41,22 +42,36 @@ var ( _eglQueryString = libEGL.NewProc("eglQueryString") ) -func init() { - mustLoadDLL(libEGL, "libEGL.dll") - mustLoadDLL(gl.LibGLESv2, "libGLESv2.dll") - // d3dcompiler_47.dll is needed internally for shader compilation to function. - mustLoadDLL(syscall.NewLazyDLL("d3dcompiler_47.dll"), "d3dcompiler_47.dll") +var loadOnce sync.Once + +func loadEGL() error { + var err error + loadOnce.Do(func() { + err = loadDLLs() + }) + return err } -func mustLoadDLL(dll *syscall.LazyDLL, name string) { +func loadDLLs() error { + if err := loadDLL(libEGL, "libEGL.dll"); err != nil { + return err + } + if err := loadDLL(gl.LibGLESv2, "libGLESv2.dll"); err != nil { + return err + } + // d3dcompiler_47.dll is needed internally for shader compilation to function. + return loadDLL(syscall.NewLazyDLL("d3dcompiler_47.dll"), "d3dcompiler_47.dll") +} + +func loadDLL(dll *syscall.LazyDLL, name string) error { loadErr := dll.Load() if loadErr == nil { - return + return nil } pmsg := syscall.StringToUTF16Ptr("Failed to load " + name + ". Gio requires the ANGLE OpenGL ES driver to run. A prebuilt version can be downloaded from https://gioui.org/doc/install.") ptitle := syscall.StringToUTF16Ptr("Error") syscall.MessageBox(0 /* HWND */, pmsg, ptitle, syscall.MB_ICONERROR|syscall.MB_SYSTEMMODAL) - os.Exit(1) + return fmt.Errorf("egl: failed to load %s", name) } func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) {