svn merge ^/trunk/blender -r48674:48681
[blender.git] / source / blender / render / intern / source / external_engine.c
index e3eab0c3b345a97f5b7ab5bfa02a3d7eae4e54c6..2b5ccae7df715415fb6be4d72a4d562acba6b112 100644 (file)
@@ -55,6 +55,7 @@
 #include "RE_engine.h"
 #include "RE_pipeline.h"
 
+#include "initrender.h"
 #include "render_types.h"
 #include "render_result.h"
 
@@ -149,7 +150,7 @@ void RE_engine_free(RenderEngine *engine)
 
 /* Render Results */
 
-RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)
+RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
 {
        Render *re = engine->re;
        RenderResult *result;
@@ -172,7 +173,9 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
        disprect.ymin = y;
        disprect.ymax = y + h;
 
-       result = render_result_new(re, &disprect, 0, RR_USE_MEM);
+       result = render_result_new(re, &disprect, 0, RR_USE_MEM, layername);
+
+       /* todo: make this thread safe */
 
        /* can be NULL if we CLAMP the width or height to 0 */
        if (result) {
@@ -197,21 +200,36 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
        }
 }
 
-void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
+void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
 {
        Render *re = engine->re;
+       RenderPart *pa;
 
        if (!result)
                return;
 
        /* merge. on break, don't merge in result for preview renders, looks nicer */
-       if (!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
-               render_result_merge(re->result, result);
+       if (!cancel) {
+               /* for exr tile render, detect tiles that are done */
+               for (pa = re->parts.first; pa; pa = pa->next) {
+                       if (result->tilerect.xmin == pa->disprect.xmin &&
+                          result->tilerect.ymin == pa->disprect.ymin &&
+                          result->tilerect.xmax == pa->disprect.xmax &&
+                          result->tilerect.ymax == pa->disprect.ymax) {
+                               pa->ready = 1;
+                       }
+               }
 
-       /* draw */
-       if (!re->test_break(re->tbh)) {
-               result->renlay = result->layers.first; // weak, draws first layer always
-               re->display_draw(re->ddh, result, NULL);
+               if (re->result->do_exr_tile)
+                       render_result_exr_file_merge(re->result, result);
+               else if (!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
+                       render_result_merge(re->result, result);
+
+               /* draw */
+               if (!re->test_break(re->tbh)) {
+                       result->renlay = result->layers.first; // weak, draws first layer always
+                       re->display_draw(re->ddh, result, NULL);
+               }
        }
 
        /* free */
@@ -294,12 +312,16 @@ int RE_engine_render(Render *re, int do_all)
        /* create render result */
        BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
        if (re->result == NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
+               int savebuffers;
+
                if (re->result)
                        render_result_free(re->result);
-               re->result = render_result_new(re, &re->disprect, 0, 0);
+
+               savebuffers = (re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM;
+               re->result = render_result_new(re, &re->disprect, 0, savebuffers, RR_ALL_LAYERS);
        }
        BLI_rw_mutex_unlock(&re->resultmutex);
-       
+
        if (re->result == NULL)
                return 1;
 
@@ -321,11 +343,29 @@ int RE_engine_render(Render *re, int do_all)
        if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_PREVIEWBUTS)) == 0)
                BKE_scene_update_for_newframe(re->main, re->scene, re->lay);
 
+       initparts(re, FALSE);
+       engine->tile_x = re->partx;
+       engine->tile_y = re->party;
+
+       if (re->result->do_exr_tile)
+               render_result_exr_file_begin(re);
+
        if (type->update)
                type->update(engine, re->main, re->scene);
+       
        if (type->render)
                type->render(engine, re->scene);
 
+       if (re->result->do_exr_tile) {
+               BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+               render_result_exr_file_end(re);
+               BLI_rw_mutex_unlock(&re->resultmutex);
+       }
+
+       engine->tile_x = 0;
+       engine->tile_y = 0;
+       freeparts(re);
+
        render_result_free_list(&engine->fullresult, engine->fullresult.first);
 
        RE_engine_free(engine);