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:
parent
9520fc0ff7
commit
c08716d3ee
|
@ -1 +1 @@
|
|||
Subproject commit ebd058d7a6438d137522063bb3286c8acc325ca6
|
||||
Subproject commit c88411ff7776a2db5d6ef6117a1b2faa42a95611
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in New Issue