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:
-rw-r--r--intern/cycles/blender/blender_session.cpp12
-rw-r--r--source/blender/blenkernel/intern/image.c7
-rw-r--r--source/blender/editors/render/render_intern.h6
-rw-r--r--source/blender/editors/render/render_internal.c190
-rw-r--r--source/blender/editors/render/render_preview.c4
-rw-r--r--source/blender/editors/render/render_view.c6
-rw-r--r--source/blender/editors/screen/glutil.c33
-rw-r--r--source/blender/imbuf/intern/colormanagement.c50
-rw-r--r--source/blender/makesrna/intern/rna_render.c3
-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
16 files changed, 265 insertions, 122 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index db673a8d625..f81de7d529a 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -261,9 +261,9 @@ static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, in
return b_engine.begin_result(x, y, w, h, layername);
}
-static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel = false)
+static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel, bool do_merge_results)
{
- b_engine.end_result(b_rr, (int)cancel);
+ b_engine.end_result(b_rr, (int)cancel, (int)do_merge_results);
}
void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only)
@@ -302,12 +302,12 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
update_render_result(b_rr, b_rlay, rtile);
}
- end_render_result(b_engine, b_rr, true);
+ end_render_result(b_engine, b_rr, true, true);
}
else {
/* write result */
write_render_result(b_rr, b_rlay, rtile);
- end_render_result(b_engine, b_rr);
+ end_render_result(b_engine, b_rr, false, true);
}
}
@@ -352,7 +352,7 @@ void BlenderSession::render()
/* layer will be missing if it was disabled in the UI */
if(b_single_rlay == b_rr.layers.end()) {
- end_render_result(b_engine, b_rr, true);
+ end_render_result(b_engine, b_rr, true, false);
continue;
}
@@ -379,7 +379,7 @@ void BlenderSession::render()
}
/* free result without merging */
- end_render_result(b_engine, b_rr, true);
+ end_render_result(b_engine, b_rr, true, false);
buffer_params.passes = passes;
scene->film->tag_passes_update(scene, passes);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 51c70e8434a..dc26cedbc46 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -2862,13 +2862,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->x = rres.rectx;
ibuf->y = rres.recty;
- /* free rect buffer if float buffer changes, so it can be recreated with
- * the updated result, and also in case we got byte buffer from sequencer,
- * so we don't keep reference to freed buffer */
- if (ibuf->rect_float != rectf || rect)
- imb_freerectImBuf(ibuf);
-
if (rect) {
+ imb_freerectImBuf(ibuf);
ibuf->rect = rect;
}
else {
diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h
index eb09606e57e..8f8cc542821 100644
--- a/source/blender/editors/render/render_intern.h
+++ b/source/blender/editors/render/render_intern.h
@@ -35,6 +35,7 @@
struct wmOperatorType;
struct RenderResult;
struct Scene;
+struct ScrArea;
/* render_shading.c */
void OBJECT_OT_material_slot_add(struct wmOperatorType *ot);
@@ -86,11 +87,8 @@ void RENDER_OT_render(struct wmOperatorType *ot);
void render_view3d_update(struct RenderEngine *engine, const struct bContext *C);
void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C);
-/* render_opengl.c uses this */
-void image_buffer_rect_update(struct Scene *scene, struct RenderResult *rr, struct ImBuf *ibuf, volatile struct rcti *renrect);
-
/* render_view.c */
-void render_view_open(struct bContext *C, int mx, int my);
+struct ScrArea *render_view_open(struct bContext *C, int mx, int my);
void RENDER_OT_view_show(struct wmOperatorType *ot);
void RENDER_OT_view_cancel(struct wmOperatorType *ot);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 1b090cb16ec..7ecada993e2 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -94,11 +94,17 @@
static int render_break(void *rjv);
/* called inside thread! */
-void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volatile rcti *renrect)
+static void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect)
{
float *rectf = NULL;
int ymin, ymax, xmin, xmax;
int rymin, rxmin;
+ int linear_stride, linear_offset_x, linear_offset_y;
+
+ if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) {
+ /* The whole image buffer it so be color managed again anyway. */
+ return;
+ }
/* if renrect argument, we only refresh scanlines */
if (renrect) {
@@ -138,33 +144,55 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
if (xmax < 1 || ymax < 1) return;
- /* find current float rect for display, first case is after composite... still weak */
- if (rr->rectf)
- rectf = rr->rectf;
- else {
- if (rr->rect32) {
- /* special case, currently only happens with sequencer rendering,
- * which updates the whole frame, so we can only mark display buffer
- * as invalid here (sergey)
- */
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- return;
- }
+ /* The thing here is, the logic below (which was default behavior
+ * of how rectf is acquiring since forever) gives float buffer for
+ * composite output only. This buffer can not be used for other
+ * passes obviously.
+ *
+ * We might try finding corresponding for pass buffer in render result
+ * (which is actually missing when rendering with Cycles, who only
+ * writes all the passes when the tile is finished) or use float
+ * buffer from image buffer as reference, which is easier to use and
+ * contains all the data we need anyway.
+ * - sergey -
+ */
+ /* TODO(sergey): Need to check has_combined here? */
+ if (iuser->pass == 0) {
+ /* find current float rect for display, first case is after composite... still weak */
+ if (rr->rectf)
+ rectf = rr->rectf;
else {
- if (rr->renlay == NULL || rr->renlay->rectf == NULL) return;
- rectf = rr->renlay->rectf;
+ if (rr->rect32) {
+ /* special case, currently only happens with sequencer rendering,
+ * which updates the whole frame, so we can only mark display buffer
+ * as invalid here (sergey)
+ */
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ return;
+ }
+ else {
+ if (rr->renlay == NULL || rr->renlay->rectf == NULL) return;
+ rectf = rr->renlay->rectf;
+ }
}
- }
- if (rectf == NULL) return;
+ if (rectf == NULL) return;
- if (ibuf->rect == NULL)
- imb_addrectImBuf(ibuf);
-
- rectf += 4 * (rr->rectx * ymin + xmin);
+ rectf += 4 * (rr->rectx * ymin + xmin);
+ linear_stride = rr->rectx;
+ linear_offset_x = rxmin;
+ linear_offset_y = rymin;
+ }
+ else {
+ rectf = ibuf->rect_float;
+ linear_stride = ibuf->x;
+ linear_offset_x = 0;
+ linear_offset_y = 0;
+ }
- IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin,
+ IMB_partial_display_buffer_update(ibuf, rectf, NULL,
+ linear_stride, linear_offset_x, linear_offset_y,
&scene->view_settings, &scene->display_settings,
- rxmin, rymin, rxmin + xmax, rymin + ymax, true);
+ rxmin, rymin, rxmin + xmax, rymin + ymax, false);
}
/* ****************************** render invoking ***************** */
@@ -262,7 +290,6 @@ typedef struct RenderJob {
Main *main;
Scene *scene;
Render *re;
- wmWindow *win;
SceneRenderLayer *srl;
struct Object *camera_override;
int lay_override;
@@ -275,6 +302,9 @@ typedef struct RenderJob {
short *do_update;
float *progress;
ReportList *reports;
+ int orig_layer;
+ int last_layer;
+ ScrArea *sa;
} RenderJob;
static void render_freejob(void *rjv)
@@ -402,6 +432,64 @@ static void render_progress_update(void *rjv, float progress)
}
}
+/* Not totally reliable, but works fine in most of cases and
+ * in worst case would just make it so extra color management
+ * for the whole render result is applied (which was already
+ * happening already).
+ */
+static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr, ImageUser *iuser)
+{
+ wmWindowManager *wm;
+ ScrArea *first_sa = NULL, *matched_sa = NULL;
+
+ /* image window, compo node users */
+ for (wm = rj->main->wm.first; wm && matched_sa == NULL; wm = wm->id.next) { /* only 1 wm */
+ wmWindow *win;
+ for (win = wm->windows.first; win && matched_sa == NULL; win = win->next) {
+ ScrArea *sa;
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = sa->spacedata.first;
+ if (sima->image == rj->image) {
+ if (first_sa == NULL) {
+ first_sa = sa;
+ }
+ if (sa == rj->sa) {
+ matched_sa = sa;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (matched_sa == NULL) {
+ matched_sa = first_sa;
+ }
+
+ if (matched_sa) {
+ SpaceImage *sima = matched_sa->spacedata.first;
+ RenderResult *main_rr = RE_AcquireResultRead(rj->re);
+
+ /* TODO(sergey): is there faster way to get the layer index? */
+ if (rr->renlay) {
+ int layer = BLI_findstringindex(&main_rr->layers,
+ (char *)rr->renlay->name,
+ offsetof(RenderLayer, name));
+ if (layer != rj->last_layer) {
+ sima->iuser.layer = layer;
+ rj->last_layer = layer;
+ }
+ }
+
+ iuser->pass = sima->iuser.pass;
+ iuser->layer = sima->iuser.layer;
+
+ RE_ReleaseResult(rj->re);
+ }
+}
+
static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
{
RenderJob *rj = rjv;
@@ -423,9 +511,17 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
}
/* update part of render */
+ render_image_update_pass_and_layer(rj, rr, &rj->iuser);
ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
if (ibuf) {
- image_buffer_rect_update(rj->scene, rr, ibuf, renrect);
+ /* Don't waste time on CPU side color management if
+ * image will be displayed using GLSL.
+ */
+ if (ibuf->channels == 1 ||
+ U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
+ {
+ image_buffer_rect_update(rj->scene, rr, ibuf, &rj->iuser, renrect);
+ }
/* make jobs timer to send notifier */
*(rj->do_update) = TRUE;
@@ -451,6 +547,28 @@ static void render_startjob(void *rjv, short *stop, short *do_update, float *pro
RE_SetReports(rj->re, NULL);
}
+static void render_image_restore_layer(RenderJob *rj)
+{
+ wmWindowManager *wm;
+
+ /* image window, compo node users */
+ for (wm = rj->main->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ ScrArea *sa;
+ for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+ if (sa == rj->sa) {
+ if (sa->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = sa->spacedata.first;
+ sima->iuser.layer = rj->orig_layer;
+ }
+ return;
+ }
+ }
+ }
+ }
+}
+
static void render_endjob(void *rjv)
{
RenderJob *rj = rjv;
@@ -481,6 +599,10 @@ static void render_endjob(void *rjv)
WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
}
+ if (rj->sa) {
+ render_image_restore_layer(rj);
+ }
+
/* XXX render stability hack */
G.is_rendering = FALSE;
WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);
@@ -592,6 +714,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
const char *name;
Object *active_object = CTX_data_active_object(C);
+ ScrArea *sa;
/* only one render job at a time */
if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
@@ -644,7 +767,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
// store spare
/* ensure at least 1 area shows result */
- render_view_open(C, event->x, event->y);
+ sa = render_view_open(C, event->x, event->y);
jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
@@ -658,7 +781,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj = MEM_callocN(sizeof(RenderJob), "render job");
rj->main = mainp;
rj->scene = scene;
- rj->win = CTX_wm_window(C);
rj->srl = srl;
rj->camera_override = camera_override;
rj->lay_override = 0;
@@ -667,6 +789,14 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->iuser.scene = scene;
rj->iuser.ok = 1;
rj->reports = op->reports;
+ rj->orig_layer = 0;
+ rj->last_layer = 0;
+ rj->sa = sa;
+
+ if (sa) {
+ SpaceImage *sima = sa->spacedata.first;
+ rj->orig_layer = sima->iuser.layer;
+ }
if (v3d) {
if (scene->lay != v3d->lay) {
@@ -699,7 +829,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
re = RE_NewRender(scene->id.name);
RE_test_break_cb(re, rj, render_breakjob);
RE_draw_lock_cb(re, rj, render_drawlock);
- RE_display_draw_cb(re, rj, image_rect_update);
+ RE_display_update_cb(re, rj, image_rect_update);
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
RE_progress_cb(re, rj, render_progress_update);
@@ -850,7 +980,7 @@ static int render_view3d_break(void *rpv)
return *(rp->stop);
}
-static void render_view3d_draw_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
+static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
{
RenderPreview *rp = rpv;
@@ -908,7 +1038,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
/* set this always, rp is different for each job */
RE_test_break_cb(re, rp, render_view3d_break);
- RE_display_draw_cb(re, rp, render_view3d_draw_update);
+ RE_display_update_cb(re, rp, render_view3d_display_update);
RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb);
rstats = RE_GetStats(re);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 081187ef1d8..99f86371eb3 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -625,7 +625,7 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
/* **************************** new shader preview system ****************** */
/* inside thread, called by renderer, sets job update value */
-static void shader_preview_draw(void *spv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
+static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
{
ShaderPreview *sp = spv;
@@ -734,7 +734,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
/* callbacs are cleared on GetRender() */
if (ELEM(sp->pr_method, PR_BUTS_RENDER, PR_NODE_RENDER)) {
- RE_display_draw_cb(re, sp, shader_preview_draw);
+ RE_display_update_cb(re, sp, shader_preview_update);
}
/* set this for all previews, default is react to G.is_break still */
RE_test_break_cb(re, sp, shader_preview_break);
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 1103f956f78..9f72ddc179f 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -132,7 +132,7 @@ static ScrArea *find_area_image_empty(bContext *C)
/********************** open image editor for render *************************/
/* new window uses x,y to set position */
-void render_view_open(bContext *C, int mx, int my)
+ScrArea *render_view_open(bContext *C, int mx, int my)
{
wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
@@ -141,7 +141,7 @@ void render_view_open(bContext *C, int mx, int my)
int area_was_image = 0;
if (scene->r.displaymode == R_OUTPUT_NONE)
- return;
+ return NULL;
if (scene->r.displaymode == R_OUTPUT_WINDOW) {
rcti rect;
@@ -226,6 +226,8 @@ void render_view_open(bContext *C, int mx, int my)
* full screen to the original tiled setup */
}
}
+
+ return sa;
}
/*************************** cancel render viewer **********************/
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index af5f9d3c875..230c3a11108 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -1050,39 +1050,6 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
- /* This is actually lots of crap, but currently not sure about
- * more clear way to bypass partial buffer update crappyness
- * while rendering.
- *
- * The thing is -- render engines are only updating byte and
- * display buffers for active render result opened in image
- * editor. This works fine to show render progress without
- * switching render layers in image editor user, but this is
- * completely useless for GLSL display, where we need to have
- * original buffer which we could color manage.
- *
- * For the time of rendering, we'll stick back to slower CPU
- * display buffer update. GLSL could be used as soon as some
- * fixes (?) are done in render itself, so we'll always have
- * image buffer with relevant float buffer opened while
- * rendering.
- *
- * On the other hand, when using Cycles, stressing GPU with
- * GLSL could backfire on a performance.
- * - sergey -
- */
- if (G.is_rendering) {
- /* Try to detect whether we're drawing render result,
- * other images could have both rect and rect_float
- * but they'll be synchronized
- */
- if (ibuf->rect_float && ibuf->rect &&
- ((ibuf->mall & IB_rectfloat) == 0))
- {
- force_fallback = true;
- }
- }
-
/* Try to draw buffer using GLSL display transform */
if (force_fallback == false) {
int ok;
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 139354c0afc..e57a876bcde 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1887,6 +1887,13 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, boo
bool requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
bool do_alpha_under = image_format_data->planes != R_IMF_PLANES_RGBA;
+ if (ibuf->rect_float && ibuf->rect &&
+ (ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0)
+ {
+ IMB_rect_from_float(ibuf);
+ ibuf->userflags &= ~(IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID);
+ }
+
do_colormanagement = save_as_render && (is_movie || !requires_linear_float);
if (do_colormanagement || do_alpha_under) {
@@ -2663,7 +2670,18 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
float pixel[4];
if (linear_buffer) {
- copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
+ if (channels == 4) {
+ copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
+ }
+ else if (channels == 3) {
+ copy_v3_v3(pixel, (float *) linear_buffer + linear_index);
+ }
+ else if (channels == 1) {
+ pixel[0] = linear_buffer[linear_index];
+ }
+ else {
+ BLI_assert(!"Unsupported number of channels in partial buffer update");
+ }
}
else if (byte_buffer) {
rgba_uchar_to_float(pixel, byte_buffer + linear_index);
@@ -2678,12 +2696,32 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
if (display_buffer_float) {
int index = ((y - ymin) * width + (x - xmin)) * channels;
- copy_v4_v4(display_buffer_float + index, pixel);
+ if (channels == 4) {
+ copy_v4_v4(display_buffer_float + index, pixel);
+ }
+ else if (channels == 3) {
+ copy_v3_v3(display_buffer_float + index, pixel);
+ }
+ else /* if (channels == 1) */ {
+ display_buffer_float[index] = pixel[0];
+ }
}
else {
- float pixel_straight[4];
- premul_to_straight_v4_v4(pixel_straight, pixel);
- rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ if (channels == 4) {
+ float pixel_straight[4];
+ premul_to_straight_v4_v4(pixel_straight, pixel);
+ rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ }
+ else if (channels == 3) {
+ rgb_float_to_uchar(display_buffer + display_index, pixel);
+ display_buffer[display_index + 1] = 255;
+ }
+ else /* if (channels == 1) */ {
+ display_buffer[display_index] =
+ display_buffer[display_index + 1] =
+ display_buffer[display_index + 2] =
+ display_buffer[display_index + 3] = FTOCHAR(pixel[0]);
+ }
}
}
}
@@ -2729,7 +2767,7 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
int channels = ibuf->channels;
int width = xmax - xmin;
int height = ymax - ymin;
- int rect_index = (ymin * ibuf->x + xmin) * channels;
+ int rect_index = (ymin * ibuf->x + xmin) * 4;
int linear_index = ((ymin - offset_y) * stride + (xmin - offset_x)) * channels;
IMB_buffer_byte_from_float(rect + rect_index, linear_buffer + linear_index, channels, ibuf->dither,
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 854275ccb64..031c5bdc367 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -393,7 +393,8 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_function_ui_description(func, "All pixels in the render result have been set and are final");
prop = RNA_def_pointer(func, "result", "RenderResult", "Result", "");
RNA_def_property_flag(prop, PROP_REQUIRED);
- RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results");
+ RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't mark tile as done, don't merge results unless forced");
+ RNA_def_boolean(func, "do_merge_results", 0, "Merge Results", "Merge results even if cancel=true");
func = RNA_def_function(srna, "test_break", "RE_engine_test_break");
RNA_def_function_ui_description(func, "Test if the render operation should been canceled, this is a fast call that should be used regularly for responsiveness");
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;