app: confine the eglWindow indirection to the Wayland backend

Only the Wayland backend needs an wl_egl_window between the wl_surface
and EGL. Move code dealing with the indirection to Wayland specific
code.

Then, introduce the eglDriver interface instead of referencing the
native window type directly. This will help when multiple backends are
supported at runtime (e.g. Wayland+X11).

Finally, move the eglDriver implementation methods from GOOS-specific
code to separate EGL-specific files, allowing EGL types to be used
directly instead of unsafe.Pointer and uinptr.

The result is simpler generic EGL code, and easier path towards X11
support.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-10-02 23:07:54 +02:00
parent 32bda106e7
commit 2dcbf6fe3c
8 changed files with 97 additions and 85 deletions
+27 -34
View File
@@ -15,16 +15,21 @@ import (
type context struct {
c *gl.Functions
driver *window
driver eglDriver
eglCtx *eglContext
nwindow _EGLNativeWindowType
eglWin *eglWindow
eglWin _EGLNativeWindowType
eglSurf _EGLSurface
width, height int
// For sRGB emulation.
srgbFBO *gl.SRGBFBO
}
type eglDriver interface {
eglDisplay() _EGLNativeDisplayType
eglWindow(visID int) (_EGLNativeWindowType, int, int, error)
eglDestroy()
}
type eglContext struct {
disp _EGLDisplay
config _EGLConfig
@@ -62,27 +67,28 @@ const (
func (c *context) Release() {
if c.srgbFBO != nil {
c.srgbFBO.Release()
c.srgbFBO = nil
}
if c.eglSurf != nilEGLSurface {
eglMakeCurrent(c.eglCtx.disp, nilEGLSurface, nilEGLSurface, nilEGLContext)
eglDestroySurface(c.eglCtx.disp, c.eglSurf)
c.eglSurf = nilEGLSurface
}
if c.eglWin != nil {
c.eglWin.destroy()
c.eglWin = nil
}
c.eglWin = nilEGLNativeWindowType
if c.eglCtx != nil {
eglDestroyContext(c.eglCtx.disp, c.eglCtx.ctx)
eglTerminate(c.eglCtx.disp)
eglReleaseThread()
c.eglCtx = nil
}
c.driver = nil
if c.driver != nil {
c.driver.eglDestroy()
c.driver = nil
}
}
func (c *context) Present() error {
if c.eglWin == nil {
if c.eglWin == nilEGLNativeWindowType {
panic("context is not active")
}
if c.srgbFBO != nil {
@@ -97,13 +103,13 @@ func (c *context) Present() error {
return nil
}
func newContext(w *window) (*context, error) {
eglCtx, err := createContext(_EGLNativeDisplayType(w.display()))
func newContext(d eglDriver) (*context, error) {
eglCtx, err := createContext(d.eglDisplay())
if err != nil {
return nil, err
}
c := &context{
driver: w,
driver: d,
eglCtx: eglCtx,
c: new(gl.Functions),
}
@@ -119,9 +125,11 @@ func (c *context) Lock() {}
func (c *context) Unlock() {}
func (c *context) MakeCurrent() error {
w, width, height := c.driver.nativeWindow(int(c.eglCtx.visualID))
win := _EGLNativeWindowType(w)
if c.nwindow == win && width == c.width && height == c.height {
win, width, height, err := c.driver.eglWindow(int(c.eglCtx.visualID))
if err != nil {
return err
}
if c.eglWin == win && width == c.width && height == c.height {
return nil
}
if win == nilEGLNativeWindowType {
@@ -138,29 +146,14 @@ func (c *context) MakeCurrent() error {
c.eglSurf = nilEGLSurface
}
c.width, c.height = width, height
c.nwindow = win
if c.nwindow == nilEGLNativeWindowType {
if c.eglWin != nil {
c.eglWin.destroy()
c.eglWin = nil
}
c.eglWin = win
if c.eglWin == nilEGLNativeWindowType {
return nil
}
if c.eglWin == nil {
var err error
c.eglWin, err = newEGLWindow(win, width, height)
if err != nil {
return err
}
} else {
c.eglWin.resize(width, height)
}
eglSurf, err := createSurfaceAndMakeCurrent(c.eglCtx, c.eglWin.window())
eglSurf, err := createSurfaceAndMakeCurrent(c.eglCtx, win)
c.eglSurf = eglSurf
if err != nil {
c.eglWin.destroy()
c.eglWin = nil
c.nwindow = nilEGLNativeWindowType
c.eglWin = nilEGLNativeWindowType
return err
}
if c.eglCtx.srgb {
+12
View File
@@ -20,3 +20,15 @@ func eglCreateWindowSurface(disp _EGLDisplay, conf _EGLConfig, win _EGLNativeWin
eglSurf := C.eglCreateWindowSurface(disp, conf, win, &attribs[0])
return eglSurf
}
func (w *window) eglDestroy() {
}
func (w *window) eglDisplay() _EGLNativeDisplayType {
return nil
}
func (w *window) eglWindow(visID int) (_EGLNativeWindowType, int, int, error) {
win, width, height := w.nativeWindow(visID)
return _EGLNativeWindowType(win), width, height, nil
}
+36 -17
View File
@@ -6,7 +6,7 @@ package app
import (
"errors"
"unsafe"
"sync"
)
/*
@@ -24,29 +24,48 @@ type (
_EGLNativeWindowType = C.EGLNativeWindowType
)
type eglWindow struct {
w *C.struct_wl_egl_window
var eglWindows struct {
mu sync.Mutex
windows map[*C.struct_wl_surface]*C.struct_wl_egl_window
}
func newEGLWindow(w _EGLNativeWindowType, width, height int) (*eglWindow, error) {
surf := (*C.struct_wl_surface)(unsafe.Pointer(w))
win := C.wl_egl_window_create(surf, C.int(width), C.int(height))
if win == nil {
return nil, errors.New("wl_egl_create_window failed")
func (w *window) eglDestroy() {
surf, _, _ := w.surface()
if surf == nil {
return
}
eglWindows.mu.Lock()
defer eglWindows.mu.Unlock()
if eglWin, ok := eglWindows.windows[surf]; ok {
C.wl_egl_window_destroy(eglWin)
delete(eglWindows.windows, surf)
}
return &eglWindow{win}, nil
}
func (w *eglWindow) window() _EGLNativeWindowType {
return w.w
func (w *window) eglDisplay() _EGLNativeDisplayType {
return w.display()
}
func (w *eglWindow) resize(width, height int) {
C.wl_egl_window_resize(w.w, C.int(width), C.int(height), 0, 0)
}
func (w *eglWindow) destroy() {
C.wl_egl_window_destroy(w.w)
func (w *window) eglWindow(visID int) (_EGLNativeWindowType, int, int, error) {
surf, width, height := w.surface()
if surf == nil {
return nilEGLNativeWindowType, 0, 0, errors.New("wayland: no surface")
}
eglWindows.mu.Lock()
defer eglWindows.mu.Unlock()
eglWin, ok := eglWindows.windows[surf]
if !ok {
if eglWindows.windows == nil {
eglWindows.windows = make(map[*C.struct_wl_surface]*C.struct_wl_egl_window)
}
eglWin = C.wl_egl_window_create(surf, C.int(width), C.int(height))
if eglWin == nil {
return nilEGLNativeWindowType, 0, 0, errors.New("wayland: wl_egl_create_window failed")
}
eglWindows.windows[surf] = eglWin
}
C.wl_egl_window_resize(eglWin, C.int(width), C.int(height), 0, 0)
return eglWin, width, height, nil
}
func eglGetDisplay(disp _EGLNativeDisplayType) _EGLDisplay {
-20
View File
@@ -1,20 +0,0 @@
// SPDX-License-Identifier: Unlicense OR MIT
// +build android windows
package app
type eglWindow struct {
w _EGLNativeWindowType
}
func newEGLWindow(w _EGLNativeWindowType, width, height int) (*eglWindow, error) {
return &eglWindow{w}, nil
}
func (w *eglWindow) window() _EGLNativeWindowType {
return w.w
}
func (w *eglWindow) resize(width, height int) {}
func (w *eglWindow) destroy() {}
+12
View File
@@ -142,3 +142,15 @@ func eglQueryString(disp _EGLDisplay, name _EGLint) string {
r, _, _ := _eglQueryString.Call(uintptr(disp), uintptr(name))
return gl.GoString(gl.SliceOf(r))
}
func (w *window) eglDestroy() {
}
func (w *window) eglDisplay() _EGLNativeDisplayType {
return _EGLNativeDisplayType(w.HDC())
}
func (w *window) eglWindow(visID int) (_EGLNativeWindowType, int, int, error) {
hwnd, width, height := w.HWND()
return _EGLNativeWindowType(hwnd), width, height, nil
}
+2 -6
View File
@@ -245,11 +245,7 @@ func (w *window) setStage(stage Stage) {
w.event(StageEvent{stage})
}
func (w *window) display() unsafe.Pointer {
return nil
}
func (w *window) nativeWindow(visID int) (unsafe.Pointer, int, int) {
func (w *window) nativeWindow(visID int) (*C.ANativeWindow, int, int) {
win := w.aNativeWindow()
var width, height int
if win != nil {
@@ -259,7 +255,7 @@ func (w *window) nativeWindow(visID int) (unsafe.Pointer, int, int) {
w, h := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win)
width, height = int(w), int(h)
}
return unsafe.Pointer(win), width, height
return win, width, height
}
func (w *window) aNativeWindow() *C.ANativeWindow {
+4 -4
View File
@@ -1036,11 +1036,11 @@ func (w *window) setStage(s Stage) {
w.w.event(StageEvent{s})
}
func (w *window) display() unsafe.Pointer {
return unsafe.Pointer(w.disp)
func (w *window) display() *C.struct_wl_display {
return w.disp
}
func (w *window) nativeWindow(visID int) (unsafe.Pointer, int, int) {
func (w *window) surface() (*C.struct_wl_surface, int, int) {
w.mu.Lock()
defer w.mu.Unlock()
if w.needAck {
@@ -1052,7 +1052,7 @@ func (w *window) nativeWindow(visID int) (unsafe.Pointer, int, int) {
C.wl_surface_set_buffer_scale(w.surf, C.int32_t(scale))
w.newScale = false
}
return unsafe.Pointer(w.surf), width * scale, height * scale
return w.surf, width * scale, height * scale
}
func (w *window) showTextInput(show bool) {}
+4 -4
View File
@@ -430,12 +430,12 @@ func (w *window) destroy() {
func (w *window) showTextInput(show bool) {}
func (w *window) display() uintptr {
return uintptr(w.hdc)
func (w *window) HDC() syscall.Handle {
return w.hdc
}
func (w *window) nativeWindow(visID int) (uintptr, int, int) {
return uintptr(w.hwnd), w.width, w.height
func (w *window) HWND() (syscall.Handle, int, int) {
return w.hwnd, w.width, w.height
}
func convertKeyCode(code uintptr) (rune, bool) {