diff options
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 14 | ||||
-rw-r--r-- | intern/cycles/render/session.cpp | 8 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_draw.c | 76 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_render.c | 3 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_engine.h | 3 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 83 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 14 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_result.c | 2 |
9 files changed, 184 insertions, 27 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index cd31a5b5bb6..770b71afcdc 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -107,6 +107,8 @@ void BlenderSession::create_session() /* set buffer parameters */ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height); session->reset(buffer_params, session_params.samples); + + b_engine.use_highlight_tiles(session_params.progressive_refine == false); } void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_) @@ -149,6 +151,8 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_) BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height); session->reset(buffer_params, session_params.samples); + + b_engine.use_highlight_tiles(session_params.progressive_refine == false); } void BlenderSession::free_session() @@ -252,7 +256,15 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda if (do_update_only) { /* update only needed */ - update_render_result(b_rr, b_rlay, rtile); + + if (rtile.sample != 0) { + /* sample would be zero at initial tile update, which is only needed + * to tag tile form blender side as IN PROGRESS for proper highlight + * no buffers should be sent to blender yet + */ + update_render_result(b_rr, b_rlay, rtile); + } + end_render_result(b_engine, b_rr, true); } else { diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 1d1a3d54893..36948adce17 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -357,7 +357,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) tile_lock.unlock(); - /* in case of a permant buffer, return it, otherwise we will allocate + /* in case of a permanent buffer, return it, otherwise we will allocate * a new temporary buffer */ if(!params.background) { tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride); @@ -411,6 +411,12 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile) rtile.rgba = 0; rtile.buffers = tilebuffers; + /* this will tag tile as IN PROGRESS in blender-side render pipeline, + * which is needed to highlight currently rendering tile before first + * sample was processed for it + */ + update_tile_sample(rtile); + return true; } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index e85ff016745..79130ccca2f 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -75,13 +75,15 @@ #include "WM_types.h" #include "RE_pipeline.h" +#include "RE_engine.h" #include "image_intern.h" -static void draw_render_info(Scene *scene, Image *ima, ARegion *ar) +static void draw_render_info(Scene *scene, Image *ima, ARegion *ar, float zoomx, float zoomy) { RenderResult *rr; - + Render *re = RE_GetRender(scene->id.name); + rr = BKE_image_acquire_renderresult(scene, ima); if (rr && rr->text) { @@ -89,6 +91,73 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar) } BKE_image_release_renderresult(scene, ima); + + if (re) { + int total_tiles; + rcti *tiles; + + RE_engine_get_current_tiles(re, &total_tiles, &tiles); + + if (total_tiles) { + int i, x, y; + rcti *tile; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + if (scene->r.mode & R_BORDER) { + glTranslatef(-scene->r.border.xmin * scene->r.xsch * scene->r.size / 100.0f, + -scene->r.border.ymin * scene->r.ysch * scene->r.size / 100.0f, + 0.0f); + } + + UI_ThemeColor(TH_FACE_SELECT); + + for (i = 0, tile = tiles; i < total_tiles; i++, tile++) { + float delta_x = 4.0f * UI_DPI_FAC / zoomx; + float delta_y = 4.0f * UI_DPI_FAC / zoomy; + + delta_x = min_ff(delta_x, tile->xmax - tile->xmin); + delta_y = min_ff(delta_y, tile->ymax - tile->ymin); + + /* left bottom corner */ + glBegin(GL_LINE_STRIP); + glVertex2f(tile->xmin, tile->ymin + delta_y); + glVertex2f(tile->xmin, tile->ymin); + glVertex2f(tile->xmin + delta_x, tile->ymin); + glEnd(); + + /* left top corner */ + glBegin(GL_LINE_STRIP); + glVertex2f(tile->xmin, tile->ymax - delta_y); + glVertex2f(tile->xmin, tile->ymax); + glVertex2f(tile->xmin + delta_x, tile->ymax); + glEnd(); + + /* right bottom corner */ + glBegin(GL_LINE_STRIP); + glVertex2f(tile->xmax - delta_x, tile->ymin); + glVertex2f(tile->xmax, tile->ymin); + glVertex2f(tile->xmax, tile->ymin + delta_y); + glEnd(); + + /* right top corner */ + glBegin(GL_LINE_STRIP); + glVertex2f(tile->xmax - delta_x, tile->ymax); + glVertex2f(tile->xmax, tile->ymax); + glVertex2f(tile->xmax, tile->ymax - delta_y); + glEnd(); + } + + MEM_freeN(tiles); + + glPopMatrix(); + } + } } /* used by node view too */ @@ -786,7 +855,6 @@ void draw_image_main(const bContext *C, ARegion *ar) if (sima->mode == SI_MODE_PAINT) draw_image_paint_helpers(C, ar, scene, zoomx, zoomy); - /* XXX integrate this code */ #if 0 if (ibuf) { @@ -812,5 +880,5 @@ void draw_image_main(const bContext *C, ARegion *ar) /* render info */ if (ima && show_render) - draw_render_info(scene, ima, ar); + draw_render_info(scene, ima, ar, zoomx, zoomy); } diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 03dc58233d5..93c5b45e642 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -406,6 +406,9 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "resolution_y"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES); + /* registration */ prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index d2ffc3a0e26..64135a16f5d 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -61,6 +61,7 @@ struct Scene; #define RE_ENGINE_DO_DRAW 4 #define RE_ENGINE_DO_UPDATE 8 #define RE_ENGINE_RENDERING 16 +#define RE_ENGINE_HIGHLIGHT_TILES 32 extern ListBase R_engines; @@ -130,5 +131,7 @@ void RE_engines_exit(void); RenderEngineType *RE_engines_find(const char *idname); +void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r); + #endif /* __RE_ENGINE_H__ */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 742241676dc..905b4b4f4a8 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -104,13 +104,19 @@ typedef struct RenderPart { rcti disprect; /* part coordinates within total picture */ int rectx, recty; /* the size */ - short crop, ready; /* crop is amount of pixels we crop, for filter */ + short crop, status; /* crop is amount of pixels we crop, for filter */ short sample, nr; /* sample can be used by zbuffers, nr is partnr */ short thread; /* thread id */ char *clipflag; /* clipflags for part zbuffering */ } RenderPart; +enum { + PART_STATUS_NONE = 0, + PART_STATUS_IN_PROGRESS = 1, + PART_STATUS_READY = 2 +}; + /* controls state of render, everything that's read-only during render stage */ struct Render { diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 6fdf11ba48c..296c8b6eba8 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -150,6 +150,23 @@ void RE_engine_free(RenderEngine *engine) /* Render Results */ +static RenderPart *get_part_from_result(Render *re, RenderResult *result) +{ + RenderPart *pa; + + for (pa = re->parts.first; pa; pa = pa->next) { + if (result->tilerect.xmin == pa->disprect.xmin - re->disprect.xmin && + result->tilerect.ymin == pa->disprect.ymin - re->disprect.ymin && + result->tilerect.xmax == pa->disprect.xmax - re->disprect.xmin && + result->tilerect.ymax == pa->disprect.ymax - re->disprect.ymin) + { + return pa; + } + } + + return NULL; +} + RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername) { Render *re = engine->re; @@ -179,12 +196,19 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, /* can be NULL if we CLAMP the width or height to 0 */ if (result) { + RenderPart *pa; + BLI_addtail(&engine->fullresult, result); result->tilerect.xmin += re->disprect.xmin; result->tilerect.xmax += re->disprect.xmin; result->tilerect.ymin += re->disprect.ymin; result->tilerect.ymax += re->disprect.ymin; + + pa = get_part_from_result(re, result); + + if (pa) + pa->status = PART_STATUS_IN_PROGRESS; } return result; @@ -203,7 +227,6 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result) void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel) { Render *re = engine->re; - RenderPart *pa; if (!result) { return; @@ -212,15 +235,10 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel /* merge. on break, don't merge in result for preview renders, looks nicer */ if (!cancel) { /* for exr tile render, detect tiles that are done */ - for (pa = re->parts.first; pa; pa = pa->next) { - if (result->tilerect.xmin == pa->disprect.xmin && - result->tilerect.ymin == pa->disprect.ymin && - result->tilerect.xmax == pa->disprect.xmax && - result->tilerect.ymax == pa->disprect.ymax) - { - pa->ready = 1; - } - } + RenderPart *pa = get_part_from_result(re, result); + + if (pa) + pa->status = PART_STATUS_READY; if (re->result->do_exr_tile) render_result_exr_file_merge(re->result, result); @@ -310,6 +328,47 @@ void RE_engine_report(RenderEngine *engine, int type, const char *msg) BKE_report(engine->reports, type, msg); } +void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r) +{ + RenderPart *pa; + int total_tiles = 0; + rcti *tiles = NULL; + int allocation_size = 0, allocation_step = BLENDER_MAX_THREADS; + + if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) { + *total_tiles_r = 0; + *tiles_r = NULL; + return; + } + + for (pa = re->parts.first; pa; pa = pa->next) { + if (pa->status == PART_STATUS_IN_PROGRESS) { + if (total_tiles >= allocation_size) { + if (tiles == NULL) + tiles = MEM_mallocN(allocation_step * sizeof(rcti), "current engine tiles"); + else + tiles = MEM_reallocN(tiles, (total_tiles + allocation_step) * sizeof(rcti)); + + allocation_size += allocation_step; + } + + tiles[total_tiles] = pa->disprect; + + if (pa->crop) { + tiles[total_tiles].xmin += pa->crop; + tiles[total_tiles].ymin += pa->crop; + tiles[total_tiles].xmax -= pa->crop; + tiles[total_tiles].ymax -= pa->crop; + } + + total_tiles++; + } + } + + *total_tiles_r = total_tiles; + *tiles_r = tiles; +} + /* Render */ int RE_engine_render(Render *re, int do_all) @@ -354,9 +413,7 @@ int RE_engine_render(Render *re, int do_all) if (!engine) { engine = RE_engine_create(type); - - if (persistent_data) - re->engine = engine; + re->engine = engine; } engine->flag |= RE_ENGINE_RENDERING; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index f2db84c47a9..755c8f40ba1 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -655,7 +655,9 @@ static int render_display_draw_enabled(Render *re) static void *do_part_thread(void *pa_v) { RenderPart *pa = pa_v; - + + pa->status = PART_STATUS_IN_PROGRESS; + /* need to return nicely all parts on esc */ if (R.test_break(R.tbh) == 0) { @@ -686,7 +688,7 @@ static void *do_part_thread(void *pa_v) } } - pa->ready = 1; + pa->status = PART_STATUS_READY; return NULL; } @@ -727,7 +729,7 @@ static RenderPart *find_next_pano_slice(Render *re, int *minx, rctf *viewplane) /* most left part of the non-rendering parts */ for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->ready == 0 && pa->nr == 0) { + if (pa->status == PART_STATUS_NONE && pa->nr == 0) { if (pa->disprect.xmin < *minx) { best = pa; *minx = pa->disprect.xmin; @@ -765,7 +767,7 @@ static RenderPart *find_next_part(Render *re, int minx) /* find center of rendered parts, image center counts for 1 too */ for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->ready) { + if (pa->status == PART_STATUS_READY) { centx += BLI_rcti_cent_x(&pa->disprect); centy += BLI_rcti_cent_y(&pa->disprect); tot++; @@ -776,7 +778,7 @@ static RenderPart *find_next_part(Render *re, int minx) /* closest of the non-rendering parts */ for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->ready == 0 && pa->nr == 0) { + if (pa->status == PART_STATUS_NONE && pa->nr == 0) { long long int distx = centx - BLI_rcti_cent_x(&pa->disprect); long long int disty = centy - BLI_rcti_cent_y(&pa->disprect); distx = (long long int)sqrt(distx * distx + disty * disty); @@ -884,7 +886,7 @@ static void threaded_tile_processor(Render *re) rendering = 0; hasdrawn = 0; for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->ready) { + if (pa->status == PART_STATUS_READY) { BLI_remove_thread(&threads, pa); diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index 78750cfd1ca..6de5830df27 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -924,7 +924,7 @@ static void save_empty_result_tiles(Render *re) IMB_exrtile_clear_channels(rl->exrhandle); for (pa = re->parts.first; pa; pa = pa->next) { - if (pa->ready == 0) { + if (pa->status != PART_STATUS_READY) { int party = pa->disprect.ymin - re->disprect.ymin + pa->crop; int partx = pa->disprect.xmin - re->disprect.xmin + pa->crop; IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0); |