123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- // SPDX-License-Identifier: Unlicense OR MIT
- package egl
- import (
- "fmt"
- "runtime"
- "sync"
- "unsafe"
- syscall "golang.org/x/sys/windows"
- )
- type (
- _EGLint int32
- _EGLDisplay uintptr
- _EGLConfig uintptr
- _EGLContext uintptr
- _EGLSurface uintptr
- NativeDisplayType uintptr
- NativeWindowType uintptr
- )
- var (
- libEGL = syscall.DLL{}
- _eglChooseConfig *syscall.Proc
- _eglCreateContext *syscall.Proc
- _eglCreateWindowSurface *syscall.Proc
- _eglDestroyContext *syscall.Proc
- _eglDestroySurface *syscall.Proc
- _eglGetConfigAttrib *syscall.Proc
- _eglGetDisplay *syscall.Proc
- _eglGetError *syscall.Proc
- _eglInitialize *syscall.Proc
- _eglMakeCurrent *syscall.Proc
- _eglReleaseThread *syscall.Proc
- _eglSwapInterval *syscall.Proc
- _eglSwapBuffers *syscall.Proc
- _eglTerminate *syscall.Proc
- _eglQueryString *syscall.Proc
- _eglWaitClient *syscall.Proc
- )
- var loadOnce sync.Once
- func loadEGL() error {
- var err error
- loadOnce.Do(func() {
- err = loadDLLs()
- })
- return err
- }
- func loadDLLs() error {
- if err := loadDLL(&libEGL, "libEGL.dll"); err != nil {
- return err
- }
- procs := map[string]**syscall.Proc{
- "eglChooseConfig": &_eglChooseConfig,
- "eglCreateContext": &_eglCreateContext,
- "eglCreateWindowSurface": &_eglCreateWindowSurface,
- "eglDestroyContext": &_eglDestroyContext,
- "eglDestroySurface": &_eglDestroySurface,
- "eglGetConfigAttrib": &_eglGetConfigAttrib,
- "eglGetDisplay": &_eglGetDisplay,
- "eglGetError": &_eglGetError,
- "eglInitialize": &_eglInitialize,
- "eglMakeCurrent": &_eglMakeCurrent,
- "eglReleaseThread": &_eglReleaseThread,
- "eglSwapInterval": &_eglSwapInterval,
- "eglSwapBuffers": &_eglSwapBuffers,
- "eglTerminate": &_eglTerminate,
- "eglQueryString": &_eglQueryString,
- "eglWaitClient": &_eglWaitClient,
- }
- for name, proc := range procs {
- p, err := libEGL.FindProc(name)
- if err != nil {
- return fmt.Errorf("failed to locate %s in %s: %w", name, libEGL.Name, err)
- }
- *proc = p
- }
- return nil
- }
- func loadDLL(dll *syscall.DLL, name string) error {
- handle, err := syscall.LoadLibraryEx(name, 0, syscall.LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)
- if err != nil {
- return fmt.Errorf("egl: failed to load %s: %v", name, err)
- }
- dll.Handle = handle
- dll.Name = name
- return nil
- }
- func eglChooseConfig(disp _EGLDisplay, attribs []_EGLint) (_EGLConfig, bool) {
- var cfg _EGLConfig
- var ncfg _EGLint
- a := &attribs[0]
- r, _, _ := _eglChooseConfig.Call(uintptr(disp), uintptr(unsafe.Pointer(a)), uintptr(unsafe.Pointer(&cfg)), 1, uintptr(unsafe.Pointer(&ncfg)))
- issue34474KeepAlive(a)
- return cfg, r != 0
- }
- func eglCreateContext(disp _EGLDisplay, cfg _EGLConfig, shareCtx _EGLContext, attribs []_EGLint) _EGLContext {
- a := &attribs[0]
- c, _, _ := _eglCreateContext.Call(uintptr(disp), uintptr(cfg), uintptr(shareCtx), uintptr(unsafe.Pointer(a)))
- issue34474KeepAlive(a)
- return _EGLContext(c)
- }
- func eglCreateWindowSurface(disp _EGLDisplay, cfg _EGLConfig, win NativeWindowType, attribs []_EGLint) _EGLSurface {
- a := &attribs[0]
- s, _, _ := _eglCreateWindowSurface.Call(uintptr(disp), uintptr(cfg), uintptr(win), uintptr(unsafe.Pointer(a)))
- issue34474KeepAlive(a)
- return _EGLSurface(s)
- }
- func eglDestroySurface(disp _EGLDisplay, surf _EGLSurface) bool {
- r, _, _ := _eglDestroySurface.Call(uintptr(disp), uintptr(surf))
- return r != 0
- }
- func eglDestroyContext(disp _EGLDisplay, ctx _EGLContext) bool {
- r, _, _ := _eglDestroyContext.Call(uintptr(disp), uintptr(ctx))
- return r != 0
- }
- func eglGetConfigAttrib(disp _EGLDisplay, cfg _EGLConfig, attr _EGLint) (_EGLint, bool) {
- var val uintptr
- r, _, _ := _eglGetConfigAttrib.Call(uintptr(disp), uintptr(cfg), uintptr(attr), uintptr(unsafe.Pointer(&val)))
- return _EGLint(val), r != 0
- }
- func eglGetDisplay(disp NativeDisplayType) _EGLDisplay {
- d, _, _ := _eglGetDisplay.Call(uintptr(disp))
- return _EGLDisplay(d)
- }
- func eglGetError() _EGLint {
- e, _, _ := _eglGetError.Call()
- return _EGLint(e)
- }
- func eglInitialize(disp _EGLDisplay) (_EGLint, _EGLint, bool) {
- var maj, min uintptr
- r, _, _ := _eglInitialize.Call(uintptr(disp), uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)))
- return _EGLint(maj), _EGLint(min), r != 0
- }
- func eglMakeCurrent(disp _EGLDisplay, draw, read _EGLSurface, ctx _EGLContext) bool {
- r, _, _ := _eglMakeCurrent.Call(uintptr(disp), uintptr(draw), uintptr(read), uintptr(ctx))
- return r != 0
- }
- func eglReleaseThread() bool {
- r, _, _ := _eglReleaseThread.Call()
- return r != 0
- }
- func eglSwapInterval(disp _EGLDisplay, interval _EGLint) bool {
- r, _, _ := _eglSwapInterval.Call(uintptr(disp), uintptr(interval))
- return r != 0
- }
- func eglSwapBuffers(disp _EGLDisplay, surf _EGLSurface) bool {
- r, _, _ := _eglSwapBuffers.Call(uintptr(disp), uintptr(surf))
- return r != 0
- }
- func eglTerminate(disp _EGLDisplay) bool {
- r, _, _ := _eglTerminate.Call(uintptr(disp))
- return r != 0
- }
- func eglQueryString(disp _EGLDisplay, name _EGLint) string {
- r, _, _ := _eglQueryString.Call(uintptr(disp), uintptr(name))
- return syscall.BytePtrToString((*byte)(unsafe.Pointer(r)))
- }
- func eglWaitClient() bool {
- r, _, _ := _eglWaitClient.Call()
- return r != 0
- }
- // issue34474KeepAlive calls runtime.KeepAlive as a
- // workaround for golang.org/issue/34474.
- func issue34474KeepAlive(v interface{}) {
- runtime.KeepAlive(v)
- }
|