Merged changes in the trunk up to revision 26856.
[blender-staging.git] / source / blender / render / intern / source / pipeline.c
index b357a17e244d2cd969dd762b5ab4f784d7f6f505..72b147e992762f21d71feac1d6a16cf23d373abc 100644 (file)
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2006 Blender Foundation.
  * All rights reserved.
@@ -48,8 +48,9 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_writeavi.h"      /* <------ should be replaced once with generic movie module */
-#include "BKE_sequence.h"
+#include "BKE_sequencer.h"
 #include "BKE_pointcache.h"
+#include "BKE_animsys.h"       /* <------ should this be here?, needed for sequencer update */
 
 #include "MEM_guardedalloc.h"
 
@@ -66,6 +67,9 @@
 
 #include "RE_pipeline.h"
 
+#include "FRS_freestyle.h"
+#include "FRS_freestyle_config.h"
+
 /* internal */
 #include "render_types.h"
 #include "renderpipeline.h"
 /* ********* globals ******** */
 
 /* here we store all renders */
-static struct ListBase RenderList= {NULL, NULL};
+static struct {
+       ListBase renderlist;
+
+       /* render slots */
+       int viewslot, renderingslot;
+
+       /* commandline thread override */
+       int threads;
+} RenderGlobal = {{NULL, NULL}, 0, 0, -1}; 
 
 /* hardcopy of current render, used while rendering for speed */
 Render R;
 
-/* commandline thread override */
-static int commandline_threads= -1;
-
 /* ********* alloc and free ******** */
 
 
@@ -129,8 +138,8 @@ static void result_nothing(void *unused, RenderResult *rr) {}
 static void result_rcti_nothing(void *unused, RenderResult *rr, volatile struct rcti *rect) {}
 static void stats_nothing(void *unused, RenderStats *rs) {}
 static void int_nothing(void *unused, int val) {}
-static int void_nothing(void *unused) {return 0;}
 static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);}
+static int default_break(void *unused) {return G.afbreek == 1;}
 
 int RE_RenderInProgress(Render *re)
 {
@@ -227,11 +236,11 @@ static void push_render_result(Render *re)
 /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
 static void pop_render_result(Render *re)
 {
-       
        if(re->result==NULL) {
                printf("pop render result error; no current result!\n");
                return;
        }
+
        if(re->pushedresult) {
                BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
 
@@ -308,6 +317,12 @@ static char *get_pass_name(int passtype, int channel)
                if(channel==2) return "Color.B";
                return "Color.A";
        }
+       if(passtype == SCE_PASS_EMIT) {
+               if(channel==-1) return "Emit";
+               if(channel==0) return "Emit.R";
+               if(channel==1) return "Emit.G";
+               return "Emit.B";
+       }
        if(passtype == SCE_PASS_DIFFUSE) {
                if(channel==-1) return "Diffuse";
                if(channel==0) return "Diffuse.R";
@@ -332,6 +347,18 @@ static char *get_pass_name(int passtype, int channel)
                if(channel==1) return "AO.G";
                return "AO.B";
        }
+       if(passtype == SCE_PASS_ENVIRONMENT) {
+               if(channel==-1) return "Environment";
+               if(channel==0) return "Environment.R";
+               if(channel==1) return "Environment.G";
+               return "Environment.B";
+       }
+       if(passtype == SCE_PASS_INDIRECT) {
+               if(channel==-1) return "Indirect";
+               if(channel==0) return "Indirect.R";
+               if(channel==1) return "Indirect.G";
+               return "Indirect.B";
+       }
        if(passtype == SCE_PASS_REFLECT) {
                if(channel==-1) return "Reflect";
                if(channel==0) return "Reflect.R";
@@ -389,6 +416,9 @@ static int passtype_from_name(char *str)
        if(strcmp(str, "Color")==0)
                return SCE_PASS_RGBA;
 
+       if(strcmp(str, "Emit")==0)
+               return SCE_PASS_EMIT;
+
        if(strcmp(str, "Diffuse")==0)
                return SCE_PASS_DIFFUSE;
 
@@ -401,6 +431,12 @@ static int passtype_from_name(char *str)
        if(strcmp(str, "AO")==0)
                return SCE_PASS_AO;
 
+       if(strcmp(str, "Environment")==0)
+               return SCE_PASS_ENVIRONMENT;
+
+       if(strcmp(str, "Indirect")==0)
+               return SCE_PASS_INDIRECT;
+
        if(strcmp(str, "Reflect")==0)
                return SCE_PASS_REFLECT;
 
@@ -571,12 +607,18 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
                        render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
                if(srl->passflag  & SCE_PASS_RGBA)
                        render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
+               if(srl->passflag  & SCE_PASS_EMIT)
+                       render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
                if(srl->passflag  & SCE_PASS_DIFFUSE)
                        render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
                if(srl->passflag  & SCE_PASS_SPEC)
                        render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
                if(srl->passflag  & SCE_PASS_AO)
                        render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
+               if(srl->passflag  & SCE_PASS_ENVIRONMENT)
+                       render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
+               if(srl->passflag  & SCE_PASS_INDIRECT)
+                       render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
                if(srl->passflag  & SCE_PASS_SHADOW)
                        render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
                if(srl->passflag  & SCE_PASS_REFLECT)
@@ -615,6 +657,7 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int
                rl->lay= (1<<20) -1;
                rl->layflag= 0x7FFF;    /* solid ztra halo strand */
                rl->passflag= SCE_PASS_COMBINED;
+               FRS_add_freestyle_config( srl );
                
                re->r.actlay= 0;
        }
@@ -955,13 +998,35 @@ static void read_render_result(Render *re, int sample)
 
 /* *************************************************** */
 
-Render *RE_GetRender(const char *name)
+void RE_SetViewSlot(int slot)
+{
+       RenderGlobal.viewslot = slot;
+}
+
+int RE_GetViewSlot(void)
+{
+       return RenderGlobal.viewslot;
+}
+
+static int re_get_slot(int slot)
+{
+       if(slot == RE_SLOT_VIEW)
+               return RenderGlobal.viewslot;
+       else if(slot == RE_SLOT_RENDERING)
+               return (G.rendering)? RenderGlobal.renderingslot: RenderGlobal.viewslot;
+
+       return slot;
+}
+
+Render *RE_GetRender(const char *name, int slot)
 {
        Render *re;
+
+       slot= re_get_slot(slot);
        
        /* search for existing renders */
-       for(re= RenderList.first; re; re= re->next) {
-               if(strncmp(re->name, name, RE_MAXNAME)==0) {
+       for(re= RenderGlobal.renderlist.first; re; re= re->next) {
+               if(strncmp(re->name, name, RE_MAXNAME)==0 && re->slot==slot) {
                        break;
                }
        }
@@ -1065,12 +1130,25 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
                int tot= rres.rectx*rres.recty;
                char *cp= (char *)rect;
                
-               for(;tot>0; tot--, cp+=4, fp+=4) {
-                       cp[0] = FTOCHAR(fp[0]);
-                       cp[1] = FTOCHAR(fp[1]);
-                       cp[2] = FTOCHAR(fp[2]);
-                       cp[3] = FTOCHAR(fp[3]);
+               if (re->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+                       /* Finally convert back to sRGB rendered image */ 
+                       for(;tot>0; tot--, cp+=4, fp+=4) {
+                               cp[0] = FTOCHAR(linearrgb_to_srgb(fp[0]));
+                               cp[1] = FTOCHAR(linearrgb_to_srgb(fp[1]));
+                               cp[2] = FTOCHAR(linearrgb_to_srgb(fp[2]));
+                               cp[3] = FTOCHAR(fp[3]);
+                       }
+               }
+               else {
+                       /* Color management is off : no conversion necessary */
+                       for(;tot>0; tot--, cp+=4, fp+=4) {
+                               cp[0] = FTOCHAR(fp[0]);
+                               cp[1] = FTOCHAR(fp[1]);
+                               cp[2] = FTOCHAR(fp[2]);
+                               cp[3] = FTOCHAR(fp[3]);
+                       }
                }
+
        }
        else
                /* else fill with black */
@@ -1079,40 +1157,35 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
        RE_ReleaseResultImage(re);
 }
 
-
 RenderStats *RE_GetStats(Render *re)
 {
        return &re->i;
 }
 
-Render *RE_NewRender(const char *name)
+Render *RE_NewRender(const char *name, int slot)
 {
        Render *re;
+
+       slot= re_get_slot(slot);
        
        /* only one render per name exists */
-       re= RE_GetRender(name);
+       re= RE_GetRender(name, slot);
        if(re==NULL) {
                
                /* new render data struct */
                re= MEM_callocN(sizeof(Render), "new render");
-               BLI_addtail(&RenderList, re);
+               BLI_addtail(&RenderGlobal.renderlist, re);
                strncpy(re->name, name, RE_MAXNAME);
+               re->slot= slot;
                BLI_rw_mutex_init(&re->resultmutex);
        }
        
-       /* prevent UI to draw old results */
-       BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-       RE_FreeRenderResult(re->result);
-       re->result= NULL;
-       re->result_ok= 0;
-       BLI_rw_mutex_unlock(&re->resultmutex);
-       
        /* set default empty callbacks */
        re->display_init= result_nothing;
        re->display_clear= result_nothing;
        re->display_draw= result_rcti_nothing;
        re->timecursor= int_nothing;
-       re->test_break= void_nothing;
+       re->test_break= default_break;
        re->error= print_error;
        if(G.background)
                re->stats_draw= stats_background;
@@ -1138,15 +1211,15 @@ void RE_FreeRender(Render *re)
        RE_FreeRenderResult(re->result);
        RE_FreeRenderResult(re->pushedresult);
        
-       BLI_remlink(&RenderList, re);
+       BLI_remlink(&RenderGlobal.renderlist, re);
        MEM_freeN(re);
 }
 
 /* exit blender */
 void RE_FreeAllRender(void)
 {
-       while(RenderList.first) {
-               RE_FreeRender(RenderList.first);
+       while(RenderGlobal.renderlist.first) {
+               RE_FreeRender(RenderGlobal.renderlist.first);
        }
 }
 
@@ -1155,7 +1228,7 @@ void RE_FreeAllRender(void)
 
 /* what doesn't change during entire render sequence */
 /* disprect is optional, if NULL it assumes full window render */
-void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy, rcti *disprect)
+void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect)
 {
        re->ok= TRUE;   /* maybe flag */
        
@@ -1181,62 +1254,77 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy
                                                                                  (re->rectx < 16 || re->recty < 16) )) {
                re->error(re->erh, "Image too small");
                re->ok= 0;
+               return;
        }
-       else {
+
 #ifdef WITH_OPENEXR
-               if(re->r.scemode & R_FULL_SAMPLE)
-                       re->r.scemode |= R_EXR_TILE_FILE;       /* enable automatic */
-#else
-               /* can't do this without openexr support */
+       if(re->r.scemode & R_FULL_SAMPLE)
+               re->r.scemode |= R_EXR_TILE_FILE;       /* enable automatic */
+
+       /* Until use_border is made compatible with save_buffers/full_sample, render without the later instead of not rendering at all.*/
+       if(re->r.mode & R_BORDER) 
+       {
                re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);
+       }
+
+#else
+       /* can't do this without openexr support */
+       re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE);
 #endif
-               
-               /* fullsample wants uniform osa levels */
-               if(source && (re->r.scemode & R_FULL_SAMPLE)) {
-                       /* but, if source has no full sample we disable it */
-                       if((source->r.scemode & R_FULL_SAMPLE)==0)
-                               re->r.scemode &= ~R_FULL_SAMPLE;
-                       else
-                               re->r.osa= re->osa= source->osa;
+       
+       /* fullsample wants uniform osa levels */
+       if(source && (re->r.scemode & R_FULL_SAMPLE)) {
+               /* but, if source has no full sample we disable it */
+               if((source->r.scemode & R_FULL_SAMPLE)==0)
+                       re->r.scemode &= ~R_FULL_SAMPLE;
+               else
+                       re->r.osa= re->osa= source->osa;
+       }
+       else {
+               /* check state variables, osa? */
+               if(re->r.mode & (R_OSA)) {
+                       re->osa= re->r.osa;
+                       if(re->osa>16) re->osa= 16;
                }
-               else {
-                       /* check state variables, osa? */
-                       if(re->r.mode & (R_OSA)) {
-                               re->osa= re->r.osa;
-                               if(re->osa>16) re->osa= 16;
-                       }
-                       else re->osa= 0;
+               else re->osa= 0;
+       }
+       
+       if (srl) {
+               int index = BLI_findindex(&re->r.layers, srl);
+               if (index != -1) {
+                       re->r.actlay = index;
+                       re->r.scemode |= (R_SINGLE_LAYER|R_COMP_RERENDER);
                }
-
-               /* always call, checks for gamma, gamma tables and jitter too */
-               make_sample_tables(re); 
+       }
                
-               /* if preview render, we try to keep old result */
-               BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+       /* always call, checks for gamma, gamma tables and jitter too */
+       make_sample_tables(re); 
+       
+       /* if preview render, we try to keep old result */
+       BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
 
-               if(re->r.scemode & R_PREVIEWBUTS) {
-                       if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
-                       else {
-                               RE_FreeRenderResult(re->result);
-                               re->result= NULL;
-                       }
-               }
+       if(re->r.scemode & R_PREVIEWBUTS) {
+               if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
                else {
-                       
-                       /* make empty render result, so display callbacks can initialize */
                        RE_FreeRenderResult(re->result);
-                       re->result= MEM_callocN(sizeof(RenderResult), "new render result");
-                       re->result->rectx= re->rectx;
-                       re->result->recty= re->recty;
+                       re->result= NULL;
                }
-
-               BLI_rw_mutex_unlock(&re->resultmutex);
-               
-               /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
-               re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx);
+       }
+       else {
                
-               RE_init_threadcount(re);
+               /* make empty render result, so display callbacks can initialize */
+               RE_FreeRenderResult(re->result);
+               re->result= MEM_callocN(sizeof(RenderResult), "new render result");
+               re->result->rectx= re->rectx;
+               re->result->recty= re->recty;
        }
+
+       BLI_rw_mutex_unlock(&re->resultmutex);
+       
+       /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */
+       re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx);
+       
+       RE_init_threadcount(re);
 }
 
 /* part of external api, not called for regular render pipeline */
@@ -1787,6 +1875,10 @@ static void do_render_3d(Render *re)
                if(!re->test_break(re->tbh))
                        add_halo_flare(re);
        
+       /* Freestyle  */
+       if( re->r.mode & R_EDGE_FRS && re->r.renderer==R_INTERN)
+               FRS_add_Freestyle(re);
+               
        /* free all render verts etc */
        RE_Database_Free(re);
 }
@@ -1881,20 +1973,20 @@ static void do_render_blur_3d(Render *re)
 {
        RenderResult *rres;
        float blurfac;
-       int blur= re->r.osa;
+       int blur= re->r.mblur_samples;
        
        /* create accumulation render result */
        rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
        
        /* do the blur steps */
        while(blur--) {
-               set_mblur_offs( re->r.blurfac*((float)(re->r.osa-blur))/(float)re->r.osa );
+               set_mblur_offs( re->r.blurfac*((float)(re->r.mblur_samples-blur))/(float)re->r.mblur_samples );
                
-               re->i.curblur= re->r.osa-blur;  /* stats */
+               re->i.curblur= re->r.mblur_samples-blur;        /* stats */
                
                do_render_3d(re);
                
-               blurfac= 1.0f/(float)(re->r.osa-blur);
+               blurfac= 1.0f/(float)(re->r.mblur_samples-blur);
                
                merge_renderresult_blur(rres, re->result, blurfac, re->r.alphamode & R_ALPHAKEY);
                if(re->test_break(re->tbh)) break;
@@ -2007,7 +2099,6 @@ static void do_render_fields_3d(Render *re)
 
        BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
        re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
-       RE_FreeRenderResult(rr1);
 
        if(rr2) {
                if(re->r.mode & R_ODDFIELD)
@@ -2017,6 +2108,8 @@ static void do_render_fields_3d(Render *re)
                
                RE_FreeRenderResult(rr2);
        }
+
+       RE_FreeRenderResult(rr1);
        
        re->i.curfield= 0;      /* stats */
        
@@ -2036,7 +2129,7 @@ static void load_backbuffer(Render *re)
                
                strcpy(name, re->r.backbuf);
                BLI_convertstringcode(name, G.sce);
-               BLI_convertstringframe(name, re->r.cfra);
+               BLI_convertstringframe(name, re->r.cfra, 0);
                
                if(re->backbuf) {
                        re->backbuf->id.us--;
@@ -2130,7 +2223,7 @@ static void do_render_fields_blur_3d(Render *re)
 */
 static void render_scene(Render *re, Scene *sce, int cfra)
 {
-       Render *resc= RE_NewRender(sce->id.name);
+       Render *resc= RE_NewRender(sce->id.name, RE_SLOT_RENDERING);
        int winx= re->winx, winy= re->winy;
        
        sce->r.cfra= cfra;
@@ -2142,7 +2235,7 @@ static void render_scene(Render *re, Scene *sce, int cfra)
        }
        
        /* initial setup */
-       RE_InitState(resc, re, &sce->r, winx, winy, &re->disprect);
+       RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect);
        
        /* still unsure entity this... */
        resc->scene= sce;
@@ -2257,7 +2350,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
                        Render *re1;
                        
                        tag_scenes_for_render(re);
-                       for(re1= RenderList.first; re1; re1= re1->next) {
+                       for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
                                if(re1->scene->id.flag & LIB_DOIT)
                                        if(re1->r.scemode & R_FULL_SAMPLE)
                                                read_render_result(re1, sample);
@@ -2284,6 +2377,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
                        float *col= rres.rectf + 4*y*re->rectx;
                                
                        for(x=0; x<re->rectx; x++, rf+=4, col+=4) {
+                               /* clamping to 1.0 is needed for correct AA */
                                if(col[0]<0.0f) col[0]=0.0f; else if(col[0] > 1.0f) col[0]= 1.0f;
                                if(col[1]<0.0f) col[1]=0.0f; else if(col[1] > 1.0f) col[1]= 1.0f;
                                if(col[2]<0.0f) col[2]=0.0f; else if(col[2] > 1.0f) col[2]= 1.0f;
@@ -2351,6 +2445,7 @@ void RE_MergeFullSample(Render *re, Scene *sce, bNodeTree *ntree)
 static void do_render_composite_fields_blur_3d(Render *re)
 {
        bNodeTree *ntree= re->scene->nodetree;
+       int update_newframe=0;
        
        /* INIT seeding, compositor can use random texture */
        BLI_srandom(re->r.cfra);
@@ -2360,6 +2455,9 @@ static void do_render_composite_fields_blur_3d(Render *re)
                ntreeFreeCache(ntree);
                
                do_render_fields_blur_3d(re);
+       } else {
+               /* scene render process already updates animsys */
+               update_newframe = 1;
        }
        
        /* swap render result */
@@ -2388,10 +2486,14 @@ static void do_render_composite_fields_blur_3d(Render *re)
                                        R.sdh= re->sdh;
                                        R.stats_draw= re->stats_draw;
                                        
+                                       if (update_newframe)
+                                               scene_update_for_newframe(re->scene, re->scene->lay);
+                                       
                                        if(re->r.scemode & R_FULL_SAMPLE) 
                                                do_merge_fullsample(re, ntree);
-                                       else
+                                       else {
                                                ntreeCompositExecTree(ntree, &re->r, G.background==0);
+                                       }
                                        
                                        ntree->stats_draw= NULL;
                                        ntree->test_break= NULL;
@@ -2411,7 +2513,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
 static void renderresult_stampinfo(Scene *scene)
 {
        RenderResult rres;
-       Render *re= RE_GetRender(scene->id.name);
+       Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
 
        /* this is the basic trick to get the displayed float or char rect from render result */
        RE_AcquireResultImage(re, &rres);
@@ -2426,6 +2528,11 @@ static void do_render_seq(Render * re)
        RenderResult *rr = re->result;
        int cfra = re->r.cfra;
 
+       if(recurs_depth==0) {
+               /* otherwise sequencer animation isnt updated */
+               BKE_animsys_evaluate_all_animation(G.main, (float)cfra); // XXX, was frame_to_float(re->scene, cfra)
+       }
+
        recurs_depth++;
 
        ibuf= give_ibuf_seq(re->scene, rr->rectx, rr->recty, cfra, 0, 100.0);
@@ -2485,6 +2592,12 @@ static void do_render_seq(Render * re)
 /* main loop: doing sequence + fields + blur + 3d render + compositing */
 static void do_render_all_options(Render *re)
 {
+#ifdef DURIAN_CAMERA_SWITCH
+       Object *camera= scene_find_camera_switch(re->scene);
+       if(camera)
+               re->scene->camera= camera;
+#endif
+
        re->i.starttime= PIL_check_seconds_timer();
 
        /* ensure no images are in memory from previous animated sequences */
@@ -2540,10 +2653,6 @@ static int is_rendering_allowed(Render *re)
                        re->error(re->erh, "No border area selected.");
                        return 0;
                }
-               if(re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) {
-                       re->error(re->erh, "Border render and Buffer-save not supported yet");
-                       return 0;
-               }
        }
        
        if(re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) {
@@ -2643,7 +2752,7 @@ static void update_physics_cache(Render *re, Scene *scene, int anim_init)
        BKE_ptcache_make_cache(&baker);
 }
 /* evaluating scene options for general Blender render */
-static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int anim_init)
+static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLayer *srl, int anim, int anim_init)
 {
        int winx, winy;
        rcti disprect;
@@ -2690,10 +2799,10 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int
                update_physics_cache(re, scene, anim_init);
        }
        
-       if(scene->r.scemode & R_SINGLE_LAYER)
+       if(srl || scene->r.scemode & R_SINGLE_LAYER)
                push_render_result(re);
        
-       RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
+       RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect);
        if(!re->ok)  /* if an error was printed, abort */
                return 0;
        
@@ -2710,27 +2819,30 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int
 }
 
 /* general Blender frame render call */
-void RE_BlenderFrame(Render *re, Scene *scene, int frame)
+void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame)
 {
        /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */
-       G.rendering= 1;
+       RenderGlobal.renderingslot= re->slot;
        re->result_ok= 0;
+       G.rendering= 1;
        
        scene->r.cfra= frame;
        
-       if(render_initialize_from_scene(re, scene, 0, 0)) {
+       if(render_initialize_from_scene(re, scene, srl, 0, 0)) {
                do_render_all_options(re);
        }
        
        /* UGLY WARNING */
-       G.rendering= 0;
        re->result_ok= 1;
+       G.rendering= 0;
+       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
-static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
+static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports)
 {
        char name[FILE_MAX];
        RenderResult rres;
+       int ok= 1;
        
        RE_AcquireResultImage(re, &rres);
 
@@ -2743,14 +2855,14 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                        dofree = 1;
                }
                RE_ResultGet32(re, (unsigned int *)rres.rect32);
-               mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty);
+               ok= mh->append_movie(&re->r, scene->r.cfra, rres.rect32, rres.rectx, rres.recty, reports);
                if(dofree) {
                        MEM_freeN(rres.rect32);
                }
                printf("Append frame %d", scene->r.cfra);
        } 
        else {
-               BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+               BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION);
                
                if(re->r.imtype==R_MULTILAYER) {
                        if(re->result) {
@@ -2760,7 +2872,6 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                }
                else {
                        ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0);
-                       int ok;
                        
                        /* if not exists, BKE_write_ibuf makes one */
                        ibuf->rect= (unsigned int *)rres.rect32;    
@@ -2769,15 +2880,23 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                        
                        /* float factor for random dither, imbuf takes care of it */
                        ibuf->dither= scene->r.dither_intensity;
-                       /* gamma correct to sRGB color space */
-                       if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
-                               ibuf->profile = IB_PROFILE_SRGB;
+                       
+                       /* prepare to gamma correct to sRGB color space */
+                       if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
+                               /* sequence editor can generate 8bpc render buffers */
+                               if (ibuf->rect) {
+                                       ibuf->profile = IB_PROFILE_SRGB;
+                                       if (ELEM(scene->r.imtype, R_OPENEXR, R_RADHDR))
+                                               IMB_float_from_rect(ibuf);
+                               } else {                                
+                                       ibuf->profile = IB_PROFILE_LINEAR_RGB;
+                               }
+                       }
 
                        ok= BKE_write_ibuf(scene, ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality);
                        
                        if(ok==0) {
                                printf("Render error: cannot save %s\n", name);
-                               G.afbreek=1;
                        }
                        else printf("Saved: %s", name);
                        
@@ -2785,7 +2904,7 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
                        if(ok && scene->r.imtype==R_OPENEXR && (scene->r.subimtype & R_PREVIEW_JPG)) {
                                if(BLI_testextensie(name, ".exr")) 
                                        name[strlen(name)-4]= 0;
-                               BKE_add_image_extension(scene, name, R_JPEG90);
+                               BKE_add_image_extension(name, R_JPEG90);
                                ibuf->depth= 24; 
                                BKE_write_ibuf(scene, ibuf, name, R_JPEG90, scene->r.subimtype, scene->r.quality);
                                printf("\nSaved: %s", name);
@@ -2801,10 +2920,12 @@ static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh)
        BLI_timestr(re->i.lastframetime, name);
        printf(" Time: %s\n", name);
        fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */
+
+       return ok;
 }
 
 /* saves images to disk */
-void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
+void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, ReportList *reports)
 {
        bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
        unsigned int lay;
@@ -2812,27 +2933,30 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
        int nfra;
        
        /* do not fully call for each frame, it initializes & pops output window */
-       if(!render_initialize_from_scene(re, scene, 0, 1))
+       if(!render_initialize_from_scene(re, scene, NULL, 0, 1))
                return;
        
        /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
        /* is also set by caller renderwin.c */
        G.rendering= 1;
+       RenderGlobal.renderingslot= re->slot;
        re->result_ok= 0;
        
        if(BKE_imtype_is_movie(scene->r.imtype))
-               mh->start_movie(scene, &re->r, re->rectx, re->recty);
-       
+               if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, reports))
+                       G.afbreek= 1;
+
        if (mh->get_next_frame) {
                while (!(G.afbreek == 1)) {
-                       int nf = mh->get_next_frame(&re->r);
+                       int nf = mh->get_next_frame(&re->r, reports);
                        if (nf >= 0 && nf >= scene->r.sfra && nf <= scene->r.efra) {
                                scene->r.cfra = re->r.cfra = nf;
                                
                                do_render_all_options(re);
 
                                if(re->test_break(re->tbh) == 0) {
-                                       do_write_image_or_movie(re, scene, mh);
+                                       if(!do_write_image_or_movie(re, scene, mh, reports))
+                                               G.afbreek= 1;
                                }
                        } else {
                                if(re->test_break(re->tbh))
@@ -2844,7 +2968,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
                        char name[FILE_MAX];
                        
                        /* only border now, todo: camera lens. (ton) */
-                       render_initialize_from_scene(re, scene, 1, 0);
+                       render_initialize_from_scene(re, scene, NULL, 1, 0);
 
                        if(nfra!=scene->r.cfra) {
                                /*
@@ -2866,7 +2990,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
                        /* Touch/NoOverwrite options are only valid for image's */
                        if(BKE_imtype_is_movie(scene->r.imtype) == 0) {
                                if(scene->r.mode & (R_NO_OVERWRITE | R_TOUCH))
-                                       BKE_makepicstring(scene, name, scene->r.pic, scene->r.cfra, scene->r.imtype);
+                                       BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype, scene->r.scemode & R_EXTENSION);
 
                                if(scene->r.mode & R_NO_OVERWRITE && BLI_exist(name)) {
                                        printf("skipping existing frame \"%s\"\n", name);
@@ -2882,8 +3006,11 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
                        
                        do_render_all_options(re);
                        
-                       if(re->test_break(re->tbh) == 0)
-                               do_write_image_or_movie(re, scene, mh);
+                       if(re->test_break(re->tbh) == 0) {
+                               if(!G.afbreek)
+                                       if(!do_write_image_or_movie(re, scene, mh, reports))
+                                               G.afbreek= 1;
+                       }
                        else
                                G.afbreek= 1;
                
@@ -2909,6 +3036,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra)
        /* UGLY WARNING */
        G.rendering= 0;
        re->result_ok= 1;
+       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
 /* note; repeated win/disprect calc... solve that nicer, also in compo */
@@ -2942,10 +3070,10 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
                scene= scenode;
        
        /* get render: it can be called from UI with draw callbacks */
-       re= RE_GetRender(scene->id.name);
+       re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
        if(re==NULL)
-               re= RE_NewRender(scene->id.name);
-       RE_InitState(re, NULL, &scene->r, winx, winy, &disprect);
+               re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
+       RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
        re->scene= scene;
        
        read_render_result(re, 0);
@@ -2954,9 +3082,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
 void RE_set_max_threads(int threads)
 {
        if (threads==0) {
-               commandline_threads = BLI_system_thread_count();
+               RenderGlobal.threads = BLI_system_thread_count();
        } else if(threads>=1 && threads<=BLENDER_MAX_THREADS) {
-               commandline_threads= threads;
+               RenderGlobal.threads= threads;
        } else {
                printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS);
        }
@@ -2964,9 +3092,9 @@ void RE_set_max_threads(int threads)
 
 void RE_init_threadcount(Render *re) 
 {
-        if(commandline_threads >= 1) { /* only set as an arg in background mode */
-               re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
-       } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+       if(RenderGlobal.threads >= 1) { /* only set as an arg in background mode */
+               re->r.threads= MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS);
+       } else if ((re->r.mode & R_FIXED_THREADS)==0 || RenderGlobal.threads == 0) { /* Automatic threads */
                re->r.threads = BLI_system_thread_count();
        }
 }