gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/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 "gioui.org/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 _eglWaitClient = libEGL.NewProc("eglWaitClient") 44 ) 45 46 var loadOnce sync.Once 47 48 func loadEGL() error { 49 var err error 50 loadOnce.Do(func() { 51 err = loadDLLs() 52 }) 53 return err 54 } 55 56 func loadDLLs() error { 57 if err := loadDLL(libEGL, "libEGL.dll"); err != nil { 58 return err 59 } 60 if err := loadDLL(gl.LibGLESv2, "libGLESv2.dll"); err != nil { 61 return err 62 } 63 // d3dcompiler_47.dll is needed internally for shader compilation to function. 64 return loadDLL(syscall.NewLazyDLL("d3dcompiler_47.dll"), "d3dcompiler_47.dll") 65 } 66 67 func loadDLL(dll *syscall.LazyDLL, name string) error { 68 err := dll.Load() 69 if err != nil { 70 return fmt.Errorf("egl: failed to load %s: %v", name, err) 71 } 72 return nil 73 } 74 75 func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) { 76 var cfg _EGLConfig 77 var ncfg _EGLint 78 a := &attribs[0] 79 r, _, _ := _eglChooseConfig.Call(uintptr(disp), uintptr(unsafe.Pointer(a)), uintptr(unsafe.Pointer(&cfg)), 1, uintptr(unsafe.Pointer(&ncfg))) 80 issue34474KeepAlive(a) 81 return cfg, r != 0 82 } 83 84 func eglCreateContext(disp _EGLDisplay, cfg _EGLConfig, shareCtx _EGLContext, attribs []_EGLint) _EGLContext { 85 a := &attribs[0] 86 c, _, _ := _eglCreateContext.Call(uintptr(disp), uintptr(cfg), uintptr(shareCtx), uintptr(unsafe.Pointer(a))) 87 issue34474KeepAlive(a) 88 return _EGLContext(c) 89 } 90 91 func eglCreateWindowSurface(disp _EGLDisplay, cfg _EGLConfig, win NativeWindowType, attribs []_EGLint) _EGLSurface { 92 a := &attribs[0] 93 s, _, _ := _eglCreateWindowSurface.Call(uintptr(disp), uintptr(cfg), uintptr(win), uintptr(unsafe.Pointer(a))) 94 issue34474KeepAlive(a) 95 return _EGLSurface(s) 96 } 97 98 func eglDestroySurface(disp _EGLDisplay, surf _EGLSurface) bool { 99 r, _, _ := _eglDestroySurface.Call(uintptr(disp), uintptr(surf)) 100 return r != 0 101 } 102 103 func eglDestroyContext(disp _EGLDisplay, ctx _EGLContext) bool { 104 r, _, _ := _eglDestroyContext.Call(uintptr(disp), uintptr(ctx)) 105 return r != 0 106 } 107 108 func eglGetConfigAttrib(disp _EGLDisplay, cfg _EGLConfig, attr _EGLint) (_EGLint, bool) { 109 var val uintptr 110 r, _, _ := _eglGetConfigAttrib.Call(uintptr(disp), uintptr(cfg), uintptr(attr), uintptr(unsafe.Pointer(&val))) 111 return _EGLint(val), r != 0 112 } 113 114 func eglGetDisplay(disp NativeDisplayType) _EGLDisplay { 115 d, _, _ := _eglGetDisplay.Call(uintptr(disp)) 116 return _EGLDisplay(d) 117 } 118 119 func eglGetError() _EGLint { 120 e, _, _ := _eglGetError.Call() 121 return _EGLint(e) 122 } 123 124 func eglInitialize(disp _EGLDisplay) (_EGLint, _EGLint, bool) { 125 var maj, min uintptr 126 r, _, _ := _eglInitialize.Call(uintptr(disp), uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min))) 127 return _EGLint(maj), _EGLint(min), r != 0 128 } 129 130 func eglMakeCurrent(disp _EGLDisplay, draw, read _EGLSurface, ctx _EGLContext) bool { 131 r, _, _ := _eglMakeCurrent.Call(uintptr(disp), uintptr(draw), uintptr(read), uintptr(ctx)) 132 return r != 0 133 } 134 135 func eglReleaseThread() bool { 136 r, _, _ := _eglReleaseThread.Call() 137 return r != 0 138 } 139 140 func eglSwapInterval(disp _EGLDisplay, interval _EGLint) bool { 141 r, _, _ := _eglSwapInterval.Call(uintptr(disp), uintptr(interval)) 142 return r != 0 143 } 144 145 func eglSwapBuffers(disp _EGLDisplay, surf _EGLSurface) bool { 146 r, _, _ := _eglSwapBuffers.Call(uintptr(disp), uintptr(surf)) 147 return r != 0 148 } 149 150 func eglTerminate(disp _EGLDisplay) bool { 151 r, _, _ := _eglTerminate.Call(uintptr(disp)) 152 return r != 0 153 } 154 155 func eglQueryString(disp _EGLDisplay, name _EGLint) string { 156 r, _, _ := _eglQueryString.Call(uintptr(disp), uintptr(name)) 157 return syscall.BytePtrToString((*byte)(unsafe.Pointer(r))) 158 } 159 160 func eglWaitClient() bool { 161 r, _, _ := _eglWaitClient.Call() 162 return r != 0 163 } 164 165 // issue34474KeepAlive calls runtime.KeepAlive as a 166 // workaround for golang.org/issue/34474. 167 func issue34474KeepAlive(v interface{}) { 168 runtime.KeepAlive(v) 169 }