mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 09:55:40 +00:00
app,gpu,internal/egl: lock OS thread when making OpenGL context current
OpenGL stores the current context in thread-local memory, but commit
4f5baa9a51 removed a runtime.LockOSThread from app.Window that ensured
the goroutine that drives the context stays on the operating thread that
has the context current. This change restores the thread lock.
As a bonus, this change makes the OpenGL contexts responsible for locking
the thread at MakeCurrent, thereby removing LockOSThread calls from GPU
backend-agnostic code.
Fixes: https://todo.sr.ht/~eliasnaur/gio/334
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"gioui.org/gpu"
|
"gioui.org/gpu"
|
||||||
"gioui.org/internal/gl"
|
"gioui.org/internal/gl"
|
||||||
@@ -101,6 +102,9 @@ func (c *context) Present() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Lock() error {
|
func (c *context) Lock() error {
|
||||||
|
// OpenGL contexts are implicit and thread-local. Lock the OS thread.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
if C.gio_makeCurrent(c.ctx) == 0 {
|
if C.gio_makeCurrent(c.ctx) == 0 {
|
||||||
return errors.New("[EAGLContext setCurrentContext] failed")
|
return errors.New("[EAGLContext setCurrentContext] failed")
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -7,6 +7,9 @@ package app
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"gioui.org/gpu"
|
"gioui.org/gpu"
|
||||||
"gioui.org/internal/gl"
|
"gioui.org/internal/gl"
|
||||||
@@ -35,8 +38,6 @@ static void glFlush(PFN_glFlush f) {
|
|||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
type glContext struct {
|
type glContext struct {
|
||||||
c *gl.Functions
|
c *gl.Functions
|
||||||
ctx C.CFTypeRef
|
ctx C.CFTypeRef
|
||||||
@@ -95,6 +96,9 @@ func (c *glContext) Present() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *glContext) Lock() error {
|
func (c *glContext) Lock() error {
|
||||||
|
// OpenGL contexts are implicit and thread-local. Lock the OS thread.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
C.gio_lockContext(c.ctx)
|
C.gio_lockContext(c.ctx)
|
||||||
C.gio_makeCurrentContext(c.ctx)
|
C.gio_makeCurrentContext(c.ctx)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ func newDriver(t *testing.T) driver.Device {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Skipf("no context available: %v", err)
|
t.Skipf("no context available: %v", err)
|
||||||
}
|
}
|
||||||
runtime.LockOSThread()
|
|
||||||
if err := ctx.MakeCurrent(); err != nil {
|
if err := ctx.MakeCurrent(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"gioui.org/gpu"
|
"gioui.org/gpu"
|
||||||
"gioui.org/gpu/internal/driver"
|
"gioui.org/gpu/internal/driver"
|
||||||
@@ -146,8 +145,6 @@ func (w *Window) Screenshot(img *image.RGBA) error {
|
|||||||
func contextDo(ctx context, f func() error) error {
|
func contextDo(ctx context, f func() error) error {
|
||||||
errCh := make(chan error)
|
errCh := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
if err := ctx.MakeCurrent(); err != nil {
|
if err := ctx.MakeCurrent(); err != nil {
|
||||||
errCh <- err
|
errCh <- err
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ func (c *Context) ReleaseCurrent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) MakeCurrent() error {
|
func (c *Context) MakeCurrent() error {
|
||||||
|
// OpenGL contexts are implicit and thread-local. Lock the OS thread.
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
if c.eglSurf == nilEGLSurface && !c.eglCtx.surfaceless {
|
if c.eglSurf == nilEGLSurface && !c.eglCtx.surfaceless {
|
||||||
return errors.New("no surface created yet EGL_KHR_surfaceless_context is not supported")
|
return errors.New("no surface created yet EGL_KHR_surfaceless_context is not supported")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user