Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorEdmund Kapusniak <edmundmk>2018-06-11 21:50:14 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-11 22:10:24 +0300
commitc08716d3eec06eb341b7e59a65875b1bdf70708e (patch)
tree94d5d5bd66db672c758bd6abc189a0c7603cb373 /source
parent9520fc0ff72cb510a0991889dcbbd2010c97c16e (diff)
Fix crash with OpenGL rendering in multiple threads on macOS.
On macOS we must always go through BLI_thread_local_get/set(). Differential Revision: https://developer.blender.org/D3470
Diffstat (limited to 'source')
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c54
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c2
-rw-r--r--source/blender/gpu/intern/gpu_private.h4
3 files changed, 44 insertions, 16 deletions
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index f86da2eb064..6e791f6ac07 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -42,7 +42,9 @@
#include "GPU_shader.h"
#include "GPU_texture.h"
-static ThreadLocal(GLuint) g_currentfb;
+#include "intern/gpu_private.h"
+
+static ThreadLocal(void*) g_currentfb;
typedef enum {
GPU_FB_DEPTH_ATTACHMENT = 0,
@@ -163,6 +165,26 @@ static void gpu_print_framebuffer_error(GLenum status, char err_out[256])
}
}
+void gpu_framebuffer_module_init(void)
+{
+ BLI_thread_local_create(g_currentfb);
+}
+
+void gpu_framebuffer_module_exit(void)
+{
+ BLI_thread_local_delete(g_currentfb);
+}
+
+static uint gpu_framebuffer_current_get()
+{
+ return GET_UINT_FROM_POINTER(BLI_thread_local_get(g_currentfb));
+}
+
+static void gpu_framebuffer_current_set(uint object)
+{
+ BLI_thread_local_set(g_currentfb, SET_UINT_IN_POINTER(object));
+}
+
/* GPUFrameBuffer */
GPUFrameBuffer *GPU_framebuffer_create(void)
@@ -188,8 +210,8 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb)
/* This restores the framebuffer if it was bound */
glDeleteFramebuffers(1, &fb->object);
- if (g_currentfb == fb->object) {
- g_currentfb = 0;
+ if (gpu_framebuffer_current_get() == fb->object) {
+ gpu_framebuffer_current_set(0);
}
MEM_freeN(fb);
@@ -341,7 +363,7 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb)
GLenum gl_attachments[GPU_FB_MAX_COLOR_ATTACHMENT];
int numslots = 0;
- BLI_assert(g_currentfb == fb->object);
+ BLI_assert(gpu_framebuffer_current_get() == fb->object);
/* Update attachments */
for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; ++type) {
@@ -385,10 +407,10 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
if (fb->object == 0)
gpu_framebuffer_init(fb);
- if (g_currentfb != fb->object)
+ if (gpu_framebuffer_current_get() != fb->object)
glBindFramebuffer(GL_FRAMEBUFFER, fb->object);
- g_currentfb = fb->object;
+ gpu_framebuffer_current_set(fb->object);
if (fb->dirty_flag != 0)
gpu_framebuffer_update_attachments(fb);
@@ -409,20 +431,20 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_framebuffer_restore(void)
{
- if (g_currentfb != 0) {
+ if (gpu_framebuffer_current_get() != 0) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- g_currentfb = 0;
+ gpu_framebuffer_current_set(0);
}
}
bool GPU_framebuffer_bound(GPUFrameBuffer *fb)
{
- return (fb->object == g_currentfb) && (fb->object != 0);
+ return (fb->object == gpu_framebuffer_current_get()) && (fb->object != 0);
}
unsigned int GPU_framebuffer_current_get(void)
{
- return g_currentfb;
+ return gpu_framebuffer_current_get();
}
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
@@ -513,7 +535,7 @@ void GPU_framebuffer_blit(
{
BLI_assert(blit_buffers != 0);
- GLuint prev_fb = g_currentfb;
+ GLuint prev_fb = gpu_framebuffer_current_get();
/* Framebuffers must be up to date. This simplify this function. */
if (fb_read->dirty_flag != 0 || fb_read->object == 0) {
@@ -573,7 +595,7 @@ void GPU_framebuffer_blit(
}
else {
glBindFramebuffer(GL_FRAMEBUFFER, prev_fb);
- g_currentfb = prev_fb;
+ gpu_framebuffer_current_set(prev_fb);
}
}
@@ -586,13 +608,13 @@ void GPU_framebuffer_recursive_downsample(
void (*callback)(void *userData, int level), void *userData)
{
/* Framebuffer must be up to date and bound. This simplify this function. */
- if (g_currentfb != fb->object || fb->dirty_flag != 0 || fb->object == 0) {
+ if (gpu_framebuffer_current_get() != fb->object || fb->dirty_flag != 0 || fb->object == 0) {
GPU_framebuffer_bind(fb);
}
/* HACK: We make the framebuffer appear not bound in order to
* not trigger any error in GPU_texture_bind(). */
- GLuint prev_fb = g_currentfb;
- g_currentfb = 0;
+ GLuint prev_fb = gpu_framebuffer_current_get();
+ gpu_framebuffer_current_set(0);
int i;
int current_dim[2] = {fb->width, fb->height};
@@ -640,7 +662,7 @@ void GPU_framebuffer_recursive_downsample(
}
}
- g_currentfb = prev_fb;
+ gpu_framebuffer_current_set(prev_fb);
}
/* GPUOffScreen */
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 92ad9d81b6c..78d4f491b66 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -60,6 +60,7 @@ void GPU_init(void)
GPU_texture_orphans_init();
GPU_material_orphans_init();
gpu_codegen_init();
+ gpu_framebuffer_module_init();
if (G.debug & G_DEBUG_GPU)
gpu_debug_init();
@@ -89,6 +90,7 @@ void GPU_exit(void)
if (G.debug & G_DEBUG_GPU)
gpu_debug_exit();
+ gpu_framebuffer_module_exit();
gpu_codegen_exit();
gpu_extensions_exit(); /* must come last */
diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h
index 72627e3563e..996ba9c63a1 100644
--- a/source/blender/gpu/intern/gpu_private.h
+++ b/source/blender/gpu/intern/gpu_private.h
@@ -33,4 +33,8 @@ void gpu_extensions_exit(void);
void gpu_debug_init(void);
void gpu_debug_exit(void);
+/* gpu_framebuffer.c */
+void gpu_framebuffer_module_init(void);
+void gpu_framebuffer_module_exit(void);
+
#endif /* __GPU_PRIVATE_H__ */