Merged changes in the trunk up to revision 54802.

This commit is contained in:
2013-02-24 03:39:20 +00:00
401 changed files with 4578 additions and 2960 deletions

View File

@@ -648,6 +648,8 @@ static int get_next_bake_face(BakeShade *bs)
ImBuf *ibuf = NULL;
const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
tface = RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
@@ -684,9 +686,12 @@ static int get_next_bake_face(BakeShade *bs)
if (ibuf->rect_float)
imb_freerectImBuf(ibuf);
/* clear image */
if (R.r.bake_flag & R_BAKE_CLEAR)
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
if (R.r.bake_flag & R_BAKE_CLEAR) {
if (R.r.bake_mode == RE_BAKE_NORMALS && R.r.bake_normal_space == R_BAKE_SPACE_TANGENT)
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
else
IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
}
/* might be read by UI to set active image for display */
R.bakebuf = ima;
}

View File

@@ -4079,18 +4079,10 @@ static void set_renderlayer_lightgroups(Render *re, Scene *sce)
void init_render_world(Render *re)
{
int a;
char *cp;
if (re->scene && re->scene->world) {
re->wrld= *(re->scene->world);
cp= (char *)&re->wrld.fastcol;
cp[0]= 255.0f*re->wrld.horr;
cp[1]= 255.0f*re->wrld.horg;
cp[2]= 255.0f*re->wrld.horb;
cp[3]= 1;
copy_v3_v3(re->grvec, re->viewmat[2]);
normalize_v3(re->grvec);
copy_m3_m4(re->imat, re->viewinv);

View File

@@ -1258,13 +1258,13 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
if (ibuf->x <= 0 || ibuf->y <= 0)
continue;
RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
if (use_displacement_buffer) {
RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
result->height_min, result->height_max);
}
RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
if (ibuf->rect_float)

View File

@@ -678,6 +678,10 @@ static void *do_part_thread(void *pa_v)
else
zbufshade_tile(pa);
/* we do actually write pixels, but don't allocate/deallocate anything,
* so it is safe with other threads reading at the same time */
BLI_rw_mutex_lock(&R.resultmutex, THREAD_LOCK_READ);
/* merge too on break! */
if (R.result->do_exr_tile) {
render_result_exr_file_merge(R.result, pa->result);
@@ -691,6 +695,8 @@ static void *do_part_thread(void *pa_v)
render_result_merge(R.result, pa->result);
}
}
BLI_rw_mutex_unlock(&R.resultmutex);
}
pa->status = PART_STATUS_READY;
@@ -724,24 +730,33 @@ float panorama_pixel_rot(Render *re)
return phi;
}
/* call when all parts stopped rendering, to find the next Y slice */
/* if slice found, it rotates the dbase */
static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
/* for panorama, we render per Y slice, and update
* camera parameters when we go the next slice */
static bool find_next_pano_slice(Render *re, int *slice, int *minx, rctf *viewplane)
{
RenderPart *pa, *best = NULL;
bool found = false;
*minx = re->winx;
if (!(re->r.mode & R_PANORAMA)) {
/* for regular render, just one 'slice' */
found = (*slice == 0);
(*slice)++;
return found;
}
/* most left part of the non-rendering parts */
for (pa = re->parts.first; pa; pa = pa->next) {
if (pa->status == PART_STATUS_NONE && pa->nr == 0) {
if (pa->disprect.xmin < *minx) {
found = true;
best = pa;
*minx = pa->disprect.xmin;
}
}
}
if (best) {
float phi = panorama_pixel_rot(re);
@@ -759,7 +774,10 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane)
R.panosi = sin(R.panodxp * phi);
R.panoco = cos(R.panodxp * phi);
}
return best;
(*slice)++;
return found;
}
static RenderPart *find_next_part(Render *re, int minx)
@@ -814,26 +832,53 @@ static void print_part_stats(Render *re, RenderPart *pa)
re->i.infostr = NULL;
}
typedef struct RenderThread {
ThreadQueue *workqueue;
ThreadQueue *donequeue;
int number;
} RenderThread;
static void *do_render_thread(void *thread_v)
{
RenderThread *thread = thread_v;
RenderPart *pa;
while ((pa = BLI_thread_queue_pop(thread->workqueue))) {
pa->thread = thread->number;
do_part_thread(pa);
BLI_thread_queue_push(thread->donequeue, pa);
if(R.test_break(R.tbh))
break;
}
return NULL;
}
static void threaded_tile_processor(Render *re)
{
RenderThread thread[BLENDER_MAX_THREADS];
ThreadQueue *workqueue, *donequeue;
ListBase threads;
RenderPart *pa, *nextpa;
RenderPart *pa;
rctf viewplane = re->viewplane;
int rendering = 1, counter = 1, drawtimer = 0, hasdrawn, minx = 0;
double lastdraw, elapsed, redrawtime = 1.0f;
int totpart = 0, minx = 0, slice = 0, a, wait;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
/* first step; free the entire render result, make new, and/or prepare exr buffer saving */
if (re->result == NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
render_result_free(re->result);
if (re->sss_points && render_display_draw_enabled(re))
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
else if (re->r.scemode & R_FULL_SAMPLE)
re->result = render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR);
else
re->result = render_result_new(re, &re->disprect, 0,
(re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS);
(re->r.scemode & R_EXR_TILE_FILE) ? RR_USE_EXR : RR_USE_MEM, RR_ALL_LAYERS);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -848,53 +893,46 @@ static void threaded_tile_processor(Render *re)
if (re->result->do_exr_tile)
render_result_exr_file_begin(re);
BLI_init_threads(&threads, do_part_thread, re->r.threads);
/* assuming no new data gets added to dbase... */
R = *re;
/* set threadsafe break */
R.test_break = thread_break;
/* timer loop demands to sleep when no parts are left, so we enter loop with a part */
if (re->r.mode & R_PANORAMA)
nextpa = find_next_pano_slice(re, &minx, &viewplane);
else
nextpa = find_next_part(re, 0);
/* create and fill work queue */
workqueue = BLI_thread_queue_init();
donequeue = BLI_thread_queue_init();
while (rendering) {
if (re->test_break(re->tbh))
PIL_sleep_ms(50);
else if (nextpa && BLI_available_threads(&threads)) {
drawtimer = 0;
nextpa->nr = counter++; /* for nicest part, and for stats */
nextpa->thread = BLI_available_thread_index(&threads); /* sample index */
BLI_insert_thread(&threads, nextpa);
nextpa = find_next_part(re, minx);
}
else if (re->r.mode & R_PANORAMA) {
if (nextpa == NULL && BLI_available_threads(&threads) == re->r.threads)
nextpa = find_next_pano_slice(re, &minx, &viewplane);
else {
PIL_sleep_ms(50);
drawtimer++;
}
}
else {
PIL_sleep_ms(50);
drawtimer++;
/* for panorama we loop over slices */
while (find_next_pano_slice(re, &slice, &minx, &viewplane)) {
/* gather parts into queue */
while ((pa = find_next_part(re, minx))) {
pa->nr = totpart + 1; /* for nicest part, and for stats */
totpart++;
BLI_thread_queue_push(workqueue, pa);
}
/* 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->status == PART_STATUS_READY) {
BLI_remove_thread(&threads, pa);
BLI_thread_queue_nowait(workqueue);
/* start all threads */
BLI_init_threads(&threads, do_render_thread, re->r.threads);
for (a = 0; a < re->r.threads; a++) {
thread[a].workqueue = workqueue;
thread[a].donequeue = donequeue;
thread[a].number = a;
BLI_insert_thread(&threads, &thread[a]);
}
/* wait for results to come back */
lastdraw = PIL_check_seconds_timer();
while (1) {
elapsed = PIL_check_seconds_timer() - lastdraw;
wait = (redrawtime - elapsed)*1000;
/* handle finished part */
if ((pa=BLI_thread_queue_pop_timeout(donequeue, wait))) {
if (pa->result) {
if (render_display_draw_enabled(re))
re->display_draw(re->ddh, pa->result, NULL);
@@ -904,27 +942,40 @@ static void threaded_tile_processor(Render *re)
pa->result = NULL;
re->i.partsdone++;
re->progress(re->prh, re->i.partsdone / (float)re->i.totpart);
hasdrawn = 1;
}
totpart--;
}
else {
rendering = 1;
if (pa->nr && pa->result && drawtimer > 20) {
if (render_display_draw_enabled(re))
re->display_draw(re->ddh, pa->result, &pa->result->renrect);
hasdrawn = 1;
}
/* check for render cancel */
if ((g_break=re->test_break(re->tbh)))
break;
/* or done with parts */
if (totpart == 0)
break;
/* redraw in progress parts */
elapsed = PIL_check_seconds_timer() - lastdraw;
if (elapsed > redrawtime) {
if (render_display_draw_enabled(re))
for (pa = re->parts.first; pa; pa = pa->next)
if ((pa->status == PART_STATUS_IN_PROGRESS) && pa->nr && pa->result)
re->display_draw(re->ddh, pa->result, &pa->result->renrect);
lastdraw = PIL_check_seconds_timer();
}
}
if (hasdrawn)
drawtimer = 0;
/* on break, wait for all slots to get freed */
if ( (g_break = re->test_break(re->tbh)) && BLI_available_threads(&threads) == re->r.threads)
rendering = 0;
BLI_end_threads(&threads);
if ((g_break=re->test_break(re->tbh)))
break;
}
BLI_thread_queue_free(donequeue);
BLI_thread_queue_free(workqueue);
if (re->result->do_exr_tile) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
render_result_exr_file_end(re);
@@ -934,7 +985,6 @@ static void threaded_tile_processor(Render *re)
/* unset threadsafety */
g_break = 0;
BLI_end_threads(&threads);
RE_parts_free(re);
re->viewplane = viewplane; /* restore viewplane, modified by pano render */
}