From 691adf4e77160eef31c215795138fd1db4ef5ea1 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Wed, 1 May 2024 17:38:20 +0000 Subject: [PATCH] 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 Signed-off-by: Elias Naur --- app/egl_android.go | 10 ++++------ app/egl_wayland.go | 2 +- app/egl_windows.go | 29 ++++++++++++----------------- app/egl_x11.go | 23 ++++++++++++----------- internal/egl/egl.go | 11 ++++------- 5 files changed, 33 insertions(+), 42 deletions(-) diff --git a/app/egl_android.go b/app/egl_android.go index 4d8352e76..f1db93ab5 100644 --- a/app/egl_android.go +++ b/app/egl_android.go @@ -17,9 +17,8 @@ import ( ) type androidContext struct { - win *window - eglSurf egl.NativeWindowType - width, height int + win *window + eglSurf egl.NativeWindowType *egl.Context } @@ -45,9 +44,8 @@ func (c *androidContext) Refresh() error { if err := c.win.setVisual(c.Context.VisualID()); err != nil { return err } - win, width, height := c.win.nativeWindow() + win, _, _ := c.win.nativeWindow() c.eglSurf = egl.NativeWindowType(unsafe.Pointer(win)) - c.width, c.height = width, height return nil } @@ -55,7 +53,7 @@ func (c *androidContext) Lock() error { // The Android emulator creates a broken surface if it is not // created on the same thread as the context is made current. 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 } c.eglSurf = nil diff --git a/app/egl_wayland.go b/app/egl_wayland.go index 04aa60d80..52a883eb7 100644 --- a/app/egl_wayland.go +++ b/app/egl_wayland.go @@ -69,7 +69,7 @@ func (c *wlContext) Refresh() error { } c.eglWin = 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 } if err := c.Context.MakeCurrent(); err != nil { diff --git a/app/egl_windows.go b/app/egl_windows.go index f4d994ad3..0522a7925 100644 --- a/app/egl_windows.go +++ b/app/egl_windows.go @@ -5,8 +5,6 @@ package app import ( - "golang.org/x/sys/windows" - "gioui.org/internal/egl" ) @@ -24,6 +22,18 @@ func init() { if err != nil { 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 }, }) @@ -37,21 +47,6 @@ func (c *glContext) Release() { } 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 } diff --git a/app/egl_x11.go b/app/egl_x11.go index c60f06dee..b10b2581d 100644 --- a/app/egl_x11.go +++ b/app/egl_x11.go @@ -25,6 +25,18 @@ func init() { if err != nil { 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 } } @@ -37,17 +49,6 @@ func (c *x11Context) Release() { } 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 } diff --git a/internal/egl/egl.go b/internal/egl/egl.go index 90dd90094..ab2eab762 100644 --- a/internal/egl/egl.go +++ b/internal/egl/egl.go @@ -15,10 +15,9 @@ import ( ) type Context struct { - disp _EGLDisplay - eglCtx *eglContext - eglSurf _EGLSurface - width, height int + disp _EGLDisplay + eglCtx *eglContext + eglSurf _EGLSurface } type eglContext struct { @@ -121,11 +120,9 @@ func (c *Context) VisualID() int { 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) c.eglSurf = eglSurf - c.width = width - c.height = height return err }