egl_windows.go raw
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/p9c/p9/pkg/gel/gio/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 err := dll.Load()
68 if err != nil {
69 return fmt.Errorf("egl: failed to load %s: %v", name, err)
70 }
71 return nil
72 }
73
74 func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) {
75 var cfg _EGLConfig
76 var ncfg _EGLint
77 a := &attribs[0]
78 r, _, _ := _eglChooseConfig.Call(uintptr(disp), uintptr(unsafe.Pointer(a)), uintptr(unsafe.Pointer(&cfg)), 1, uintptr(unsafe.Pointer(&ncfg)))
79 issue34474KeepAlive(a)
80 return cfg, r != 0
81 }
82
83 func eglCreateContext(disp _EGLDisplay, cfg _EGLConfig, shareCtx _EGLContext, attribs []_EGLint) _EGLContext {
84 a := &attribs[0]
85 c, _, _ := _eglCreateContext.Call(uintptr(disp), uintptr(cfg), uintptr(shareCtx), uintptr(unsafe.Pointer(a)))
86 issue34474KeepAlive(a)
87 return _EGLContext(c)
88 }
89
90 func eglCreateWindowSurface(disp _EGLDisplay, cfg _EGLConfig, win NativeWindowType, attribs []_EGLint) _EGLSurface {
91 a := &attribs[0]
92 s, _, _ := _eglCreateWindowSurface.Call(uintptr(disp), uintptr(cfg), uintptr(win), uintptr(unsafe.Pointer(a)))
93 issue34474KeepAlive(a)
94 return _EGLSurface(s)
95 }
96
97 func eglDestroySurface(disp _EGLDisplay, surf _EGLSurface) bool {
98 r, _, _ := _eglDestroySurface.Call(uintptr(disp), uintptr(surf))
99 return r != 0
100 }
101
102 func eglDestroyContext(disp _EGLDisplay, ctx _EGLContext) bool {
103 r, _, _ := _eglDestroyContext.Call(uintptr(disp), uintptr(ctx))
104 return r != 0
105 }
106
107 func eglGetConfigAttrib(disp _EGLDisplay, cfg _EGLConfig, attr _EGLint) (_EGLint, bool) {
108 var val uintptr
109 r, _, _ := _eglGetConfigAttrib.Call(uintptr(disp), uintptr(cfg), uintptr(attr), uintptr(unsafe.Pointer(&val)))
110 return _EGLint(val), r != 0
111 }
112
113 func eglGetDisplay(disp NativeDisplayType) _EGLDisplay {
114 d, _, _ := _eglGetDisplay.Call(uintptr(disp))
115 return _EGLDisplay(d)
116 }
117
118 func eglGetError() _EGLint {
119 e, _, _ := _eglGetError.Call()
120 return _EGLint(e)
121 }
122
123 func eglInitialize(disp _EGLDisplay) (_EGLint, _EGLint, bool) {
124 var maj, min uintptr
125 r, _, _ := _eglInitialize.Call(uintptr(disp), uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)))
126 return _EGLint(maj), _EGLint(min), r != 0
127 }
128
129 func eglMakeCurrent(disp _EGLDisplay, draw, read _EGLSurface, ctx _EGLContext) bool {
130 r, _, _ := _eglMakeCurrent.Call(uintptr(disp), uintptr(draw), uintptr(read), uintptr(ctx))
131 return r != 0
132 }
133
134 func eglReleaseThread() bool {
135 r, _, _ := _eglReleaseThread.Call()
136 return r != 0
137 }
138
139 func eglSwapInterval(disp _EGLDisplay, interval _EGLint) bool {
140 r, _, _ := _eglSwapInterval.Call(uintptr(disp), uintptr(interval))
141 return r != 0
142 }
143
144 func eglSwapBuffers(disp _EGLDisplay, surf _EGLSurface) bool {
145 r, _, _ := _eglSwapBuffers.Call(uintptr(disp), uintptr(surf))
146 return r != 0
147 }
148
149 func eglTerminate(disp _EGLDisplay) bool {
150 r, _, _ := _eglTerminate.Call(uintptr(disp))
151 return r != 0
152 }
153
154 func eglQueryString(disp _EGLDisplay, name _EGLint) string {
155 r, _, _ := _eglQueryString.Call(uintptr(disp), uintptr(name))
156 return syscall.BytePtrToString((*byte)(unsafe.Pointer(r)))
157 }
158
159 // issue34474KeepAlive calls runtime.KeepAlive as a
160 // workaround for golang.org/issue/34474.
161 func issue34474KeepAlive(v interface{}) {
162 runtime.KeepAlive(v)
163 }
164