#include "BLI_arithb.h"
#include "BLI_blenlib.h"
+#include "BLI_threads.h"
#include "PIL_time.h"
#include "IMB_imbuf.h"
#include "zbuf.h"
#include "SDL_thread.h"
+#include "SDL_mutex.h"
/* render flow
/* ********* alloc and free ******** */
-static SDL_mutex *malloc_lock= NULL;
+SDL_mutex *malloc_lock= NULL;
void *RE_mallocN(int len, char *name)
{
}
if(res->rect32)
- MEM_freeN(res->rect32);
+ RE_freeN(res->rect32);
if(res->rectz)
- MEM_freeN(res->rectz);
+ RE_freeN(res->rectz);
if(res->rectf)
- MEM_freeN(res->rectf);
+ RE_freeN(res->rectf);
RE_freeN(res);
}
rl= RE_callocN(sizeof(RenderLayer), "new render layer");
BLI_addtail(&rr->layers, rl);
- rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
- rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
+ rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
+ rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
+
+ /* note, this has to be in sync with scene.c */
+ rl->lay= (1<<20) -1;
+ rl->layflag= 0x7FFF; /* solid ztra halo strand */
+ rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
+
}
return rr;
}
-/* ********** basic thread control API ************ */
-
-#define RE_MAX_THREAD 4
-
-typedef struct ThreadSlot {
- RenderPart *part;
- int avail;
-} ThreadSlot;
-
-static ThreadSlot threadslots[RE_MAX_THREAD];
-
-static void init_threadslots(int tot)
-{
- int a;
-
- if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
- else if(tot<1) tot= 1;
-
- for(a=0; a< RE_MAX_THREAD; a++) {
- threadslots[a].part= NULL;
- if(a<tot)
- threadslots[a].avail= 1;
- else
- threadslots[a].avail= 0;
- }
-}
-
-static int available_threadslots(void)
-{
- int a, counter=0;
- for(a=0; a< RE_MAX_THREAD; a++)
- if(threadslots[a].avail)
- counter++;
- return counter;
-}
-
-static void insert_threadslot(RenderPart *pa)
-{
- int a;
- for(a=0; a< RE_MAX_THREAD; a++) {
- if(threadslots[a].avail) {
- threadslots[a].avail= 0;
- threadslots[a].part= pa;
- pa->thread= a;
- break;
- }
- }
-}
-
-static void remove_threadslot(RenderPart *pa)
-{
- int a;
- for(a=0; a< RE_MAX_THREAD; a++) {
- if(threadslots[a].part==pa) {
- threadslots[a].avail= 1;
- threadslots[a].part= NULL;
- }
- }
-}
-
-/* ********** basic thread control API ************ */
+/* *************************************** */
static int do_part_thread(void *pa_v)
{
}
pa->ready= 1;
- remove_threadslot(pa);
return 0;
}
static void threaded_tile_processor(Render *re)
{
+ ListBase threads;
RenderPart *pa;
int maxthreads=2, rendering=1, counter= 1;
return;
initparts(re);
- init_threadslots(maxthreads);
+ BLI_init_threads(&threads, do_part_thread, maxthreads);
/* assuming no new data gets added to dbase... */
R= *re;
while(rendering) {
/* I noted that test_break() in a thread doesn't make ghost send ESC */
- if(available_threadslots() && !re->test_break()) {
+ if(BLI_available_threads(&threads) && !re->test_break()) {
pa= find_nicest_part(re);
if(pa) {
- insert_threadslot(pa);
- pa->nr= counter++; /* only for stats */
- SDL_CreateThread(do_part_thread, pa);
+ pa->nr= counter++; /* for nicest part, and for stats */
+ pa->thread= BLI_available_thread_index(&threads); /* sample index */
+ BLI_insert_thread(&threads, pa);
}
}
else
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);
free_render_result(pa->result);
pa->result= NULL;
}
/* on break, wait for all slots to get freed */
- if(re->test_break() && available_threadslots()==maxthreads)
+ if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
}
if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
+ BLI_end_threads(&threads);
freeparts(re);
}
/* first check if theres nodetree with render result */
int do_render= ntreeCompositNeedsRender(scene->nodetree);
/* but.. do we use nodes? */
- if(scene->use_nodes==NULL) do_render= 1;
+ if(scene->use_nodes==0) do_render= 1;
re->scene= scene;
else
render_one_frame(re);
}
+
+ ntreeCompositTagRender(scene->nodetree);
+ ntreeCompositTagAnimated(scene->nodetree);
+
if(re->r.scemode & R_DOCOMP)
ntreeCompositExecTree(scene->nodetree, &re->r, 0);
}