From 7e0eb0d071776ea938a70737fb3a0a9592264e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 31 Jul 2018 18:16:08 +0200 Subject: GPUFrameBuffer: Put active framebuffer in GPUContext instead of being ThreadLocal and leading to incorrect usage. We still enforce no framebuffer when changing context. We can lift this restriction later. --- source/blender/gpu/GPU_framebuffer.h | 3 +- source/blender/gpu/intern/gpu_context.cpp | 12 ++++++ source/blender/gpu/intern/gpu_context_private.h | 3 ++ source/blender/gpu/intern/gpu_framebuffer.c | 54 ++++++++++++------------- 4 files changed, 43 insertions(+), 29 deletions(-) (limited to 'source/blender/gpu') diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h index 04357d6a927..ef49f9721dd 100644 --- a/source/blender/gpu/GPU_framebuffer.h +++ b/source/blender/gpu/GPU_framebuffer.h @@ -69,8 +69,7 @@ void GPU_framebuffer_restore(void); bool GPU_framebuffer_bound(GPUFrameBuffer *fb); bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]); -/* internal use only */ -unsigned int GPU_framebuffer_current_get(void); +GPUFrameBuffer *GPU_framebuffer_active_get(void); #define GPU_FRAMEBUFFER_FREE_SAFE(fb) do { \ if (fb != NULL) { \ diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cpp index 8d8f4d12b04..ce3eb64fa37 100644 --- a/source/blender/gpu/intern/gpu_context.cpp +++ b/source/blender/gpu/intern/gpu_context.cpp @@ -69,6 +69,7 @@ static std::mutex orphans_mutex; struct GPUContext { GLuint default_vao; + GPUFrameBuffer *current_fbo; std::unordered_set batches; /* Batches that have VAOs from this context */ #ifdef DEBUG std::unordered_set framebuffers; /* Framebuffers that have FBO from this context */ @@ -82,6 +83,7 @@ struct GPUContext { GPUContext() { thread_is_used = false; + current_fbo = 0; } #endif }; @@ -315,3 +317,13 @@ void gpu_context_remove_framebuffer(GPUContext *ctx, GPUFrameBuffer *fb) UNUSED_VARS(ctx, fb); #endif } + +void gpu_context_active_framebuffer_set(GPUContext *ctx, GPUFrameBuffer *fb) +{ + ctx->current_fbo = fb; +} + +GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx) +{ + return ctx->current_fbo; +} diff --git a/source/blender/gpu/intern/gpu_context_private.h b/source/blender/gpu/intern/gpu_context_private.h index 4881a892e38..762d9ff10c0 100644 --- a/source/blender/gpu/intern/gpu_context_private.h +++ b/source/blender/gpu/intern/gpu_context_private.h @@ -61,6 +61,9 @@ void gpu_context_remove_batch(GPUContext *ctx, GPUBatch *batch); void gpu_context_add_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); void gpu_context_remove_framebuffer(GPUContext *ctx, struct GPUFrameBuffer *fb); +void gpu_context_active_framebuffer_set(GPUContext *ctx, struct GPUFrameBuffer *fb); +struct GPUFrameBuffer *gpu_context_active_framebuffer_get(GPUContext *ctx); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index ba8dcb04269..56abe040f32 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -45,8 +45,6 @@ #include "gpu_private.h" #include "gpu_context_private.h" -static ThreadLocal(void *) g_currentfb; - typedef enum { GPU_FB_DEPTH_ATTACHMENT = 0, GPU_FB_DEPTH_STENCIL_ATTACHMENT, @@ -169,22 +167,29 @@ 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(void) +GPUFrameBuffer *GPU_framebuffer_active_get(void) { - return GET_UINT_FROM_POINTER(BLI_thread_local_get(g_currentfb)); + GPUContext *ctx = GPU_context_active_get(); + if (ctx) { + return gpu_context_active_framebuffer_get(ctx); + } + else { + return 0; + } } -static void gpu_framebuffer_current_set(uint object) +static void gpu_framebuffer_current_set(GPUFrameBuffer *fb) { - BLI_thread_local_set(g_currentfb, SET_UINT_IN_POINTER(object)); + GPUContext *ctx = GPU_context_active_get(); + if (ctx) { + gpu_context_active_framebuffer_set(ctx, fb); + } } /* GPUFrameBuffer */ @@ -217,8 +222,8 @@ void GPU_framebuffer_free(GPUFrameBuffer *fb) gpu_context_remove_framebuffer(fb->ctx, fb); } - if (gpu_framebuffer_current_get() == fb->object) { - gpu_framebuffer_current_set(0); + if (GPU_framebuffer_active_get() == fb) { + gpu_framebuffer_current_set(NULL); } MEM_freeN(fb); @@ -371,7 +376,7 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb) GLenum gl_attachments[GPU_FB_MAX_COLOR_ATTACHMENT]; int numslots = 0; - BLI_assert(gpu_framebuffer_current_get() == fb->object); + BLI_assert(GPU_framebuffer_active_get() == fb); /* Update attachments */ for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; ++type) { @@ -415,10 +420,10 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) if (fb->object == 0) gpu_framebuffer_init(fb); - if (gpu_framebuffer_current_get() != fb->object) + if (GPU_framebuffer_active_get() != fb) glBindFramebuffer(GL_FRAMEBUFFER, fb->object); - gpu_framebuffer_current_set(fb->object); + gpu_framebuffer_current_set(fb); if (fb->dirty_flag != 0) gpu_framebuffer_update_attachments(fb); @@ -439,20 +444,15 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb) void GPU_framebuffer_restore(void) { - if (gpu_framebuffer_current_get() != 0) { + if (GPU_framebuffer_active_get() != NULL) { glBindFramebuffer(GL_FRAMEBUFFER, 0); - gpu_framebuffer_current_set(0); + gpu_framebuffer_current_set(NULL); } } bool GPU_framebuffer_bound(GPUFrameBuffer *fb) { - return (fb->object == gpu_framebuffer_current_get()) && (fb->object != 0); -} - -unsigned int GPU_framebuffer_current_get(void) -{ - return gpu_framebuffer_current_get(); + return (fb == GPU_framebuffer_active_get()) && (fb->object != 0); } bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256]) @@ -543,7 +543,7 @@ void GPU_framebuffer_blit( { BLI_assert(blit_buffers != 0); - GLuint prev_fb = gpu_framebuffer_current_get(); + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); /* Framebuffers must be up to date. This simplify this function. */ if (fb_read->dirty_flag != 0 || fb_read->object == 0) { @@ -601,11 +601,11 @@ void GPU_framebuffer_blit( mask, GL_NEAREST); /* Restore previous framebuffer */ - if (fb_write->object == prev_fb) { + if (fb_write == prev_fb) { GPU_framebuffer_bind(fb_write); /* To update drawbuffers */ } else { - glBindFramebuffer(GL_FRAMEBUFFER, prev_fb); + glBindFramebuffer(GL_FRAMEBUFFER, prev_fb->object); gpu_framebuffer_current_set(prev_fb); } } @@ -619,13 +619,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 (gpu_framebuffer_current_get() != fb->object || fb->dirty_flag != 0 || fb->object == 0) { + if (GPU_framebuffer_active_get() != fb || 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 = gpu_framebuffer_current_get(); - gpu_framebuffer_current_set(0); + GPUFrameBuffer *prev_fb = GPU_framebuffer_active_get(); + gpu_framebuffer_current_set(NULL); int i; int current_dim[2] = {fb->width, fb->height}; -- cgit v1.2.3