app: [X11] don't recreate EGL surface during resize

According to #565 X11 GPU drivers don't deal well with recreation of
EGL surfaces.

Thanks to Walter Schneider for debugging this issue and coming up with
the original patch.

Fixes: https://todo.sr.ht/~eliasnaur/gio/565
Co-authored-by: Walter Werner SCHNEIDER <contact@schnwalter.eu>
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2024-05-01 17:38:20 +00:00
parent ba1e34e570
commit 691adf4e77
5 changed files with 33 additions and 42 deletions
+4 -6
View File
@@ -17,9 +17,8 @@ import (
) )
type androidContext struct { type androidContext struct {
win *window win *window
eglSurf egl.NativeWindowType eglSurf egl.NativeWindowType
width, height int
*egl.Context *egl.Context
} }
@@ -45,9 +44,8 @@ func (c *androidContext) Refresh() error {
if err := c.win.setVisual(c.Context.VisualID()); err != nil { if err := c.win.setVisual(c.Context.VisualID()); err != nil {
return err return err
} }
win, width, height := c.win.nativeWindow() win, _, _ := c.win.nativeWindow()
c.eglSurf = egl.NativeWindowType(unsafe.Pointer(win)) c.eglSurf = egl.NativeWindowType(unsafe.Pointer(win))
c.width, c.height = width, height
return nil return nil
} }
@@ -55,7 +53,7 @@ func (c *androidContext) Lock() error {
// The Android emulator creates a broken surface if it is not // The Android emulator creates a broken surface if it is not
// created on the same thread as the context is made current. // created on the same thread as the context is made current.
if c.eglSurf != nil { if c.eglSurf != nil {
if err := c.Context.CreateSurface(c.eglSurf, c.width, c.height); err != nil { if err := c.Context.CreateSurface(c.eglSurf); err != nil {
return err return err
} }
c.eglSurf = nil c.eglSurf = nil
+1 -1
View File
@@ -69,7 +69,7 @@ func (c *wlContext) Refresh() error {
} }
c.eglWin = eglWin c.eglWin = eglWin
eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin))) eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin)))
if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { if err := c.Context.CreateSurface(eglSurf); err != nil {
return err return err
} }
if err := c.Context.MakeCurrent(); err != nil { if err := c.Context.MakeCurrent(); err != nil {
+12 -17
View File
@@ -5,8 +5,6 @@
package app package app
import ( import (
"golang.org/x/sys/windows"
"gioui.org/internal/egl" "gioui.org/internal/egl"
) )
@@ -24,6 +22,18 @@ func init() {
if err != nil { if err != nil {
return nil, err return nil, err
} }
win, _, _ := w.HWND()
eglSurf := egl.NativeWindowType(win)
if err := ctx.CreateSurface(eglSurf); err != nil {
ctx.Release()
return nil, err
}
if err := ctx.MakeCurrent(); err != nil {
ctx.Release()
return nil, err
}
defer ctx.ReleaseCurrent()
ctx.EnableVSync(true)
return &glContext{win: w, Context: ctx}, nil return &glContext{win: w, Context: ctx}, nil
}, },
}) })
@@ -37,21 +47,6 @@ func (c *glContext) Release() {
} }
func (c *glContext) Refresh() error { func (c *glContext) Refresh() error {
c.Context.ReleaseSurface()
var (
win windows.Handle
width, height int
)
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)
c.Context.ReleaseCurrent()
return nil return nil
} }
+12 -11
View File
@@ -25,6 +25,18 @@ func init() {
if err != nil { if err != nil {
return nil, err return nil, err
} }
win, _, _ := w.window()
eglSurf := egl.NativeWindowType(uintptr(win))
if err := ctx.CreateSurface(eglSurf); err != nil {
ctx.Release()
return nil, err
}
if err := ctx.MakeCurrent(); err != nil {
ctx.Release()
return nil, err
}
defer ctx.ReleaseCurrent()
ctx.EnableVSync(true)
return &x11Context{win: w, Context: ctx}, nil return &x11Context{win: w, Context: ctx}, nil
} }
} }
@@ -37,17 +49,6 @@ func (c *x11Context) Release() {
} }
func (c *x11Context) Refresh() error { func (c *x11Context) Refresh() 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
}
defer c.Context.ReleaseCurrent()
c.Context.EnableVSync(true)
return nil return nil
} }
+4 -7
View File
@@ -15,10 +15,9 @@ import (
) )
type Context struct { type Context struct {
disp _EGLDisplay disp _EGLDisplay
eglCtx *eglContext eglCtx *eglContext
eglSurf _EGLSurface eglSurf _EGLSurface
width, height int
} }
type eglContext struct { type eglContext struct {
@@ -121,11 +120,9 @@ func (c *Context) VisualID() int {
return c.eglCtx.visualID return c.eglCtx.visualID
} }
func (c *Context) CreateSurface(win NativeWindowType, width, height int) error { func (c *Context) CreateSurface(win NativeWindowType) error {
eglSurf, err := createSurface(c.disp, c.eglCtx, win) eglSurf, err := createSurface(c.disp, c.eglCtx, win)
c.eglSurf = eglSurf c.eglSurf = eglSurf
c.width = width
c.height = height
return err return err
} }