github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/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/cybriq/giocore/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  }