Merge branch 'blender2.7'
authorLukas Stockner <lukas.stockner@freenet.de>
Fri, 18 Jan 2019 00:47:32 +0000 (01:47 +0100)
committerLukas Stockner <lukas.stockner@freenet.de>
Fri, 18 Jan 2019 00:47:32 +0000 (01:47 +0100)
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/include/render_result.h
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/render_result.c

index 856b876..ce41e30 100644 (file)
@@ -214,6 +214,23 @@ void node_cmp_rlayers_register_pass(bNodeTree *ntree, bNode *node, Scene *scene,
        }
 }
 
+static void cmp_node_rlayer_create_outputs_cb(RenderEngine *UNUSED(engine), Scene *scene, ViewLayer *view_layer,
+                                              const char *name, int UNUSED(channels), const char *UNUSED(chanid), int type)
+{
+       /* 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??? */
+       ntreeCompositRegisterPass(scene->nodetree, scene, view_layer, name, type);
+
+       for (Scene *sce = G_MAIN->scene.first; sce; sce = sce->id.next) {
+               if (sce->nodetree && sce != scene) {
+                       ntreeCompositRegisterPass(sce->nodetree, scene, view_layer, name, type);
+               }
+       }
+}
+
 static void cmp_node_rlayer_create_outputs(bNodeTree *ntree, bNode *node, LinkNodePair *available_sockets)
 {
        Scene *scene = (Scene *)node->id;
@@ -229,7 +246,7 @@ static void cmp_node_rlayer_create_outputs(bNodeTree *ntree, bNode *node, LinkNo
                                node->storage = data;
 
                                RenderEngine *engine = RE_engine_create(engine_type);
-                               engine_type->update_render_passes(engine, scene, view_layer);
+                               RE_engine_update_render_passes(engine, scene, view_layer, cmp_node_rlayer_create_outputs_cb);
                                RE_engine_free(engine);
 
                                MEM_freeN(data);
index faa4c8b..8a6282a 100644 (file)
@@ -37,6 +37,8 @@
 #include "RNA_types.h"
 #include "RE_bake.h"
 
+#include "BLI_threads.h"
+
 struct bNode;
 struct bNodeTree;
 struct BakePixel;
@@ -111,6 +113,9 @@ typedef struct RenderEngineType {
        ExtensionRNA ext;
 } RenderEngineType;
 
+typedef void (*update_render_passes_cb_t)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer,
+                                          const char *name, int channels, const char *chanid, int type);
+
 typedef struct RenderEngine {
        RenderEngineType *type;
        void *py_instance;
@@ -137,6 +142,10 @@ typedef struct RenderEngine {
        int update_flag;
        int job_update_flag;
 
+       /* callback for render pass query */
+       ThreadMutex update_render_passes_mutex;
+       update_render_passes_cb_t update_render_passes_cb;
+
        rctf last_viewplane;
        rcti last_disprect;
        float last_viewmat[4][4];
@@ -175,6 +184,8 @@ bool RE_engine_is_external(struct Render *re);
 
 void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe);
 
+void RE_engine_update_render_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer,
+                                    update_render_passes_cb_t callback);
 void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer,
                              const char *name, int channels, const char *chanid, int type);
 
index ab7eee1..707b1f6 100644 (file)
@@ -44,6 +44,7 @@ struct ImBuf;
 struct ListBase;
 struct Render;
 struct RenderData;
+struct RenderEngine;
 struct RenderLayer;
 struct RenderResult;
 struct Scene;
@@ -83,8 +84,8 @@ void render_result_single_layer_end(struct Render *re);
 /* EXR Tile File Render */
 
 void render_result_save_empty_result_tiles(struct Render *re);
-void render_result_exr_file_begin(struct Render *re);
-void render_result_exr_file_end(struct Render *re);
+void render_result_exr_file_begin(struct Render *re, struct RenderEngine *engine);
+void render_result_exr_file_end(struct Render *re, struct RenderEngine *engine);
 
 /* render pass wrapper for gpencil */
 struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, const char *name, const char *viewname);
@@ -92,7 +93,7 @@ struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl,
 void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, const char *viewname);
 
 void render_result_exr_file_path(struct Scene *scene, const char *layname, int sample, char *filepath);
-int render_result_exr_file_read_sample(struct Render *re, int sample);
+int render_result_exr_file_read_sample(struct Render *re, int sample, struct RenderEngine *engine);
 int render_result_exr_file_read_path(struct RenderResult *rr, struct RenderLayer *rl_single, const char *filepath);
 
 /* EXR cache */
index 283f4c4..7e53151 100644 (file)
@@ -150,6 +150,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;
 }
 
@@ -165,6 +167,8 @@ void RE_engine_free(RenderEngine *engine)
                BLI_threaded_malloc_end();
        }
 
+       BLI_mutex_end(&engine->update_render_passes_mutex);
+
        MEM_freeN(engine);
 }
 
@@ -711,7 +715,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);
 
        /* Clear UI drawing locks. */
        if (re->draw_lock) {
@@ -765,19 +769,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);
@@ -798,27 +802,29 @@ int RE_engine_render(Render *re, int do_all)
        return 1;
 }
 
-void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer,
-                             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 ViewLayer *view_layer,
+                                    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 && view_layer && engine)) {
+       if (!(scene && view_layer && 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??? */
-       ntreeCompositRegisterPass(scene->nodetree, scene, view_layer, name, type);
+       BLI_mutex_lock(&engine->update_render_passes_mutex);
 
-       for (Scene *sce = G_MAIN->scene.first; sce; sce = sce->id.next) {
-               if (sce->nodetree && sce != scene) {
-                       ntreeCompositRegisterPass(sce->nodetree, scene, view_layer, name, type);
-               }
+       engine->update_render_passes_cb = callback;
+       engine->type->update_render_passes(engine, scene, view_layer);
+
+       BLI_mutex_unlock(&engine->update_render_passes_mutex);
+}
+
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer,
+                             const char *name, int channels, const char *chanid, int type)
+{
+       if (!(scene && view_layer && engine && engine->update_render_passes_cb)) {
+               return;
        }
+
+       engine->update_render_passes_cb(engine, scene, view_layer, name, channels, chanid, type);
 }
 
 void RE_engine_free_blender_memory(RenderEngine *engine)
index 7efe0a5..9ec7054 100644 (file)
@@ -57,6 +57,8 @@
 
 #include "intern/openexr/openexr_multi.h"
 
+#include "RE_engine.h"
+
 #include "render_result.h"
 #include "render_types.h"
 
@@ -482,6 +484,7 @@ void render_result_add_pass(RenderResult *rr, const char *name, int channels, co
                        for (rp = rl->passes.first; rp; rp = rp->next) {
                                if (!STREQ(rp->name, name)) continue;
                                if (!STREQ(rp->view, view)) continue;
+                               break;
                        }
 
                        if (!rp) {
@@ -1063,8 +1066,25 @@ void render_result_save_empty_result_tiles(Render *re)
        }
 }
 
+static void render_result_register_pass_cb(RenderEngine *engine, Scene *UNUSED(scene), ViewLayer *view_layer,
+                                           const char *name, int channels, const char *chanid, int UNUSED(type))
+{
+       RE_engine_add_pass(engine, name, channels, chanid, view_layer->name);
+}
+
+static void render_result_create_all_passes(RenderEngine *engine, Render *re, RenderLayer *rl)
+{
+       if (engine && engine->type->update_render_passes) {
+               ViewLayer *view_layer;
+               view_layer = BLI_findstring(&re->view_layers, rl->name, offsetof(ViewLayer, name));
+               if (view_layer) {
+                       RE_engine_update_render_passes(engine, re->scene, view_layer, render_result_register_pass_cb);
+               }
+       }
+}
+
 /* begin write of exr tile file */
-void render_result_exr_file_begin(Render *re)
+void render_result_exr_file_begin(Render *re, RenderEngine *engine)
 {
        RenderResult *rr;
        RenderLayer *rl;
@@ -1072,6 +1092,8 @@ void render_result_exr_file_begin(Render *re)
 
        for (rr = re->result; rr; rr = rr->next) {
                for (rl = rr->layers.first; rl; rl = rl->next) {
+                       render_result_create_all_passes(engine, re, rl);
+
                        render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
                        printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
                        IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
@@ -1080,7 +1102,7 @@ void render_result_exr_file_begin(Render *re)
 }
 
 /* end write of exr tile file, read back first sample */
-void render_result_exr_file_end(Render *re)
+void render_result_exr_file_end(Render *re, RenderEngine *engine)
 {
        RenderResult *rr;
        RenderLayer *rl;
@@ -1097,7 +1119,7 @@ void render_result_exr_file_end(Render *re)
        render_result_free_list(&re->fullresult, re->result);
        re->result = NULL;
 
-       render_result_exr_file_read_sample(re, 0);
+       render_result_exr_file_read_sample(re, 0, engine);
 }
 
 /* save part into exr file */
@@ -1127,7 +1149,7 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample,
 }
 
 /* only for temp buffer, makes exact copy of render result */
-int render_result_exr_file_read_sample(Render *re, int sample)
+int render_result_exr_file_read_sample(Render *re, int sample, RenderEngine *engine)
 {
        RenderLayer *rl;
        char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
@@ -1137,6 +1159,8 @@ int render_result_exr_file_read_sample(Render *re, int sample)
        re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
 
        for (rl = re->result->layers.first; rl; rl = rl->next) {
+               render_result_create_all_passes(engine, re, rl);
+
                render_result_exr_file_path(re->scene, rl->name, sample, str);
                printf("read exr tmp file: %s\n", str);