Cycles: svn merge -r41157:41182 ^/trunk/blender
[blender.git] / source / blender / render / intern / source / pipeline.c
index 405779c360f5a422d87a5c52fd9c4db45f862cf2..864707d70609f64b68e0fe1c9943b12138ff464d 100644 (file)
@@ -73,6 +73,7 @@
 
 #include "intern/openexr/openexr_multi.h"
 
+#include "RE_engine.h"
 #include "RE_pipeline.h"
 
 /* internal */
@@ -215,7 +216,7 @@ void RE_FreeRenderResult(RenderResult *res)
 }
 
 /* version that's compatible with fullsample buffers */
-static void free_render_result(ListBase *lb, RenderResult *rr)
+void free_render_result(ListBase *lb, RenderResult *rr)
 {
        RenderResult *rrnext;
        
@@ -545,12 +546,11 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
        return NULL;
 }
 
-#define RR_USEMEM      0
 /* called by main render as well for parts */
 /* will read info from Render *re to define layers */
 /* called in threads */
 /* re->winx,winy is coordinate space of entire image, partrct the part within */
-static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
+RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
 {
        RenderResult *rr;
        RenderLayer *rl;
@@ -729,7 +729,7 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
 /* no test happens here if it fits... we also assume layers are in sync */
 /* is used within threads */
-static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
+void merge_render_result(RenderResult *rr, RenderResult *rrpart)
 {
        RenderLayer *rl, *rlp;
        RenderPass *rpass, *rpassp;
@@ -889,18 +889,39 @@ static void *ml_addlayer_cb(void *base, char *str)
 {
        RenderResult *rr= base;
        RenderLayer *rl;
+
+       /* don't add if layer already exists */
+       for(rl=rr->layers.first; rl; rl=rl->next)
+               if(strcmp(rl->name, str) == 0)
+                       return rl;
        
+       /* add render layer */
        rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
        BLI_addtail(&rr->layers, rl);
        
        BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
+       rl->rectx = rr->rectx;
+       rl->recty = rr->recty;
+
        return rl;
 }
-static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)
+static void ml_addpass_cb(void *base, void *lay, char *str, float *rect, int totchan, char *chan_id)
 {
+       RenderResult *rr= base;
        RenderLayer *rl= lay;   
-       RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
+       RenderPass *rpass;
        int a;
+
+       /* don't add if pass already exists */
+       for(rpass=rl->passes.first; rpass; rpass=rpass->next) {
+               if(strcmp(rpass->name, str) == 0) {
+                       MEM_freeN(rect);
+                       return;
+               }
+       }
+       
+       /* add render pass */
+       rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
        
        BLI_addtail(&rl->passes, rpass);
        rpass->channels= totchan;
@@ -914,6 +935,8 @@ static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect,
        for(a=0; a<totchan; a++)
                rpass->chan_id[a]= chan_id[a];
        
+       rpass->rectx = rr->rectx;
+       rpass->recty = rr->recty;
        rpass->rect= rect;
 }
 
@@ -921,24 +944,12 @@ static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect,
 RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty)
 {
        RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
-       RenderLayer *rl;
-       RenderPass *rpass;
        
        rr->rectx= rectx;
        rr->recty= recty;
        
        IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
 
-       for(rl=rr->layers.first; rl; rl=rl->next) {
-               rl->rectx= rectx;
-               rl->recty= recty;
-
-               for(rpass=rl->passes.first; rpass; rpass=rpass->next) {
-                       rpass->rectx= rectx;
-                       rpass->recty= recty;
-               }
-       }
-       
        return rr;
 }
 
@@ -954,7 +965,7 @@ static void renderresult_add_names(RenderResult *rr)
 }
 
 /* called for reading temp files, and for external engines */
-static int read_render_result_from_file(const char *filename, RenderResult *rr)
+static int read_render_result_from_file(const char *filename, RenderResult *rr, int external)
 {
        RenderLayer *rl;
        RenderPass *rpass;
@@ -998,7 +1009,7 @@ static int read_render_result_from_file(const char *filename, RenderResult *rr)
                IMB_exr_read_channels(exrhandle);
                renderresult_add_names(rr);
        }
-       
+
        IMB_exr_close(exrhandle);
 
        return 1;
@@ -1018,7 +1029,7 @@ static int read_render_result(Render *re, int sample)
        render_unique_exr_name(re, str, sample);
        printf("read exr tmp file: %s\n", str);
 
-       if(read_render_result_from_file(str, re->result)) {
+       if(read_render_result_from_file(str, re->result, 0)) {
                success= TRUE;
        }
        else {
@@ -1811,12 +1822,10 @@ void RE_TileProcessor(Render *re)
 
 /* ************  This part uses API, for rendering Blender scenes ********** */
 
-static int external_render_3d(Render *re, int do_all);
-
 static void do_render_3d(Render *re)
 {
        /* try external */
-       if(external_render_3d(re, 0))
+       if(RE_engine_render(re, 0))
                return;
 
        /* internal */
@@ -2648,7 +2657,7 @@ static void do_render_all_options(Render *re)
        /* ensure no images are in memory from previous animated sequences */
        BKE_image_all_free_anim_ibufs(re->r.cfra);
 
-       if(external_render_3d(re, 1)) {
+       if(RE_engine_render(re, 1)) {
                /* in this case external render overrides all */
        }
        else if(seq_render_active(re)) {
@@ -3279,106 +3288,6 @@ void RE_init_threadcount(Render *re)
        }
 }
 
-/************************** External Engines ***************************/
-
-RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h)
-{
-       Render *re= engine->re;
-       RenderResult *result;
-       rcti disprect;
-
-       /* ensure the coordinates are within the right limits */
-       CLAMP(x, 0, re->result->rectx);
-       CLAMP(y, 0, re->result->recty);
-       CLAMP(w, 0, re->result->rectx);
-       CLAMP(h, 0, re->result->recty);
-
-       if(x + w > re->result->rectx)
-               w= re->result->rectx - x;
-       if(y + h > re->result->recty)
-               h= re->result->recty - y;
-
-       /* allocate a render result */
-       disprect.xmin= x;
-       disprect.xmax= x+w;
-       disprect.ymin= y;
-       disprect.ymax= y+h;
-
-       if(0) { // XXX (re->r.scemode & R_FULL_SAMPLE)) {
-               result= new_full_sample_buffers(re, &engine->fullresult, &disprect, 0);
-       }
-       else {
-               result= new_render_result(re, &disprect, 0, RR_USEMEM);
-               BLI_addtail(&engine->fullresult, result);
-       }
-
-       return result;
-}
-
-void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
-{
-       Render *re= engine->re;
-
-       if(result && render_display_draw_enabled(re)) {
-               result->renlay= result->layers.first; // weak
-               re->display_draw(re->ddh, result, NULL);
-       }
-}
-
-void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
-{
-       Render *re= engine->re;
-
-       if(!result)
-               return;
-
-       /* merge */
-       if(re->result->exrhandle) {
-               RenderResult *rr, *rrpart;
-               
-               // XXX crashes, exr expects very particular part sizes
-               for(rr= re->result, rrpart= result; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
-                       save_render_result_tile(rr, rrpart);
-       }
-       else if(render_display_draw_enabled(re)) {
-               /* on break, don't merge in result for preview renders, looks nicer */
-               if(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS));
-               else merge_render_result(re->result, result);
-       }
-
-       /* draw */
-       if(!re->test_break(re->tbh) && render_display_draw_enabled(re)) {
-               result->renlay= result->layers.first; // weak
-               re->display_draw(re->ddh, result, NULL);
-       }
-
-       /* free */
-       free_render_result(&engine->fullresult, result);
-}
-
-int RE_engine_test_break(RenderEngine *engine)
-{
-       Render *re= engine->re;
-
-       return re->test_break(re->tbh);
-}
-
-void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
-{
-       Render *re= engine->re;
-
-       re->i.statstr= stats;
-       re->i.infostr= info;
-       re->stats_draw(re->sdh, &re->i);
-       re->i.infostr= NULL;
-       re->i.statstr= NULL;
-}
-
-void RE_engine_report(RenderEngine *engine, int type, const char *msg)
-{
-       BKE_report(engine->re->reports, type, msg);
-}
-
 /* loads in image into a result, size must match
  * x/y offsets are only used on a partial copy when dimensions dont match */
 void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
@@ -3423,68 +3332,22 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char
 
 void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename)
 {
-       if(!read_render_result_from_file(filename, result)) {
-               BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename);
-               return;
-       }
-}
+       /* optionally also add layers/passes that were in the file but not setup
+          for rendering, useful for external render engines or network render */
+       void *exrhandle= IMB_exr_get_handle();
+       int rectx, recty;
 
-static int external_render_3d(Render *re, int do_all)
-{
-       RenderEngineType *type= BLI_findstring(&R_engines, re->r.engine, offsetof(RenderEngineType, idname));
-       RenderEngine engine;
+       if(IMB_exr_begin_read(exrhandle, filename, &rectx, &recty))
+               IMB_exr_multilayer_convert(exrhandle, result, ml_addlayer_cb, ml_addpass_cb);
 
-       if(!(type && type->render))
-               return 0;
-       if((re->r.scemode & R_PREVIEWBUTS) && !(type->flag & RE_DO_PREVIEW))
-               return 0;
-       if(do_all && !(type->flag & RE_DO_ALL))
-               return 0;
-       if(!do_all && (type->flag & RE_DO_ALL))
-               return 0;
-
-       BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-       if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
-               RE_FreeRenderResult(re->result);
-       
-               if(0) // XXX re->r.scemode & R_FULL_SAMPLE)
-                       re->result= new_full_sample_buffers_exr(re);
-               else
-                       re->result= new_render_result(re, &re->disprect, 0, 0); // XXX re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE));
-       }
-       BLI_rw_mutex_unlock(&re->resultmutex);
+       IMB_exr_close(exrhandle);
        
-       if(re->result==NULL)
-               return 1;
-
-       /* external */
-       memset(&engine, 0, sizeof(engine));
-       engine.type= type;
-       engine.re= re;
-
-       type->render(&engine, re->scene);
-
-       free_render_result(&engine.fullresult, engine.fullresult.first);
-
-       BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-       if(re->result->exrhandle) {
-               RenderResult *rr;
-
-               save_empty_result_tiles(re);
-               
-               for(rr= re->result; rr; rr= rr->next) {
-                       IMB_exr_close(rr->exrhandle);
-                       rr->exrhandle= NULL;
-               }
-               
-               free_render_result(&re->fullresult, re->result);
-               re->result= NULL;
-               
-               read_render_result(re, 0);
+#if 0
+       if(!read_render_result_from_file(filename, result, 1)) {
+               BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename);
+               return;
        }
-       BLI_rw_mutex_unlock(&re->resultmutex);
-
-       return 1;
+#endif
 }
 
 const float default_envmap_layout[] = { 0,0, 1,0, 2,0, 0,1, 1,1, 2,1 };
@@ -3544,3 +3407,4 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
                return FALSE;
        }
 }
+