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
This commit is contained in:
Edmund Kapusniak 2018-06-11 20:50:14 +02:00 committed by Brecht Van Lommel
parent 9520fc0ff7
commit c08716d3ee
4 changed files with 45 additions and 17 deletions

@ -1 +1 @@
Subproject commit ebd058d7a6438d137522063bb3286c8acc325ca6
Subproject commit c88411ff7776a2db5d6ef6117a1b2faa42a95611

View File

@ -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 */

View File

@ -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 */

View File

@ -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__ */