forked from joejulian/gio
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
|
||||
}
|
||||
|
||||
func (c *context) Lock() {}
|
||||
|
||||
func (c *context) Unlock() {}
|
||||
|
||||
func (c *context) MakeCurrent() error {
|
||||
w, width, height := c.driver.nativeWindow(int(c.eglCtx.visualID))
|
||||
win := _EGLNativeWindowType(w)
|
||||
|
||||
@@ -83,6 +83,10 @@ func (c *context) Present() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) Lock() {}
|
||||
|
||||
func (c *context) Unlock() {}
|
||||
|
||||
func (c *context) MakeCurrent() error {
|
||||
if C.gio_makeCurrent(c.ctx) == 0 {
|
||||
C.CFRelease(c.ctx)
|
||||
|
||||
@@ -62,6 +62,10 @@ func (c *context) Present() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *context) Lock() {}
|
||||
|
||||
func (c *context) Unlock() {}
|
||||
|
||||
func (c *context) MakeCurrent() error {
|
||||
if c.srgbFBO == nil {
|
||||
var err error
|
||||
|
||||
@@ -44,17 +44,30 @@ func (c *context) Functions() *gl.Functions {
|
||||
}
|
||||
|
||||
func (c *context) Release() {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
C.gio_clearCurrentContext()
|
||||
C.CFRelease(c.ctx)
|
||||
c.ctx = 0
|
||||
}
|
||||
|
||||
func (c *context) Present() error {
|
||||
// Assume the caller already locked the context.
|
||||
C.glFlush()
|
||||
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 {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
C.gio_makeCurrentContext(c.ctx)
|
||||
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_flushContextBuffer(CFTypeRef ctx);
|
||||
__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;
|
||||
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
|
||||
MakeCurrent() error
|
||||
Release()
|
||||
Lock()
|
||||
Unlock()
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -202,6 +202,7 @@ func (g *GPU) renderLoop(glctx gl.Context) error {
|
||||
case <-g.refresh:
|
||||
g.refreshErr <- glctx.MakeCurrent()
|
||||
case frame := <-g.frames:
|
||||
glctx.Lock()
|
||||
if frame.collectStats && timers == nil && ctx.caps.EXT_disjoint_timer_query {
|
||||
timers = newTimers(ctx)
|
||||
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.err = err
|
||||
glctx.Unlock()
|
||||
g.results <- res
|
||||
case <-g.stop:
|
||||
break loop
|
||||
|
||||
Reference in New Issue
Block a user