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:
authorLukas Stockner <lukas.stockner@freenet.de>2019-01-18 02:45:21 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2019-01-18 02:58:28 +0300
commitc9eef24903479a70783efb2e00766d0eeec43823 (patch)
treee8b7434dd06068e2030146fcd1922d44e95b5dcc /source/blender/render/intern/source/external_engine.c
parentaf316e8bc87b053e5b50453c8c5081546777d4a9 (diff)
Fix T56799: Custom render passes missing when using Save Buffers
The problem here was that when a render result is allocated, the standard render passes are added according to the pass bitfield. Then, when the render engine sets the result, it adds the additional passes which are then merged into the main render result. However, when using Save Buffers, the EXR is created before the actual render starts, so it's missing all those additional passes. To fix that, we need to query the render engine for a list of additional passes so they can be added before the EXR is created. Luckily, there already is a function to do that for the node editor. The same needs to be done when the EXR is loaded back. Due to how that is implemented though (Render API calls into engine, engine calls back for each pass), if we have multiple places that call this function there needs to be a way to tell which one the call came from in the pass registration callback. Therefore, the original caller now provides a callback that is called for each pass.
Diffstat (limited to 'source/blender/render/intern/source/external_engine.c')
-rw-r--r--source/blender/render/intern/source/external_engine.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 3404a2eeb8b..01044804d3e 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -146,6 +146,8 @@ RenderEngine *RE_engine_create_ex(RenderEngineType *type, bool use_for_viewport)
BLI_threaded_malloc_begin();
}
+ BLI_mutex_init(&engine->update_render_passes_mutex);
+
return engine;
}
@@ -161,6 +163,8 @@ void RE_engine_free(RenderEngine *engine)
BLI_threaded_malloc_end();
}
+ BLI_mutex_end(&engine->update_render_passes_mutex);
+
MEM_freeN(engine);
}
@@ -724,7 +728,7 @@ int RE_engine_render(Render *re, int do_all)
engine->tile_y = re->party;
if (re->result->do_exr_tile)
- render_result_exr_file_begin(re);
+ render_result_exr_file_begin(re, engine);
if (type->update)
type->update(engine, re->main, re->scene);
@@ -745,19 +749,19 @@ int RE_engine_render(Render *re, int do_all)
BLI_rw_mutex_lock(&re->partsmutex, THREAD_LOCK_WRITE);
- /* re->engine becomes zero if user changed active render engine during render */
- if (!persistent_data || !re->engine) {
- RE_engine_free(engine);
- re->engine = NULL;
- }
-
if (re->result->do_exr_tile) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_save_empty_result_tiles(re);
- render_result_exr_file_end(re);
+ render_result_exr_file_end(re, engine);
BLI_rw_mutex_unlock(&re->resultmutex);
}
+ /* re->engine becomes zero if user changed active render engine during render */
+ if (!persistent_data || !re->engine) {
+ RE_engine_free(engine);
+ re->engine = NULL;
+ }
+
if (re->r.scemode & R_EXR_CACHE_FILE) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_exr_file_cache_write(re);
@@ -778,23 +782,27 @@ int RE_engine_render(Render *re, int do_all)
return 1;
}
-void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
- const char *name, int UNUSED(channels), const char *UNUSED(chanid), int type)
+void RE_engine_update_render_passes(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+ update_render_passes_cb_t callback)
{
- /* The channel information is currently not used, but is part of the API in case it's needed in the future. */
-
- if (!(scene && srl && engine)) {
+ if (!(scene && srl && engine && callback && engine->type->update_render_passes)) {
return;
}
- /* Register the pass in all scenes that have a render layer node for this layer.
- * Since multiple scenes can be used in the compositor, the code must loop over all scenes
- * and check whether their nodetree has a node that needs to be updated. */
- /* NOTE: using G_MAIN seems valid here,
- * unless we want to register that for every other temp Main we could generate??? */
- for (Scene *sce = G_MAIN->scene.first; sce; sce = sce->id.next) {
- if (sce->nodetree) {
- ntreeCompositRegisterPass(sce->nodetree, scene, srl, name, type);
- }
+ BLI_mutex_lock(&engine->update_render_passes_mutex);
+
+ engine->update_render_passes_cb = callback;
+ engine->type->update_render_passes(engine, scene, srl);
+
+ BLI_mutex_unlock(&engine->update_render_passes_mutex);
+}
+
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+ const char *name, int channels, const char *chanid, int type)
+{
+ if (!(scene && srl && engine && engine->update_render_passes_cb)) {
+ return;
}
+
+ engine->update_render_passes_cb(engine, scene, srl, name, channels, chanid, type);
}