app/internal/window: move context refresh to window

Instead of calling from the low level context into the window
for its surface and dimensions, add a Context.MakeCurrent method
that does it directly.

The result is simpler and clearer logic. For example, synchronization
is obviously no longer needed. It wasn't necessary before, but the
reason was unclear.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-11-28 18:46:33 +01:00
parent 3199ae7600
commit 8cec7d1a40
7 changed files with 187 additions and 176 deletions
+30 -12
View File
@@ -14,20 +14,38 @@ import (
"gioui.org/app/internal/gl"
)
func (w *window) EGLDestroy() {
}
func (w *window) EGLDisplay() egl.NativeDisplayType {
return nil
}
func (w *window) EGLWindow(visID int) (egl.NativeWindowType, int, int, error) {
win, width, height := w.nativeWindow(visID)
return egl.NativeWindowType(unsafe.Pointer(win)), width, height, nil
type context struct {
win *window
*egl.Context
}
func (w *window) NewContext() (gl.Context, error) {
return egl.NewContext(w)
ctx, err := egl.NewContext(nil)
if err != nil {
return nil, err
}
return &context{win: w, Context: ctx}, nil
}
func (w *window) NeedVSync() bool { return false }
func (c *context) Release() {
if c.Context != nil {
c.Context.Release()
c.Context = nil
}
}
func (c *context) MakeCurrent() error {
c.Context.ReleaseSurface()
win, width, height := c.win.nativeWindow(c.Context.VisualID())
if win == nil {
return nil
}
eglSurf := egl.NativeWindowType(unsafe.Pointer(win))
if err := c.Context.CreateSurface(eglSurf, width, height); err != nil {
return err
}
if err := c.Context.MakeCurrent(); err != nil {
return err
}
return nil
}
+42 -45
View File
@@ -6,7 +6,6 @@ package window
import (
"errors"
"sync"
"unsafe"
"gioui.org/app/internal/egl"
@@ -22,52 +21,50 @@ import (
*/
import "C"
var eglWindows struct {
mu sync.Mutex
windows map[*C.struct_wl_surface]*C.struct_wl_egl_window
}
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)
}
}
func (w *window) EGLDisplay() egl.NativeDisplayType {
return egl.NativeDisplayType(unsafe.Pointer(w.display()))
}
func (w *window) EGLWindow(visID int) (egl.NativeWindowType, int, int, error) {
surf, width, height := w.surface()
if surf == nil {
return 0, 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 0, 0, 0, errors.New("wayland: wl_egl_window_create failed")
}
eglWindows.windows[surf] = eglWin
}
C.wl_egl_window_resize(eglWin, C.int(width), C.int(height), 0, 0)
return egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin))), width, height, nil
type context struct {
win *window
*egl.Context
eglWin *C.struct_wl_egl_window
}
func (w *window) NewContext() (gl.Context, error) {
return egl.NewContext(w)
disp := egl.NativeDisplayType(unsafe.Pointer(w.display()))
ctx, err := egl.NewContext(disp)
if err != nil {
return nil, err
}
return &context{Context: ctx, win: w}, nil
}
func (w *window) NeedVSync() bool { return false }
func (c *context) Release() {
if c.Context != nil {
c.Context.Release()
c.Context = nil
}
if c.eglWin != nil {
C.wl_egl_window_destroy(c.eglWin)
c.eglWin = nil
}
}
func (c *context) MakeCurrent() error {
c.Context.ReleaseSurface()
if c.eglWin != nil {
C.wl_egl_window_destroy(c.eglWin)
c.eglWin = nil
}
surf, width, height := c.win.surface()
if surf == nil {
return errors.New("wayland: no surface")
}
eglWin := C.wl_egl_window_create(surf, C.int(width), C.int(height))
if eglWin == nil {
return errors.New("wayland: wl_egl_window_create failed")
}
c.eglWin = eglWin
eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin)))
if err := c.Context.CreateSurface(eglSurf, width, height); err != nil {
return err
}
return c.Context.MakeCurrent()
}
+31 -12
View File
@@ -3,24 +3,43 @@
package window
import (
"unsafe"
"gioui.org/app/internal/egl"
"gioui.org/app/internal/gl"
)
func (w *window) EGLDestroy() {
}
func (w *window) EGLDisplay() egl.NativeDisplayType {
return egl.NativeDisplayType(w.HDC())
}
func (w *window) EGLWindow(visID int) (egl.NativeWindowType, int, int, error) {
hwnd, width, height := w.HWND()
return egl.NativeWindowType(hwnd), width, height, nil
type context struct {
win *window
*egl.Context
}
func (w *window) NewContext() (gl.Context, error) {
return egl.NewContext(w)
disp := egl.NativeDisplayType(unsafe.Pointer(w.HDC()))
ctx, err := egl.NewContext(disp)
if err != nil {
return nil, err
}
return &context{win: w, Context: ctx}, nil
}
func (w *window) NeedVSync() bool { return true }
func (c *context) Release() {
if c.Context != nil {
c.Context.Release()
c.Context = nil
}
}
func (c *context) MakeCurrent() error {
c.Context.ReleaseSurface()
win, width, height := c.win.HWND()
eglSurf := egl.NativeWindowType(win)
if err := c.Context.CreateSurface(eglSurf, width, height); err != nil {
return err
}
if err := c.Context.MakeCurrent(); err != nil {
return err
}
c.Context.EnableVSync(true)
return nil
}
+30 -10
View File
@@ -5,23 +5,43 @@
package window
import (
"unsafe"
"gioui.org/app/internal/egl"
"gioui.org/app/internal/gl"
)
type x11Context struct {
win *x11Window
*egl.Context
}
func (w *x11Window) NewContext() (gl.Context, error) {
return egl.NewContext(w)
disp := egl.NativeDisplayType(unsafe.Pointer(w.display()))
ctx, err := egl.NewContext(disp)
if err != nil {
return nil, err
}
return &x11Context{win: w, Context: ctx}, nil
}
func (w *x11Window) EGLDestroy() {
func (c *x11Context) Release() {
if c.Context != nil {
c.Context.Release()
c.Context = nil
}
}
func (w *x11Window) EGLDisplay() egl.NativeDisplayType {
return egl.NativeDisplayType(w.display())
func (c *x11Context) MakeCurrent() error {
c.Context.ReleaseSurface()
win, width, height := c.win.window()
eglSurf := egl.NativeWindowType(uintptr(win))
if err := c.Context.CreateSurface(eglSurf, width, height); err != nil {
return err
}
if err := c.Context.MakeCurrent(); err != nil {
return err
}
c.Context.EnableVSync(true)
return nil
}
func (w *x11Window) EGLWindow(visID int) (egl.NativeWindowType, int, int, error) {
return egl.NativeWindowType(uintptr(w.xw)), w.width, w.height, nil
}
func (w *x11Window) NeedVSync() bool { return true }
-2
View File
@@ -1052,8 +1052,6 @@ func (w *window) display() *C.struct_wl_display {
}
func (w *window) surface() (*C.struct_wl_surface, int, int) {
w.mu.Lock()
defer w.mu.Unlock()
if w.needAck {
C.xdg_surface_ack_configure(w.wmSurf, w.serial)
w.needAck = false
+6 -2
View File
@@ -78,8 +78,12 @@ func (w *x11Window) wakeup() {
}
}
func (w *x11Window) display() unsafe.Pointer {
return unsafe.Pointer(w.x)
func (w *x11Window) display() *C.Display {
return w.x
}
func (w *x11Window) window() (C.Window, int, int) {
return w.xw, w.width, w.height
}
func (w *x11Window) setStage(s system.Stage) {