diff options
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 30 | ||||
-rw-r--r-- | source/blender/editors/render/render_internal.c | 1 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 5 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 43 |
5 files changed, 81 insertions, 2 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 5f059f92d5f..054d070bea1 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1464,8 +1464,24 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) WM_init_opengl(); } + void *re_gl_context = RE_gl_context_get(render); + void *re_gwn_context = NULL; + /* Changing Context */ - DRW_opengl_context_enable(); + if (re_gl_context != NULL) { + /* TODO get rid of the blocking. Only here because of the static global DST. */ + BLI_mutex_lock(&DST.gl_context_mutex); + WM_opengl_context_activate(re_gl_context); + re_gwn_context = RE_gwn_context_get(render); + if (GWN_context_active_get() == NULL) { + GWN_context_active_set(re_gwn_context); + } + DRW_shape_cache_reset(); /* XXX fix that too. */ + } + else { + DRW_opengl_context_enable(); + } + /* IMPORTANT: We dont support immediate mode in render mode! * This shall remain in effect until immediate mode supports * multiple threads. */ @@ -1533,7 +1549,17 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) GPU_framebuffer_restore(); /* Changing Context */ - DRW_opengl_context_disable(); + if (re_gl_context != NULL) { + DRW_shape_cache_reset(); /* XXX fix that too. */ + glFlush(); + GWN_context_active_set(NULL); + WM_opengl_context_release(re_gl_context); + /* TODO get rid of the blocking. */ + BLI_mutex_unlock(&DST.gl_context_mutex); + } + else { + DRW_opengl_context_disable(); + } #ifdef DEBUG /* Avoid accidental reuse. */ diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 2d65b361f99..ad546b6c2d3 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1015,6 +1015,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even RE_current_scene_update_cb(re, rj, current_scene_update); RE_stats_draw_cb(re, rj, image_renderinfo_cb); RE_progress_cb(re, rj, render_progress_update); + RE_gl_context_create(re); rj->re = re; G.is_break = false; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 660e81eb022..55638471883 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -311,6 +311,11 @@ void RE_draw_lock_cb (struct Render *re, void *handle, void (*f)(void *handle, void RE_test_break_cb (struct Render *re, void *handle, int (*f)(void *handle)); void RE_current_scene_update_cb(struct Render *re, void *handle, void (*f)(void *handle, struct Scene *scene)); +void RE_gl_context_create(Render *re); +void RE_gl_context_destroy(Render *re); +void *RE_gl_context_get(Render *re); +void *RE_gwn_context_get(Render *re); + /* should move to kernel once... still unsure on how/where */ float RE_filter_value(int type, float x); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index fd24f4eb053..34535fba1e0 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -157,6 +157,10 @@ struct Render { void **movie_ctx_arr; char viewname[MAX_NAME]; + + /* TODO replace by a whole draw manager. */ + void *gl_context; + void *gwn_context; }; /* **************** defines ********************* */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index c9f13004836..0ca9aa41056 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -94,6 +94,9 @@ #include "RE_pipeline.h" #include "RE_render_ext.h" +#include "../../../windowmanager/WM_api.h" /* XXX */ +#include "../../../intern/gawain/gawain/gwn_context.h" + #ifdef WITH_FREESTYLE # include "FRS_freestyle.h" #endif @@ -1020,6 +1023,40 @@ void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle)) re->tbh = handle; } +/* ********* GL Context ******** */ + +void RE_gl_context_create(Render *re) +{ + /* Needs to be created in the main ogl thread. */ + re->gl_context = WM_opengl_context_create(); +} + +void RE_gl_context_destroy(Render *re) +{ + /* Needs to be called from the thread which used the ogl context for rendering. */ + if (re->gwn_context) { + GWN_context_active_set(re->gwn_context); + GWN_context_discard(re->gwn_context); + re->gwn_context = NULL; + } + if (re->gl_context) { + WM_opengl_context_dispose(re->gl_context); + re->gl_context = NULL; + } +} + +void *RE_gl_context_get(Render *re) +{ + return re->gl_context; +} + +void *RE_gwn_context_get(Render *re) +{ + if (re->gwn_context == NULL) { + re->gwn_context = GWN_context_create(); + } + return re->gwn_context; +} /* ********* add object data (later) ******** */ @@ -2224,6 +2261,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_la BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE); + /* Destroy the opengl context in the correct thread. */ + RE_gl_context_destroy(re); + /* UGLY WARNING */ G.is_rendering = false; } @@ -2779,6 +2819,9 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE); BKE_sound_reset_scene_specs(scene); + /* Destroy the opengl context in the correct thread. */ + RE_gl_context_destroy(re); + /* UGLY WARNING */ G.is_rendering = false; } |