mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-05 17:35:36 +00:00
ui/app: add Lock/Unlock to Context for macOS
Without locking, asynchronous OpenGL rendering crashes on macOS. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -114,6 +114,10 @@ func (c *context) Functions() *gl.Functions {
|
|||||||
return c.c
|
return c.c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *context) Lock() {}
|
||||||
|
|
||||||
|
func (c *context) Unlock() {}
|
||||||
|
|
||||||
func (c *context) MakeCurrent() error {
|
func (c *context) MakeCurrent() error {
|
||||||
w, width, height := c.driver.nativeWindow(int(c.eglCtx.visualID))
|
w, width, height := c.driver.nativeWindow(int(c.eglCtx.visualID))
|
||||||
win := _EGLNativeWindowType(w)
|
win := _EGLNativeWindowType(w)
|
||||||
|
|||||||
@@ -83,6 +83,10 @@ func (c *context) Present() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *context) Lock() {}
|
||||||
|
|
||||||
|
func (c *context) Unlock() {}
|
||||||
|
|
||||||
func (c *context) MakeCurrent() error {
|
func (c *context) MakeCurrent() error {
|
||||||
if C.gio_makeCurrent(c.ctx) == 0 {
|
if C.gio_makeCurrent(c.ctx) == 0 {
|
||||||
C.CFRelease(c.ctx)
|
C.CFRelease(c.ctx)
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ func (c *context) Present() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *context) Lock() {}
|
||||||
|
|
||||||
|
func (c *context) Unlock() {}
|
||||||
|
|
||||||
func (c *context) MakeCurrent() error {
|
func (c *context) MakeCurrent() error {
|
||||||
if c.srgbFBO == nil {
|
if c.srgbFBO == nil {
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@@ -44,17 +44,30 @@ func (c *context) Functions() *gl.Functions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Release() {
|
func (c *context) Release() {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
C.gio_clearCurrentContext()
|
C.gio_clearCurrentContext()
|
||||||
C.CFRelease(c.ctx)
|
C.CFRelease(c.ctx)
|
||||||
c.ctx = 0
|
c.ctx = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Present() error {
|
func (c *context) Present() error {
|
||||||
|
// Assume the caller already locked the context.
|
||||||
C.glFlush()
|
C.glFlush()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *context) Lock() {
|
||||||
|
C.gio_lockContext(c.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *context) Unlock() {
|
||||||
|
C.gio_unlockContext(c.ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *context) MakeCurrent() error {
|
func (c *context) MakeCurrent() error {
|
||||||
|
c.Lock()
|
||||||
|
defer c.Unlock()
|
||||||
C.gio_makeCurrentContext(c.ctx)
|
C.gio_makeCurrentContext(c.ctx)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ __attribute__ ((visibility ("hidden"))) CFTypeRef gio_contextForView(CFTypeRef v
|
|||||||
__attribute__ ((visibility ("hidden"))) void gio_makeCurrentContext(CFTypeRef ctx);
|
__attribute__ ((visibility ("hidden"))) void gio_makeCurrentContext(CFTypeRef ctx);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ctx);
|
__attribute__ ((visibility ("hidden"))) void gio_flushContextBuffer(CFTypeRef ctx);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext();
|
__attribute__ ((visibility ("hidden"))) void gio_clearCurrentContext();
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_lockContext(CFTypeRef ctxRef);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_unlockContext(CFTypeRef ctxRef);
|
||||||
|
|||||||
@@ -151,3 +151,13 @@ void gio_makeCurrentContext(CFTypeRef ctxRef) {
|
|||||||
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||||
return [ctx makeCurrentContext];
|
return [ctx makeCurrentContext];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gio_lockContext(CFTypeRef ctxRef) {
|
||||||
|
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||||
|
CGLLockContext([ctx CGLContextObj]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gio_unlockContext(CFTypeRef ctxRef) {
|
||||||
|
NSOpenGLContext *ctx = (__bridge NSOpenGLContext *)ctxRef;
|
||||||
|
CGLUnlockContext([ctx CGLContextObj]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ type Context interface {
|
|||||||
Present() error
|
Present() error
|
||||||
MakeCurrent() error
|
MakeCurrent() error
|
||||||
Release()
|
Release()
|
||||||
|
Lock()
|
||||||
|
Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ func (g *GPU) renderLoop(glctx gl.Context) error {
|
|||||||
case <-g.refresh:
|
case <-g.refresh:
|
||||||
g.refreshErr <- glctx.MakeCurrent()
|
g.refreshErr <- glctx.MakeCurrent()
|
||||||
case frame := <-g.frames:
|
case frame := <-g.frames:
|
||||||
|
glctx.Lock()
|
||||||
if frame.collectStats && timers == nil && ctx.caps.EXT_disjoint_timer_query {
|
if frame.collectStats && timers == nil && ctx.caps.EXT_disjoint_timer_query {
|
||||||
timers = newTimers(ctx)
|
timers = newTimers(ctx)
|
||||||
zopsTimer = timers.newTimer()
|
zopsTimer = timers.newTimer()
|
||||||
@@ -253,6 +254,7 @@ func (g *GPU) renderLoop(glctx gl.Context) error {
|
|||||||
res.summary = fmt.Sprintf("f:%7s zt:%7s st:%7s cov:%7s", ft, zt, st, covt)
|
res.summary = fmt.Sprintf("f:%7s zt:%7s st:%7s cov:%7s", ft, zt, st, covt)
|
||||||
}
|
}
|
||||||
res.err = err
|
res.err = err
|
||||||
|
glctx.Unlock()
|
||||||
g.results <- res
|
g.results <- res
|
||||||
case <-g.stop:
|
case <-g.stop:
|
||||||
break loop
|
break loop
|
||||||
|
|||||||
Reference in New Issue
Block a user