forked from joejulian/gio
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:
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user