From 293a37c5938ab7d39c2f957f0d331857343ed580 Mon Sep 17 00:00:00 2001 From: Graham Date: Sun, 1 Sep 2019 20:42:24 +0100 Subject: [PATCH] Lock framebuffer variables accessed from multiple threads --- gl-natives/src/main/c/jaggl.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/gl-natives/src/main/c/jaggl.c b/gl-natives/src/main/c/jaggl.c index 015062bd..1a6c7cd3 100644 --- a/gl-natives/src/main/c/jaggl.c +++ b/gl-natives/src/main/c/jaggl.c @@ -131,6 +131,7 @@ static HGLRC jaggl_context; GLuint framebuffer; GLuint renderbuffer_color, renderbuffer_depth; GLint framebuffer_width, framebuffer_height; + NSLock *lock; } @end @@ -216,9 +217,15 @@ static void *jaggl_proc_addr(const char *name) { self.needsDisplayOnBoundsChange = YES; self.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; } + lock = [[NSLock alloc] init]; return self; } +- (void)dealloc { + [lock release]; + [super dealloc]; +} + - (void)genFramebuffer { framebuffer_width = (GLint) self.bounds.size.width; framebuffer_height = (GLint) self.bounds.size.height; @@ -246,7 +253,8 @@ static void *jaggl_proc_addr(const char *name) { } - (void)blit { - /* TODO(gpe): I think we need locking here and in drawInCGLContext */ + [lock lock]; + if (!framebuffer) { return; } @@ -258,6 +266,8 @@ static void *jaggl_proc_addr(const char *name) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + [lock unlock]; + dispatch_sync(dispatch_get_main_queue(), ^{ [self setNeedsDisplay]; }); @@ -279,6 +289,8 @@ static void *jaggl_proc_addr(const char *name) { GLint width = (GLint) self.bounds.size.width; GLint height = (GLint) self.bounds.size.height; + [lock lock]; + /* TODO(gpe): improve resize support (fix corruption, do we need to resize the NSView/NSWindow?) */ if (width != framebuffer_width || height != framebuffer_height) { [self deleteFramebuffer]; @@ -289,6 +301,8 @@ static void *jaggl_proc_addr(const char *name) { glBlitFramebufferEXT(0, 0, framebuffer_width, framebuffer_height, 0, 0, framebuffer_width, framebuffer_height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + [lock unlock]; + [super drawInCGLContext:context pixelFormat:pixelFormat forLayerTime:layerTime displayTime:displayTime]; } @@ -302,13 +316,17 @@ static void *jaggl_proc_addr(const char *name) { - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pix { CGLSetCurrentContext(jaggl_onscreen_context); + [lock lock]; [self genFramebuffer]; + [lock unlock]; return jaggl_onscreen_context; } - (void)releaseCGLContext:(CGLContextObj)context { CGLSetCurrentContext(context); + [lock lock]; [self deleteFramebuffer]; + [lock unlock]; CGLClearDrawable(context); } @end