diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 7 | ||||
-rw-r--r-- | source/blender/editors/render/render_intern.h | 6 | ||||
-rw-r--r-- | source/blender/editors/render/render_internal.c | 190 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 4 | ||||
-rw-r--r-- | source/blender/editors/render/render_view.c | 6 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 33 | ||||
-rw-r--r-- | source/blender/imbuf/intern/colormanagement.c | 50 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_render.c | 3 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_engine.h | 2 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/envmap.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 54 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 2 |
15 files changed, 259 insertions, 116 deletions
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; |