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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-12-17 21:42:38 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-12-17 21:42:38 +0400
commitc5d7ea091fa5a291b270565e456612df1e37b50c (patch)
tree4322fffdf299ec35afe86030b49fdda9d0f38c8a /source/blender/render
parent04eb24a33737b9d9e29ec758c3db8fb81d140fc1 (diff)
Changes to partial update during rendering
Summary: Mainly addressed to solve old TODO with color managed fallback to CPU mode when displaying render result during rendering. That fallback was caused by the fact that partial image update was always acquiring image buffer for composite output and was only modifying display buffer directly. This was a big issue for Cycles rendering which renders layers one by one and wanted to display progress of each individual layer. This lead to situations when display buffer was based on what Cycles passes via RenderResult and didn't take layer/pass from image editor header into account. Now made it so image buffer which partial update is operating with always corresponds to what is set in image editor header. To make Cycles displaying progress of all the layers one by one made it so image_rect_update switches image editor user to newly rendering render layer. It happens only once when render engine starts rendering next render layer, so should not be annoying for navigation during rendering. Additional change to render engines was done to make it so they're able to merge composite output to final result without marking tile as done. This is done via do_merge_result argument to end_result() callback. This argument is optional so should not break script compatibility. Additional changes: - Partial display update for Blender Internal now happens from the same thread as tile rendering. This makes it so display conversion (which could be pretty heavy actually) is done in separate threads. Also gives better UI feedback when rendering easy scene with small tiles. - Avoid freeing/allocating byte buffer for render result if it's owned by the image buffer. Only mark it as invalid for color management. Saves loads of buffer re-allocations in cases when having several image editors opened with render result. This change in conjunction with the rest of the patch gave around 50%-100% speedup of render time when displaying non-combined pass during rendering on my laptop. - Partial display buffer update was wrong for buffers with number of channels different from 4. - Remove unused window from RenderJob. - Made image_buffer_rect_update static since it's only used in single file. Reviewers: brecht Reviewed By: brecht CC: dingto Differential Revision: http://developer.blender.org/D98
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/extern/include/RE_engine.h2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/external_engine.c8
-rw-r--r--source/blender/render/intern/source/pipeline.c54
-rw-r--r--source/blender/render/intern/source/rendercore.c2
7 files changed, 44 insertions, 32 deletions
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 7bec3eb234d..559f21f6961 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -132,7 +132,7 @@ void RE_result_load_from_file(struct RenderResult *result, struct ReportList *re
struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername);
void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
-void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel);
+void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results);
int RE_engine_test_break(RenderEngine *engine);
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 109524c9814..7e8713566e5 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -250,7 +250,7 @@ void RE_MergeFullSample(struct Render *re, struct Main *bmain, struct Scene *sce
/* display and event callbacks */
void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
void RE_display_clear_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
-void RE_display_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile struct rcti *rect));
+void RE_display_update_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile struct rcti *rect));
void RE_stats_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderStats *rs));
void RE_progress_cb (struct Render *re, void *handle, void (*f)(void *handle, float));
void RE_draw_lock_cb (struct Render *re, void *handle, void (*f)(void *handle, int));
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 3d97eda50d9..2a43cab7bce 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -252,8 +252,8 @@ struct Render
void *dih;
void (*display_clear)(void *handle, RenderResult *rr);
void *dch;
- void (*display_draw)(void *handle, RenderResult *rr, volatile rcti *rect);
- void *ddh;
+ void (*display_update)(void *handle, RenderResult *rr, volatile rcti *rect);
+ void *duh;
void (*stats_draw)(void *handle, RenderStats *ri);
void *sdh;
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index b5bc5ea768b..ac814e9e033 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -168,8 +168,8 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
copy_m4_m4(envre->viewmat_orig, re->viewmat_orig);
/* callbacks */
- envre->display_draw = re->display_draw;
- envre->ddh = re->ddh;
+ envre->display_update = re->display_update;
+ envre->duh = re->duh;
envre->test_break = re->test_break;
envre->tbh = re->tbh;
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 827a1f8f113..c3628e99d04 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -235,11 +235,11 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
if (result) {
result->renlay = result->layers.first; /* weak, draws first layer always */
- re->display_draw(re->ddh, result, NULL);
+ re->display_update(re->duh, result, NULL);
}
}
-void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel)
+void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int merge_results)
{
Render *re = engine->re;
@@ -260,7 +260,9 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
* buffers, we are going to get openexr save errors */
fprintf(stderr, "RenderEngine.end_result: dimensions do not match any OpenEXR tile.\n");
}
+ }
+ if (!cancel || merge_results) {
if (re->result->do_exr_tile)
render_result_exr_file_merge(re->result, result);
else if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW)))
@@ -269,7 +271,7 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
/* draw */
if (!re->test_break(re->tbh)) {
result->renlay = result->layers.first; /* weak, draws first layer always */
- re->display_draw(re->ddh, result, NULL);
+ re->display_update(re->duh, result, NULL);
}
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index d11f4615698..ba8265a83fe 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -390,7 +390,7 @@ void RE_InitRenderCB(Render *re)
/* set default empty callbacks */
re->display_init = result_nothing;
re->display_clear = result_nothing;
- re->display_draw = result_rcti_nothing;
+ re->display_update = result_rcti_nothing;
re->progress = float_nothing;
re->test_break = default_break;
if (G.background)
@@ -398,7 +398,7 @@ void RE_InitRenderCB(Render *re)
else
re->stats_draw = stats_nothing;
/* clear callback handles */
- re->dih = re->dch = re->ddh = re->sdh = re->prh = re->tbh = NULL;
+ re->dih = re->dch = re->duh = re->sdh = re->prh = re->tbh = NULL;
}
/* only call this while you know it will remove the link too */
@@ -709,10 +709,10 @@ void RE_display_clear_cb(Render *re, void *handle, void (*f)(void *handle, Rende
re->display_clear = f;
re->dch = handle;
}
-void RE_display_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile rcti *rect))
+void RE_display_update_cb(Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile rcti *rect))
{
- re->display_draw = f;
- re->ddh = handle;
+ re->display_update = f;
+ re->duh = handle;
}
void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderStats *rs))
{
@@ -751,7 +751,7 @@ void RE_AddObject(Render *UNUSED(re), Object *UNUSED(ob))
/* *************************************** */
-static int render_display_draw_enabled(Render *re)
+static int render_display_update_enabled(Render *re)
{
/* don't show preprocess for previewrender sss */
if (re->sss_points)
@@ -790,7 +790,7 @@ static void *do_part_thread(void *pa_v)
if (R.result->do_exr_tile) {
render_result_exr_file_merge(R.result, pa->result);
}
- else if (render_display_draw_enabled(&R)) {
+ else if (render_display_update_enabled(&R)) {
/* on break, don't merge in result for preview renders, looks nicer */
if (R.test_break(R.tbh) && (R.r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) {
/* pass */
@@ -941,6 +941,9 @@ typedef struct RenderThread {
ThreadQueue *donequeue;
int number;
+
+ void (*display_update)(void *handle, RenderResult *rr, volatile rcti *rect);
+ void *duh;
} RenderThread;
static void *do_render_thread(void *thread_v)
@@ -951,6 +954,11 @@ static void *do_render_thread(void *thread_v)
while ((pa = BLI_thread_queue_pop(thread->workqueue))) {
pa->thread = thread->number;
do_part_thread(pa);
+
+ if (thread->display_update) {
+ thread->display_update(thread->duh, pa->result, NULL);
+ }
+
BLI_thread_queue_push(thread->donequeue, pa);
if (R.test_break(R.tbh))
@@ -976,7 +984,7 @@ static void threaded_tile_processor(Render *re)
if (re->result == NULL || !(re->r.scemode & (R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))) {
render_result_free(re->result);
- if (re->sss_points && render_display_draw_enabled(re))
+ if (re->sss_points && render_display_update_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);
@@ -1025,6 +1033,10 @@ static void threaded_tile_processor(Render *re)
thread[a].workqueue = workqueue;
thread[a].donequeue = donequeue;
thread[a].number = a;
+ if (render_display_update_enabled(re)) {
+ thread[a].display_update = re->display_update;
+ thread[a].duh = re->duh;
+ }
BLI_insert_thread(&threads, &thread[a]);
}
@@ -1038,8 +1050,6 @@ static void threaded_tile_processor(Render *re)
/* 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);
print_part_stats(re, pa);
render_result_free_list(&pa->fullresult, pa->result);
@@ -1062,10 +1072,10 @@ static void threaded_tile_processor(Render *re)
/* redraw in progress parts */
elapsed = PIL_check_seconds_timer() - lastdraw;
if (elapsed > redrawtime) {
- if (render_display_draw_enabled(re))
+ if (render_display_update_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);
+ re->display_update(re->duh, pa->result, &pa->result->renrect);
lastdraw = PIL_check_seconds_timer();
}
@@ -1315,7 +1325,7 @@ static void do_render_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
@@ -1436,7 +1446,7 @@ static void do_render_fields_3d(Render *re)
BLI_rw_mutex_unlock(&re->resultmutex);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
/* make sure disprect is not affected by the render border */
@@ -1496,7 +1506,7 @@ static void do_render_fields_blur_3d(Render *re)
BLI_rw_mutex_unlock(&re->resultmutex);
re->display_init(re->dih, re->result);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
else {
/* set offset (again) for use in compositor, disprect was manipulated. */
@@ -1539,8 +1549,8 @@ static void render_scene(Render *re, Scene *sce, int cfra)
BKE_scene_set_background(re->main, sce);
/* copy callbacks */
- resc->display_draw = re->display_draw;
- resc->ddh = re->ddh;
+ resc->display_update = re->display_update;
+ resc->duh = re->duh;
resc->test_break = re->test_break;
resc->tbh = re->tbh;
resc->stats_draw = re->stats_draw;
@@ -1849,7 +1859,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
if (sample != re->osa - 1) {
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
if (re->test_break(re->tbh))
@@ -2034,7 +2044,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* weak... the display callback wants an active renderlayer pointer... */
re->result->renlay = render_get_active_layer(re, re->result);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
static void renderresult_stampinfo(Render *re)
@@ -2140,7 +2150,7 @@ static void do_render_seq(Render *re)
re->progress(re->prh, 1.0f);
/* would mark display buffers as invalid */
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -2164,7 +2174,7 @@ static void do_render_all_options(Render *re)
do_render_seq(re);
re->stats_draw(re->sdh, &re->i);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
else {
re->pool = BKE_image_pool_new();
@@ -2182,7 +2192,7 @@ static void do_render_all_options(Render *re)
/* stamp image info here */
if ((re->r.stamp & R_STAMP_ALL) && (re->r.stamp & R_STAMP_DRAW)) {
renderresult_stampinfo(re);
- re->display_draw(re->ddh, re->result, NULL);
+ re->display_update(re->duh, re->result, NULL);
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 8791af55792..2fb956ee3a6 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1866,7 +1866,7 @@ void add_halo_flare(Render *re)
if (do_draw) {
/* weak... the display callback wants an active renderlayer pointer... */
rr->renlay= rl;
- re->display_draw(re->ddh, rr, NULL);
+ re->display_update(re->duh, rr, NULL);
}
R.r.mode= mode;