mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-04 17:05:38 +00:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user