github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/app/internal/egl/egl_windows.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package egl 4 5 import ( 6 "fmt" 7 "runtime" 8 "sync" 9 "unsafe" 10 11 syscall "golang.org/x/sys/windows" 12 13 "github.com/gop9/olt/gio/app/internal/gl" 14 ) 15 16 type ( 17 _EGLint int32 18 _EGLDisplay uintptr 19 _EGLConfig uintptr 20 _EGLContext uintptr 21 _EGLSurface uintptr 22 NativeDisplayType uintptr 23 NativeWindowType uintptr 24 ) 25 26 var ( 27 libEGL = syscall.NewLazyDLL("libEGL.dll") 28 _eglChooseConfig = libEGL.NewProc("eglChooseConfig") 29 _eglCreateContext = libEGL.NewProc("eglCreateContext") 30 _eglCreateWindowSurface = libEGL.NewProc("eglCreateWindowSurface") 31 _eglDestroyContext = libEGL.NewProc("eglDestroyContext") 32 _eglDestroySurface = libEGL.NewProc("eglDestroySurface") 33 _eglGetConfigAttrib = libEGL.NewProc("eglGetConfigAttrib") 34 _eglGetDisplay = libEGL.NewProc("eglGetDisplay") 35 _eglGetError = libEGL.NewProc("eglGetError") 36 _eglInitialize = libEGL.NewProc("eglInitialize") 37 _eglMakeCurrent = libEGL.NewProc("eglMakeCurrent") 38 _eglReleaseThread = libEGL.NewProc("eglReleaseThread") 39 _eglSwapInterval = libEGL.NewProc("eglSwapInterval") 40 _eglSwapBuffers = libEGL.NewProc("eglSwapBuffers") 41 _eglTerminate = libEGL.NewProc("eglTerminate") 42 _eglQueryString = libEGL.NewProc("eglQueryString") 43 ) 44 45 var loadOnce sync.Once 46 47 func loadEGL() error { 48 var err error 49 loadOnce.Do(func() { 50 err = loadDLLs() 51 }) 52 return err 53 } 54 55 func loadDLLs() error { 56 if err := loadDLL(libEGL, "libEGL.dll"); err != nil { 57 return err 58 } 59 if err := loadDLL(gl.LibGLESv2, "libGLESv2.dll"); err != nil { 60 return err 61 } 62 // d3dcompiler_47.dll is needed internally for shader compilation to function. 63 return loadDLL(syscall.NewLazyDLL("d3dcompiler_47.dll"), "d3dcompiler_47.dll") 64 } 65 66 func loadDLL(dll *syscall.LazyDLL, name string) error { 67 loadErr := dll.Load() 68 if loadErr == nil { 69 return nil 70 } 71 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.") 72 ptitle := syscall.StringToUTF16Ptr("Error") 73 syscall.MessageBox(0 /* HWND */, pmsg, ptitle, syscall.MB_ICONERROR|syscall.MB_SYSTEMMODAL) 74 return fmt.Errorf("egl: failed to load %s", name) 75 } 76 77 func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) { 78 var cfg _EGLConfig 79 var ncfg _EGLint 80 a := &attribs[0] 81 r, _, _ := _eglChooseConfig.Call(uintptr(disp), uintptr(unsafe.Pointer(a)), uintptr(unsafe.Pointer(&cfg)), 1, uintptr(unsafe.Pointer(&ncfg))) 82 issue34474KeepAlive(a) 83 return cfg, r != 0 84 } 85 86 func eglCreateContext(disp _EGLDisplay, cfg _EGLConfig, shareCtx _EGLContext, attribs []_EGLint) _EGLContext { 87 a := &attribs[0] 88 c, _, _ := _eglCreateContext.Call(uintptr(disp), uintptr(cfg), uintptr(shareCtx), uintptr(unsafe.Pointer(a))) 89 issue34474KeepAlive(a) 90 return _EGLContext(c) 91 } 92 93 func eglCreateWindowSurface(disp _EGLDisplay, cfg _EGLConfig, win NativeWindowType, attribs []_EGLint) _EGLSurface { 94 a := &attribs[0] 95 s, _, _ := _eglCreateWindowSurface.Call(uintptr(disp), uintptr(cfg), uintptr(win), uintptr(unsafe.Pointer(a))) 96 issue34474KeepAlive(a) 97 return _EGLSurface(s) 98 } 99 100 func eglDestroySurface(disp _EGLDisplay, surf _EGLSurface) bool { 101 r, _, _ := _eglDestroySurface.Call(uintptr(disp), uintptr(surf)) 102 return r != 0 103 } 104 105 func eglDestroyContext(disp _EGLDisplay, ctx _EGLContext) bool { 106 r, _, _ := _eglDestroyContext.Call(uintptr(disp), uintptr(ctx)) 107 return r != 0 108 } 109 110 func eglGetConfigAttrib(disp _EGLDisplay, cfg _EGLConfig, attr _EGLint) (_EGLint, bool) { 111 var val uintptr 112 r, _, _ := _eglGetConfigAttrib.Call(uintptr(disp), uintptr(cfg), uintptr(attr), uintptr(unsafe.Pointer(&val))) 113 return _EGLint(val), r != 0 114 } 115 116 func eglGetDisplay(disp NativeDisplayType) _EGLDisplay { 117 d, _, _ := _eglGetDisplay.Call(uintptr(disp)) 118 return _EGLDisplay(d) 119 } 120 121 func eglGetError() _EGLint { 122 e, _, _ := _eglGetError.Call() 123 return _EGLint(e) 124 } 125 126 func eglInitialize(disp _EGLDisplay) (_EGLint, _EGLint, bool) { 127 var maj, min uintptr 128 r, _, _ := _eglInitialize.Call(uintptr(disp), uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min))) 129 return _EGLint(maj), _EGLint(min), r != 0 130 } 131 132 func eglMakeCurrent(disp _EGLDisplay, draw, read _EGLSurface, ctx _EGLContext) bool { 133 r, _, _ := _eglMakeCurrent.Call(uintptr(disp), uintptr(draw), uintptr(read), uintptr(ctx)) 134 return r != 0 135 } 136 137 func eglReleaseThread() bool { 138 r, _, _ := _eglReleaseThread.Call() 139 return r != 0 140 } 141 142 func eglSwapInterval(disp _EGLDisplay, interval _EGLint) bool { 143 r, _, _ := _eglSwapInterval.Call(uintptr(disp), uintptr(interval)) 144 return r != 0 145 } 146 147 func eglSwapBuffers(disp _EGLDisplay, surf _EGLSurface) bool { 148 r, _, _ := _eglSwapBuffers.Call(uintptr(disp), uintptr(surf)) 149 return r != 0 150 } 151 152 func eglTerminate(disp _EGLDisplay) bool { 153 r, _, _ := _eglTerminate.Call(uintptr(disp)) 154 return r != 0 155 } 156 157 func eglQueryString(disp _EGLDisplay, name _EGLint) string { 158 r, _, _ := _eglQueryString.Call(uintptr(disp), uintptr(name)) 159 return gl.GoString(gl.SliceOf(r)) 160 } 161 162 // issue34474KeepAlive calls runtime.KeepAlive as a 163 // workaround for golang.org/issue/34474. 164 func issue34474KeepAlive(v interface{}) { 165 runtime.KeepAlive(v) 166 }