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
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-07-31 19:16:08 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-07-31 19:21:23 +0300
commit7e0eb0d071776ea938a70737fb3a0a9592264e94 (patch)
tree3b0ef6162f0d8aa3fe5fe7abf3cdf49e55638b4a
parent3ecba657bb79e010cffae4110ee74a063429f7ae (diff)
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.
-rw-r--r--source/blender/draw/intern/draw_manager.c2
-rw-r--r--source/blender/gpu/GPU_framebuffer.h3
-rw-r--r--source/blender/gpu/intern/gpu_context.cpp12
-rw-r--r--source/blender/gpu/intern/gpu_context_private.h3
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c54
-rw-r--r--source/blender/windowmanager/intern/wm_window.c12
6 files changed, 50 insertions, 36 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 159f69d3226..0c731811f32 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1419,7 +1419,7 @@ void DRW_draw_render_loop_ex(
DRW_hair_init();
/* No framebuffer allowed before drawing. */
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
/* Init engines */
drw_engines_init();
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<GPUBatch *> batches; /* Batches that have VAOs from this context */
#ifdef DEBUG
std::unordered_set<GPUFrameBuffer *> 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};
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 3083607b8a9..f391c92b4ca 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1113,7 +1113,7 @@ void wm_window_clear_drawable(wmWindowManager *wm)
void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
{
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
if (win != wm->windrawable && win->ghostwin) {
// win->lmbut = 0; /* keeps hanging when mousepressed while other window opened */
@@ -1134,7 +1134,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
void wm_window_reset_drawable(void)
{
BLI_assert(BLI_thread_is_main());
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
wmWindowManager *wm = G_MAIN->wm.first;
if (wm == NULL)
@@ -2280,24 +2280,24 @@ void *WM_opengl_context_create(void)
* So we should call this function only on the main thread.
*/
BLI_assert(BLI_thread_is_main());
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
return GHOST_CreateOpenGLContext(g_system);
}
void WM_opengl_context_dispose(void *context)
{
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
GHOST_DisposeOpenGLContext(g_system, (GHOST_ContextHandle)context);
}
void WM_opengl_context_activate(void *context)
{
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
GHOST_ActivateOpenGLContext((GHOST_ContextHandle)context);
}
void WM_opengl_context_release(void *context)
{
- BLI_assert(GPU_framebuffer_current_get() == 0);
+ BLI_assert(GPU_framebuffer_active_get() == NULL);
GHOST_ReleaseOpenGLContext((GHOST_ContextHandle)context);
}