Render border: make it work together with with cache result / save buffers / full sample.

Differential Revision: https://developer.blender.org/D2080
This commit is contained in:
Brecht Van Lommel 2016-07-02 14:22:25 +02:00
parent 037aa544cc
commit 7fcab3324b
6 changed files with 73 additions and 80 deletions

View File

@ -383,7 +383,6 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.prop(cscene, "use_progressive_refine")
subsub = sub.column(align=True)
subsub.enabled = not rd.use_border
subsub.prop(rd, "use_save_buffers")
col = split.column(align=True)

View File

@ -193,7 +193,6 @@ class RENDER_PT_antialiasing(RenderButtonsPanel, Panel):
col = split.column()
col.row().prop(rd, "antialiasing_samples", expand=True)
sub = col.row()
sub.enabled = not rd.use_border
sub.prop(rd, "use_full_sample")
col = split.column()
@ -280,7 +279,7 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel):
col = split.column()
col.label(text="Memory:")
sub = col.column()
sub.enabled = not (rd.use_border or rd.use_full_sample)
sub.enabled = not rd.use_full_sample
sub.prop(rd, "use_save_buffers")
sub = col.column()
sub.active = rd.use_compositing

View File

@ -841,21 +841,12 @@ static int rna_RenderSettings_save_buffers_get(PointerRNA *ptr)
RenderData *rd = (RenderData *)ptr->data;
Scene *scene = (Scene *)ptr->id.data;
if (rd->mode & R_BORDER)
return 0;
else if (!BKE_scene_use_new_shading_nodes(scene))
if (!BKE_scene_use_new_shading_nodes(scene))
return (rd->scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE)) != 0;
else
return (rd->scemode & R_EXR_TILE_FILE) != 0;
}
static int rna_RenderSettings_full_sample_get(PointerRNA *ptr)
{
RenderData *rd = (RenderData *)ptr->data;
return (rd->scemode & R_FULL_SAMPLE) && !(rd->mode & R_BORDER);
}
static void rna_ImageFormatSettings_file_format_set(PointerRNA *ptr, int value)
{
ImageFormatData *imf = (ImageFormatData *)ptr->data;
@ -5768,7 +5759,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_full_sample", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FULL_SAMPLE);
RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_full_sample_get", NULL);
RNA_def_property_ui_text(prop, "Full Sample",
"Save for every anti-aliasing sample the entire RenderLayer results "
"(this solves anti-aliasing issues with compositing)");

View File

@ -38,7 +38,7 @@
*/
void add_filt_fmask(unsigned int mask, const float col[4], float *rowbuf, int row_w);
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize);
void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y);
void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask);
void mask_array(unsigned int mask, float filt[3][3]);
/**

View File

@ -634,12 +634,6 @@ static int check_mode_full_sample(RenderData *rd)
#ifdef WITH_OPENEXR
if (scemode & R_FULL_SAMPLE)
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 (rd->mode & R_BORDER) {
scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
}
#else
/* can't do this without openexr support */
scemode &= ~(R_EXR_TILE_FILE | R_FULL_SAMPLE);
@ -1829,6 +1823,53 @@ static void render_result_disprect_to_full_resolution(Render *re)
re->recty = re->winy;
}
static void render_result_uncrop(Render *re)
{
/* when using border render with crop disabled, insert render result into
* full size with black pixels outside */
if (re->result && (re->r.mode & R_BORDER)) {
if ((re->r.mode & R_CROP) == 0) {
RenderResult *rres;
/* backup */
const rcti orig_disprect = re->disprect;
const int orig_rectx = re->rectx, orig_recty = re->recty;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
/* sub-rect for merge call later on */
re->result->tilerect = re->disprect;
/* weak is: it chances disprect from border */
render_result_disprect_to_full_resolution(re);
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
render_result_merge(rres, re->result);
render_result_free(re->result);
re->result = rres;
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
BLI_rw_mutex_unlock(&re->resultmutex);
re->display_init(re->dih, re->result);
re->display_update(re->duh, re->result, NULL);
/* restore the disprect from border */
re->disprect = orig_disprect;
re->rectx = orig_rectx;
re->recty = orig_recty;
}
else {
/* set offset (again) for use in compositor, disprect was manipulated. */
re->result->xof = 0;
re->result->yof = 0;
}
}
}
/* main render routine, no compositing */
static void do_render_fields_blur_3d(Render *re)
{
@ -1851,49 +1892,7 @@ static void do_render_fields_blur_3d(Render *re)
do_render_3d(re);
/* when border render, check if we have to insert it in black */
if (re->result) {
if (re->r.mode & R_BORDER) {
if ((re->r.mode & R_CROP) == 0) {
RenderResult *rres;
/* backup */
const rcti orig_disprect = re->disprect;
const int orig_rectx = re->rectx, orig_recty = re->recty;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
/* sub-rect for merge call later on */
re->result->tilerect = re->disprect;
/* weak is: it chances disprect from border */
render_result_disprect_to_full_resolution(re);
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
render_result_merge(rres, re->result);
render_result_free(re->result);
re->result = rres;
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
BLI_rw_mutex_unlock(&re->resultmutex);
re->display_init(re->dih, re->result);
re->display_update(re->duh, re->result, NULL);
/* restore the disprect from border */
re->disprect = orig_disprect;
re->rectx = orig_rectx;
re->recty = orig_recty;
}
else {
/* set offset (again) for use in compositor, disprect was manipulated. */
re->result->xof = 0;
re->result->yof = 0;
}
}
}
render_result_uncrop(re);
}
@ -2292,6 +2291,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
{
ListBase *rectfs;
RenderView *rv;
rcti filter_mask = re->disprect;
float *rectf, filt[3][3];
int x, y, sample;
int nr, numviews;
@ -2317,7 +2317,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
rv = MEM_callocN(sizeof(RenderView), "fullsample renderview");
/* we accumulate in here */
rv->rectf = MEM_mapallocN(re->rectx * re->recty * sizeof(float) * 4, "fullsample rgba");
rv->rectf = MEM_mapallocN(re->result->rectx * re->result->recty * sizeof(float) * 4, "fullsample rgba");
BLI_addtail(rectfs, rv);
}
@ -2347,6 +2347,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
composite_freestyle_renders(re1, sample);
#endif
BLI_rw_mutex_unlock(&re->resultmutex);
render_result_uncrop(re1);
}
ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
}
@ -2373,17 +2374,17 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
mask = (1 << sample);
mask_array(mask, filt);
for (y = 0; y < re->recty; y++) {
float *rf = rectf + 4 * y * re->rectx;
float *col = rres.rectf + 4 * y * re->rectx;
for (y = 0; y < re->result->recty; y++) {
float *rf = rectf + 4 * y * re->result->rectx;
float *col = rres.rectf + 4 * y * re->result->rectx;
for (x = 0; x < re->rectx; x++, rf += 4, col += 4) {
for (x = 0; x < re->result->rectx; x++, rf += 4, col += 4) {
/* clamping to 1.0 is needed for correct AA */
CLAMP(col[0], 0.0f, 1.0f);
CLAMP(col[1], 0.0f, 1.0f);
CLAMP(col[2], 0.0f, 1.0f);
add_filt_fmask_coord(filt, col, rf, re->rectx, re->recty, x, y);
add_filt_fmask_coord(filt, col, rf, re->result->rectx, x, y, &filter_mask);
}
}
@ -2403,10 +2404,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
rectf = ((RenderView *)BLI_findlink(rectfs, nr))->rectf;
/* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
for (y = 0; y < re->recty; y++) {
float *rf = rectf + 4 * y * re->rectx;
for (y = 0; y < re->result->recty; y++) {
float *rf = rectf + 4 * y * re->result->rectx;
for (x = 0; x < re->rectx; x++, rf += 4) {
for (x = 0; x < re->result->rectx; x++, rf += 4) {
rf[0] = MAX2(rf[0], 0.0f);
rf[1] = MAX2(rf[1], 0.0f);
rf[2] = MAX2(rf[2], 0.0f);
@ -3847,6 +3848,8 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
success = render_result_exr_file_cache_read(re);
BLI_rw_mutex_unlock(&re->resultmutex);
render_result_uncrop(re);
return success;
}

View File

@ -240,7 +240,7 @@ void mask_array(unsigned int mask, float filt[3][3])
* </pre>
*/
void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_w, int col_h, int x, int y)
void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, int row_stride, int x, int y, rcti *mask)
{
float *fpoin[3][3];
float val, r, g, b, al, lfilt[3][3];
@ -252,9 +252,9 @@ void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, i
memcpy(lfilt, filt, sizeof(lfilt));
fpoin[0][1] = rowbuf - 4 * row_w;
fpoin[0][1] = rowbuf - 4 * row_stride;
fpoin[1][1] = rowbuf;
fpoin[2][1] = rowbuf + 4 * row_w;
fpoin[2][1] = rowbuf + 4 * row_stride;
fpoin[0][0] = fpoin[0][1] - 4;
fpoin[1][0] = fpoin[1][1] - 4;
@ -264,7 +264,9 @@ void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, i
fpoin[1][2] = fpoin[1][1] + 4;
fpoin[2][2] = fpoin[2][1] + 4;
if (y == 0) {
/* limit filtering to withing a mask for border rendering, so pixels don't
* leak outside of the border */
if (y <= mask->ymin) {
fpoin[0][0] = fpoin[1][0];
fpoin[0][1] = fpoin[1][1];
fpoin[0][2] = fpoin[1][2];
@ -273,7 +275,7 @@ void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, i
lfilt[0][1] = filt[2][1];
lfilt[0][2] = filt[2][2];
}
else if (y == col_h - 1) {
else if (y >= mask->ymax - 1) {
fpoin[2][0] = fpoin[1][0];
fpoin[2][1] = fpoin[1][1];
fpoin[2][2] = fpoin[1][2];
@ -283,7 +285,7 @@ void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, i
lfilt[2][2] = filt[0][2];
}
if (x == 0) {
if (x <= mask->xmin) {
fpoin[2][0] = fpoin[2][1];
fpoin[1][0] = fpoin[1][1];
fpoin[0][0] = fpoin[0][1];
@ -292,7 +294,7 @@ void add_filt_fmask_coord(float filt[3][3], const float col[4], float *rowbuf, i
lfilt[1][0] = filt[1][2];
lfilt[0][0] = filt[0][2];
}
else if (x == row_w - 1) {
else if (x >= mask->xmax - 1) {
fpoin[2][2] = fpoin[2][1];
fpoin[1][2] = fpoin[1][1];
fpoin[0][2] = fpoin[0][1];