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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp194
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.h26
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_multi.h74
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h9
-rw-r--r--source/blender/render/intern/source/pipeline.c281
-rw-r--r--source/blender/src/sequence.c2
7 files changed, 444 insertions, 144 deletions
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 13ac8b14edf..8c0bbb66911 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -42,6 +42,9 @@ extern "C"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_allocimbuf.h"
+
+#define WITH_OPENEXR
+#include "openexr_multi.h"
}
#include <iostream>
@@ -333,103 +336,213 @@ short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags)
/* ********************* Tile file support ************************************ */
-typedef struct ExrTileHandle {
- TiledOutputFile *file;
+typedef struct ExrHandle {
+ InputFile *ifile;
+ TiledOutputFile *tofile;
+ OutputFile *ofile;
int tilex, tiley;
int width, height;
ListBase channels;
-} ExrTileHandle;
+} ExrHandle;
-typedef struct ExrTileChannel {
- struct ExrTileChannel *next, *prev;
- char *name;
+#define CHANMAXNAME 64
+typedef struct ExrChannel {
+ struct ExrChannel *next, *prev;
+ char name[2*CHANMAXNAME + 1];
int xstride, ystride;
float *rect;
-} ExrTileChannel;
+} ExrChannel;
/* not threaded! write one tiled file at a time */
-void *imb_exrtile_get_handle(void)
+void *IMB_exr_get_handle(void)
{
- static ExrTileHandle data;
+ static ExrHandle data;
+
+ memset(&data, sizeof(ExrHandle), 0);
- data.channels.first= data.channels.last= NULL;
return &data;
}
-void imb_exrtile_add_channel(void *handle, char *channame)
+/* still clumsy name handling, layers/channels can be ordered as list in list later */
+void IMB_exr_add_channel(void *handle, const char *layname, const char *channame)
{
- ExrTileHandle *data= (ExrTileHandle *)handle;
- ExrTileChannel *echan;
+ ExrHandle *data= (ExrHandle *)handle;
+ ExrChannel *echan;
- echan= (ExrTileChannel *)MEM_callocN(sizeof(ExrTileChannel), "exr tile channel");
- echan->name= channame;
+ echan= (ExrChannel *)MEM_callocN(sizeof(ExrChannel), "exr tile channel");
+
+ if(layname) {
+ char lay[CHANMAXNAME], chan[CHANMAXNAME];
+ strncpy(lay, layname, CHANMAXNAME-1);
+ strncpy(chan, channame, CHANMAXNAME-1);
+
+ sprintf(echan->name, "%s.%s", lay, chan);
+ }
+ else
+ strncpy(echan->name, channame, 2*CHANMAXNAME);
+ printf("added channel %s\n", echan->name);
BLI_addtail(&data->channels, echan);
}
-void imb_exrtile_begin_write(void *handle, char *filename, int width, int height, int tilex, int tiley)
+void IMB_exr_begin_write(void *handle, char *filename, int width, int height)
{
- ExrTileHandle *data= (ExrTileHandle *)handle;
+ ExrHandle *data= (ExrHandle *)handle;
Header header (width, height);
- ExrTileChannel *echan;
+ ExrChannel *echan;
+
+ data->width= width;
+ data->height= height;
+
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
+ header.channels().insert (echan->name, Channel (FLOAT));
+
+ header.insert ("comments", StringAttribute ("Blender MultiChannel"));
+
+ data->ofile = new OutputFile(filename, header);
+}
+
+void IMB_exrtile_begin_write(void *handle, char *filename, int width, int height, int tilex, int tiley)
+{
+ ExrHandle *data= (ExrHandle *)handle;
+ Header header (width, height);
+ ExrChannel *echan;
data->tilex= tilex;
data->tiley= tiley;
data->width= width;
data->height= height;
- for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next)
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
header.channels().insert (echan->name, Channel (FLOAT));
header.setTileDescription (TileDescription (tilex, tiley, ONE_LEVEL));
+ header.lineOrder() = RANDOM_Y,
+ header.compression() = NO_COMPRESSION;
- header.insert ("comments", StringAttribute ("Blender RenderResult"));
+ header.insert ("comments", StringAttribute ("Blender MultiChannel"));
- data->file = new TiledOutputFile(filename, header);
+ data->tofile = new TiledOutputFile(filename, header);
}
+int IMB_exr_begin_read(void *handle, char *filename, int *width, int *height)
+{
+ ExrHandle *data= (ExrHandle *)handle;
+
+ data->ifile = new InputFile(filename);
+ if(data->ifile) {
+ Box2i dw = data->ifile->header().dataWindow();
+ data->width= *width = dw.max.x - dw.min.x + 1;
+ data->height= *height = dw.max.y - dw.min.y + 1;
+
+ const ChannelList &channels = data->ifile->header().channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+ IMB_exr_add_channel(data, NULL, i.name());
+
+ return 1;
+ }
+ return 0;
+}
-void imb_exrtile_set_channel(void *handle, char *channame, int xstride, int ystride, float *rect)
+/* still clumsy name handling, layers/channels can be ordered as list in list later */
+void IMB_exr_set_channel(void *handle, char *layname, char *channame, int xstride, int ystride, float *rect)
{
- ExrTileHandle *data= (ExrTileHandle *)handle;
- ExrTileChannel *echan;
+ ExrHandle *data= (ExrHandle *)handle;
+ ExrChannel *echan;
+ char name[2*CHANMAXNAME + 1];
- for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next)
- if(strcmp(echan->name, channame)==0)
+ if(layname) {
+ char lay[CHANMAXNAME], chan[CHANMAXNAME];
+ strncpy(lay, layname, CHANMAXNAME-1);
+ strncpy(chan, channame, CHANMAXNAME-1);
+
+ sprintf(name, "%s.%s", lay, chan);
+ }
+ else
+ strncpy(name, channame, 2*CHANMAXNAME);
+
+
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
+ if(strcmp(echan->name, name)==0)
break;
+
if(echan) {
echan->xstride= xstride;
echan->ystride= ystride;
echan->rect= rect;
}
else
- printf("imb_exrtile_set_channel error\n");
+ printf("IMB_exrtile_set_channel error %s\n", name);
}
-void imb_exrtile_write_channels(void *handle, int partx, int party)
+void IMB_exrtile_write_channels(void *handle, int partx, int party)
{
- ExrTileHandle *data= (ExrTileHandle *)handle;
+ ExrHandle *data= (ExrHandle *)handle;
FrameBuffer frameBuffer;
- ExrTileChannel *echan;
+ ExrChannel *echan;
- for(echan= (ExrTileChannel *)data->channels.first; echan; echan= echan->next) {
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
float *rect= echan->rect - echan->xstride*partx - echan->ystride*party;
frameBuffer.insert (echan->name, Slice (FLOAT, (char *)rect,
echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
}
- data->file->setFrameBuffer (frameBuffer);
+ data->tofile->setFrameBuffer (frameBuffer);
printf("write tile %d %d\n", partx/data->tilex, party/data->tiley);
- data->file->writeTile (partx/data->tilex, party/data->tiley);
+ data->tofile->writeTile (partx/data->tilex, party/data->tiley);
}
-void imb_exrtile_close(void *handle)
+void IMB_exr_write_channels(void *handle)
{
- ExrTileHandle *data= (ExrTileHandle *)handle;
+ ExrHandle *data= (ExrHandle *)handle;
+ FrameBuffer frameBuffer;
+ ExrChannel *echan;
- delete data->file;
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next)
+ frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect,
+ echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
+
+ data->ofile->setFrameBuffer (frameBuffer);
+ data->ofile->writePixels (data->height);
+
+}
+
+void IMB_exr_read_channels(void *handle)
+{
+ ExrHandle *data= (ExrHandle *)handle;
+ FrameBuffer frameBuffer;
+ ExrChannel *echan;
+
+ for(echan= (ExrChannel *)data->channels.first; echan; echan= echan->next) {
+ /* no datawindow correction needed */
+ if(echan->rect)
+ frameBuffer.insert (echan->name, Slice (FLOAT, (char *)echan->rect,
+ echan->xstride*sizeof(float), echan->ystride*sizeof(float)));
+ }
+
+ data->ifile->setFrameBuffer (frameBuffer);
+ data->ifile->readPixels (0, data->height-1);
+}
+
+
+void IMB_exr_close(void *handle)
+{
+ ExrHandle *data= (ExrHandle *)handle;
+ ExrChannel *echan;
+
+ if(data->ifile)
+ delete data->ifile;
+ else if(data->ofile)
+ delete data->ofile;
+ else if(data->tofile)
+ delete data->tofile;
+
+ data->ifile= NULL;
+ data->ofile= NULL;
+ data->tofile= NULL;
BLI_freelistN(&data->channels);
}
@@ -473,11 +586,9 @@ static int exr_has_zbuffer(InputFile *file)
static int exr_is_renderresult(InputFile *file)
{
const StringAttribute *comments= file->header().findTypedAttribute<StringAttribute>("comments");
- if(comments) {
-
- if(comments->value() == "Blender RenderResult")
+ if(comments)
+ if(comments->value() == "Blender MultiChannel")
return 1;
- }
return 0;
}
@@ -529,7 +640,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
/* 1.0 is fill value */
frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
- if(exr_has_zbuffer(file)) {
+ if(exr_has_zbuffer(file))
+ {
float *firstz;
addzbuffloatImBuf(ibuf);
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.h b/source/blender/imbuf/intern/openexr/openexr_api.h
index a82713b6595..7572dbcb292 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.h
+++ b/source/blender/imbuf/intern/openexr/openexr_api.h
@@ -1,15 +1,12 @@
/**
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,14 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * The Original Code is Copyright (C) 2005 Blender Foundation
* All rights reserved.
*
* The Original Code is: all of this file.
*
- * Contributor(s): Austin Benesh.
+ * Contributor(s): Austin Benesh. Ton Roosendaal.
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
#ifndef _OPENEXR_API_H
@@ -37,8 +34,8 @@
extern "C" {
#endif
-#define OPENEXR_FLOATRGB 0x1
-#define OPENEXR_ZBUF 0x2
+#define OPENEXR_FLOATRGB 0x1
+#define OPENEXR_ZBUF 0x2
#include <stdio.h>
@@ -53,15 +50,6 @@ short imb_save_openexr (struct ImBuf *ibuf, char *name, int flags);
struct ImBuf *imb_load_openexr (unsigned char *mem, int size, int flags);
-
-void * imb_exrtile_get_handle (void);
-void imb_exrtile_add_channel (void *handle, char *channame);
-void imb_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley);
-void imb_exrtile_set_channel (void *handle, char *channame, int xstride, int ystride, float *rect);
-void imb_exrtile_write_channels (void *handle, int partx, int party);
-void imb_exrtile_close (void *handle);
-
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/imbuf/intern/openexr/openexr_multi.h b/source/blender/imbuf/intern/openexr/openexr_multi.h
new file mode 100644
index 00000000000..ff71aab5f3c
--- /dev/null
+++ b/source/blender/imbuf/intern/openexr/openexr_multi.h
@@ -0,0 +1,74 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Ton Roosendaal.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _OPENEXR_MULTI_H
+#define _OPENEXR_MULTI_H
+
+/* experiment with more advanced exr api */
+
+#ifdef WITH_OPENEXR
+void * IMB_exr_get_handle (void);
+void IMB_exr_add_channel (void *handle, const char *layname, const char *channame);
+
+int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height);
+void IMB_exr_begin_write (void *handle, char *filename, int width, int height);
+void IMB_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley);
+
+void IMB_exr_set_channel (void *handle, char *layname, char *channame, int xstride, int ystride, float *rect);
+
+void IMB_exr_read_channels (void *handle);
+void IMB_exr_write_channels (void *handle);
+void IMB_exrtile_write_channels (void *handle, int partx, int party);
+
+void IMB_exr_close (void *handle);
+
+#else
+
+/* ugly... but we only use it on pipeline.c, render module, now */
+
+void * IMB_exr_get_handle (void) {return NULL;}
+void IMB_exr_add_channel (void *handle, const char *layname, const char *channame) {}
+
+int IMB_exr_begin_read (void *handle, char *filename, int *width, int *height) {return 0;}
+void IMB_exr_begin_write (void *handle, char *filename, int width, int height) {}
+void IMB_exrtile_begin_write (void *handle, char *filename, int width, int height, int tilex, int tiley) {}
+
+void IMB_exr_set_channel (void *handle, char *layname, char *channame, int xstride, int ystride, float *rect) {}
+
+void IMB_exr_read_channels (void *handle) {}
+void IMB_exr_write_channels (void *handle) {}
+void IMB_exrtile_write_channels (void *handle, int partx, int party) {}
+
+void IMB_exr_close (void *handle) {}
+
+#endif
+
+
+
+#endif /* __OPENEXR_MULTI_H */
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index b1dfb53e357..ad3d93cd908 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -58,7 +58,7 @@ typedef struct Render Render;
typedef struct RenderPass {
struct RenderPass *next, *prev;
- int passtype;
+ int passtype, channels;
float *rect;
} RenderPass;
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index b76e5343dfd..64780b1b831 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -332,15 +332,14 @@ typedef struct LampRen
/* **************** defines ********************* */
-/* mode flag is same as for renderdata */
-/* flag */
+/* R.r.mode flag is same as for renderdata */
+
+/* R.flag */
#define R_ZTRA 1
#define R_HALO 2
#define R_SEC_FIELD 4
#define R_LAMPHALO 8
-#define R_RENDERING 16
-#define R_ANIMRENDER 32
-#define R_REDRAW_PRV 64
+#define R_FILEBUFFER 16
/* vlakren->flag (vlak = face in dutch) char!!! */
#define R_SMOOTH 1
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index c95442fc97d..a1e5108d3d6 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -51,13 +51,16 @@
#include "PIL_time.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "intern/openexr/openexr_api.h"
+
+#include "intern/openexr/openexr_multi.h"
#include "RE_pipeline.h"
#include "radio.h"
#include "BSE_sequence.h" /* <----------------- bad!!! */
+#include "SDL_thread.h"
+
/* internal */
#include "render_types.h"
#include "renderpipeline.h"
@@ -68,9 +71,6 @@
#include "shadbuf.h"
#include "zbuf.h"
-#include "SDL_thread.h"
-#include "SDL_mutex.h"
-
/* render flow
1) Initialize state
@@ -105,7 +105,8 @@ static struct ListBase RenderList= {NULL, NULL};
/* hardcopy of current render, used while rendering for speed */
Render R;
-void *exrhandle= NULL;
+static SDL_mutex *exrtile_lock= NULL;
+
/* ********* alloc and free ******** */
@@ -156,7 +157,7 @@ static void free_render_result(RenderResult *res)
if(rl->rectf) MEM_freeT(rl->rectf);
while(rl->passes.first) {
RenderPass *rpass= rl->passes.first;
- MEM_freeT(rpass->rect);
+ if(rpass->rect) MEM_freeT(rpass->rect);
BLI_remlink(&rl->passes, rpass);
MEM_freeT(rpass);
}
@@ -174,23 +175,90 @@ static void free_render_result(RenderResult *res)
MEM_freeT(res);
}
-static void render_layer_add_pass(RenderLayer *rl, int rectsize, int passtype, char *mallocstr)
+static char *get_pass_name(int passtype, int channel)
+{
+
+ if(passtype == SCE_PASS_COMBINED) {
+ if(channel==0) return "Combined.R";
+ else if(channel==1) return "Combined.G";
+ else if(channel==2) return "Combined.B";
+ else return "Combined.A";
+ }
+ if(passtype == SCE_PASS_Z)
+ return "Z";
+ if(passtype == SCE_PASS_VECTOR) {
+ if(channel==0) return "Vector.X";
+ else if(channel==1) return "Vector.Y";
+ else if(channel==2) return "Vector.Z";
+ else return "Vector.W";
+ }
+ if(passtype == SCE_PASS_NORMAL) {
+ if(channel==0) return "Normal.X";
+ else if(channel==1) return "Normal.Y";
+ else return "Normal.Z";
+ }
+ if(passtype == SCE_PASS_RGBA) {
+ if(channel==0) return "Color.R";
+ else if(channel==1) return "Color.G";
+ else if(channel==2) return "Color.B";
+ else return "Color.A";
+ }
+ if(passtype == SCE_PASS_DIFFUSE) {
+ if(channel==0) return "Diffuse.R";
+ else if(channel==1) return "Diffuse.G";
+ else return "Diffuse.B";
+ }
+ if(passtype == SCE_PASS_SPEC) {
+ if(channel==0) return "Spec.R";
+ else if(channel==1) return "Spec.G";
+ else return "Spec.B";
+ }
+ if(passtype == SCE_PASS_SHADOW) {
+ if(channel==0) return "Shadow.R";
+ else if(channel==1) return "Shadow.G";
+ else return "Shadow.B";
+ }
+ if(passtype == SCE_PASS_AO) {
+ if(channel==0) return "AO.R";
+ else if(channel==1) return "AO.G";
+ else return "AO.B";
+ }
+ if(passtype == SCE_PASS_RAY) {
+ if(channel==0) return "Ray.R";
+ else if(channel==1) return "Ray.G";
+ else return "Ray.B";
+ }
+ return "Unknown";
+}
+
+static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
{
- RenderPass *rpass= MEM_mallocT(sizeof(RenderPass), mallocstr);
+ char *typestr= get_pass_name(passtype, 0);
+ RenderPass *rpass= MEM_callocT(sizeof(RenderPass), typestr);
+ int rectsize= rr->rectx*rr->recty*channels;
BLI_addtail(&rl->passes, rpass);
rpass->passtype= passtype;
- if(passtype==SCE_PASS_VECTOR) {
- float *rect;
- int x;
-
- /* initialize to max speed */
- rect= rpass->rect= MEM_mapallocT(sizeof(float)*rectsize, mallocstr);
- for(x= rectsize-1; x>=0; x--)
- rect[x]= PASS_VECTOR_MAX;
+ rpass->channels= channels;
+
+ if(rr->exrhandle) {
+ int a;
+ for(a=0; a<channels; a++)
+ IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a));
+ }
+ else {
+ if(passtype==SCE_PASS_VECTOR) {
+ float *rect;
+ int x;
+
+ /* initialize to max speed */
+ rect= rpass->rect= MEM_mapallocT(sizeof(float)*rectsize, typestr);
+ for(x= rectsize-1; x>=0; x--)
+ rect[x]= PASS_VECTOR_MAX;
+ }
+ else
+ rpass->rect= MEM_mapallocT(sizeof(float)*rectsize, typestr);
}
- else
- rpass->rect= MEM_mapallocT(sizeof(float)*rectsize, mallocstr);
}
float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
@@ -203,10 +271,11 @@ float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
return NULL;
}
+
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
-/* winrct is coordinate rect of entire image, partrct the part within */
+/* re->winx,winy is coordinate space of entire image, partrct the part within */
static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
{
RenderResult *rr;
@@ -232,6 +301,11 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
+ /* this flag needs cleared immediate after result was made */
+ if(re->flag & R_FILEBUFFER) {
+ rr->exrhandle= IMB_exr_get_handle();
+ }
+
/* check renderdata for amount of layers */
for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) {
@@ -246,26 +320,33 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rl->layflag= srl->layflag;
rl->passflag= srl->passflag;
- rl->rectf= MEM_mapallocT(rectx*recty*sizeof(float)*4, "layer float rgba");
+ if(rr->exrhandle) {
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R");
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G");
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B");
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A");
+ }
+ else
+ rl->rectf= MEM_mapallocT(rectx*recty*sizeof(float)*4, "Combined rgba");
if(srl->passflag & SCE_PASS_Z)
- render_layer_add_pass(rl, rectx*recty, SCE_PASS_Z, "Layer float Z");
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
if(srl->passflag & SCE_PASS_VECTOR)
- render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_VECTOR, "layer float Vector");
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
if(srl->passflag & SCE_PASS_NORMAL)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_NORMAL, "layer float Normal");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
if(srl->passflag & SCE_PASS_RGBA)
- render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_RGBA, "layer float Color");
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
if(srl->passflag & SCE_PASS_DIFFUSE)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_DIFFUSE, "layer float Diffuse");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
if(srl->passflag & SCE_PASS_SPEC)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SPEC, "layer float Spec");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
if(srl->passflag & SCE_PASS_SHADOW)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SHADOW, "layer float Shadow");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
if(srl->passflag & SCE_PASS_AO)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_AO, "layer float AO");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
if(srl->passflag & SCE_PASS_RAY)
- render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_RAY, "layer float Mirror");
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_RAY);
}
/* previewrender and envmap don't do layers, so we make a default one */
@@ -346,19 +427,7 @@ static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
/* passes are allocated in sync */
for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
- switch(rpass->passtype) {
- case SCE_PASS_Z:
- do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 1);
- break;
- case SCE_PASS_VECTOR:
- do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
- break;
- case SCE_PASS_RGBA:
- do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
- break;
- default:
- do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 3);
- }
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
}
}
}
@@ -366,11 +435,13 @@ static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
static void save_render_result_tile(Render *re, RenderPart *pa)
{
-#ifdef WITH_OPENEXR
RenderResult *rrpart= pa->result;
RenderLayer *rlp;
+ RenderPass *rpassp;
int offs, partx, party;
+ if(exrtile_lock) SDL_mutexP(exrtile_lock);
+
for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
if(rrpart->crop) { /* filters add pixel extra */
@@ -384,18 +455,69 @@ static void save_render_result_tile(Render *re, RenderPart *pa)
/* combined */
if(rlp->rectf) {
- int xstride= 4;
- imb_exrtile_set_channel(exrhandle, "R", xstride, xstride*pa->rectx, rlp->rectf + xstride*offs);
- imb_exrtile_set_channel(exrhandle, "G", xstride, xstride*pa->rectx, rlp->rectf+1 + xstride*offs);
- imb_exrtile_set_channel(exrhandle, "B", xstride, xstride*pa->rectx, rlp->rectf+2 + xstride*offs);
- imb_exrtile_set_channel(exrhandle, "A", xstride, xstride*pa->rectx, rlp->rectf+3 + xstride*offs);
-
- imb_exrtile_write_channels(exrhandle, partx, party);
- }
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*pa->rectx, rlp->rectf+a + xstride*offs);
+ }
+
+ /* passes are allocated in sync */
+ for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
+ int a, xstride= rpassp->channels;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(re->result->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
+ xstride, xstride*pa->rectx, rpassp->rect+a + xstride*offs);
+ }
+
}
-#endif
+
+ IMB_exrtile_write_channels(re->result->exrhandle, partx, party);
+
+ if(exrtile_lock) SDL_mutexV(exrtile_lock);
+
}
+static void read_render_result(Render *re)
+{
+ RenderLayer *rl;
+ RenderPass *rpass;
+ void *exrhandle= IMB_exr_get_handle();
+ int rectx, recty;
+
+ free_render_result(re->result);
+ re->result= new_render_result(re, &re->disprect, 0);
+
+ IMB_exr_begin_read(exrhandle, "/tmp/render.exr", &rectx, &recty);
+ if(rectx!=re->result->rectx || recty!=re->result->recty) {
+ printf("error in reading render result\n");
+ }
+ else {
+ for(rl= re->result->layers.first; rl; rl= rl->next) {
+
+ /* combined */
+ if(rl->rectf) {
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rectx, rl->rectf+a);
+ }
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ int a, xstride= rpass->channels;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
+ xstride, xstride*rectx, rpass->rect+a);
+ }
+
+ }
+ printf("before read\n");
+ IMB_exr_read_channels(exrhandle);
+ printf("after read\n");
+ }
+
+ IMB_exr_close(exrhandle);
+}
/* *************************************************** */
@@ -590,7 +712,7 @@ void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect
/* initialize render result */
free_render_result(re->result);
re->result= new_render_result(re, &re->disprect, 0);
-
+
/* single layer render disables composit */
if(re->r.scemode & R_SINGLE_LAYER)
re->r.scemode &= ~R_DOCOMP;
@@ -701,8 +823,11 @@ static int do_part_thread(void *pa_v)
else
zbufshade_tile(pa);
- /* merge too on break! */
- merge_render_result(R.result, pa->result);
+ /* merge too on break! */
+ if(R.result->exrhandle)
+ save_render_result_tile(&R, pa);
+ else
+ merge_render_result(R.result, pa->result);
}
pa->ready= 1;
@@ -805,13 +930,19 @@ static void threaded_tile_processor(Render *re)
{
ListBase threads;
RenderPart *pa, *nextpa;
- int maxthreads, rendering=1, counter= 1, drawtimer=0;
+ RenderResult *rr= re->result;
+ int maxthreads, rendering=1, counter= 1, drawtimer=0, hasdrawn;
- if(re->result==NULL)
+ if(rr==NULL)
return;
if(re->test_break())
return;
+ if(rr->exrhandle) {
+ IMB_exrtile_begin_write(rr->exrhandle, "/tmp/render.exr", rr->rectx, rr->recty, rr->rectx/re->r.xparts, rr->recty/re->r.yparts);
+ exrtile_lock = SDL_CreateMutex();
+ }
+
if(re->r.mode & R_THREADS) maxthreads= 2;
else maxthreads= 1;
@@ -844,37 +975,45 @@ static void threaded_tile_processor(Render *re)
/* check for ready ones to display, and if we need to continue */
rendering= 0;
+ hasdrawn= 0;
for(pa= re->parts.first; pa; pa= pa->next) {
if(pa->ready) {
if(pa->result) {
BLI_remove_thread(&threads, pa);
+
re->display_draw(pa->result, NULL);
print_part_stats(re, pa);
- if(exrhandle) save_render_result_tile(re, pa);
-
free_render_result(pa->result);
pa->result= NULL;
re->i.partsdone++;
- drawtimer= 0;
+ hasdrawn= 1;
}
}
else {
rendering= 1;
if(pa->nr && pa->result && drawtimer>20) {
re->display_draw(pa->result, &pa->result->renrect);
- drawtimer= 0;
+ hasdrawn= 1;
}
}
}
-
+ if(hasdrawn)
+ drawtimer= 0;
+
/* on break, wait for all slots to get freed */
if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
}
- /* restore threadsafety */
+ if(rr->exrhandle) {
+ if(exrtile_lock) SDL_DestroyMutex(exrtile_lock);
+ IMB_exr_close(rr->exrhandle);
+ read_render_result(re);
+ }
+
+ /* unset threadsafety */
g_break= 0;
BLI_end_threads(&threads);
@@ -1158,7 +1297,9 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
disprect.ymax= winy;
}
+/* if(G.rt) re->flag |= R_FILEBUFFER; */
RE_InitState(re, &scene->r, winx, winy, &disprect);
+ re->flag &= ~R_FILEBUFFER;
re->scene= scene;
if(!is_rendering_allowed(re))
@@ -1167,15 +1308,6 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
re->display_init(re->result);
re->display_clear(re->result);
- if(0) {
- exrhandle= imb_exrtile_get_handle();
- imb_exrtile_add_channel(exrhandle, "R");
- imb_exrtile_add_channel(exrhandle, "G");
- imb_exrtile_add_channel(exrhandle, "B");
- imb_exrtile_add_channel(exrhandle, "A");
- imb_exrtile_begin_write(exrhandle, "/tmp/render.exr", winx, winy, winx/scene->r.xparts, winy/scene->r.yparts);
- }
-
return 1;
}
@@ -1189,11 +1321,6 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
if(render_initialize_from_scene(re, scene)) {
do_render_final(re);
-#ifdef WITH_OPENEXR
- if(exrhandle)
- imb_exrtile_close(exrhandle);
-#endif
- exrhandle= NULL;
}
}
diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c
index 1333e1f177f..dd54d014c5c 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -2182,7 +2182,7 @@ static void do_build_seq_ibuf(Sequence * seq, int cfra)
Scene *oldsce;
unsigned int *rectot;
int oldcfra, doseq;
- int redisplay= (!G.background && !(R.flag & R_RENDERING));
+ int redisplay= (!G.background && !G.rendering);
oldsce= G.scene;
if(seq->scene!=G.scene) set_scene_bg(seq->scene);