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:
authorBastien Montagne <montagne29@wanadoo.fr>2014-06-28 21:13:54 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-06-28 21:23:34 +0400
commit78cdc707ab4d10017c70e5c860146f40ec8457a4 (patch)
treea4bcd6c40b0c60df11ec65fc1f2440ea4302d39a
parent0caee7843e51c5c7a24e24a18de4f4aa6cbf6550 (diff)
Add render result caching.
Simply add an option to render settings to save an EXR cache, just when the render is finished. Also changed RE_ReadRenderResult() to read cache instead of temp sample files (those are fully volatile now anyway). Path to save cached render results is an UserPreferences setting. Also added 'Reload render' feature to the Image Editor (so one can now re-open a blend, and in an Image Editor hit ctrl-R to (try to) reload last render from cache). Reviewers: campbellbarton, sergey Differential Revision: https://developer.blender.org/D553
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py4
-rw-r--r--release/scripts/startup/bl_ui/space_image.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py2
-rw-r--r--source/blender/editors/space_image/image_intern.h2
-rw-r--r--source/blender/editors/space_image/image_ops.c32
-rw-r--r--source/blender/editors/space_image/space_image.c3
-rw-r--r--source/blender/makesdna/DNA_scene_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c8
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c4
-rw-r--r--source/blender/render/intern/include/render_result.h7
-rw-r--r--source/blender/render/intern/source/external_engine.c6
-rw-r--r--source/blender/render/intern/source/pipeline.c19
-rw-r--r--source/blender/render/intern/source/render_result.c70
14 files changed, 149 insertions, 13 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index ce375eca894..42cb6086c35 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -396,7 +396,9 @@ class RENDER_PT_output(RenderButtonsPanel, Panel):
col.prop(rd, "use_overwrite")
col.prop(rd, "use_placeholder")
- split.prop(rd, "use_file_extension")
+ col = split.column()
+ col.prop(rd, "use_file_extension")
+ col.prop(rd, "use_render_cache")
layout.template_image_settings(image_settings, color_management=False)
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index f19e77eff8e..97c89df0693 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -154,6 +154,8 @@ class IMAGE_MT_image(Menu):
show_render = sima.show_render
+ layout.operator("image.read_renderlayers")
+
if ima:
if not show_render:
layout.operator("image.replace")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 31ca972726e..cba6f065a6f 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -865,6 +865,7 @@ class USERPREF_PT_file(Panel):
sub.label(text="Scripts:")
sub.label(text="Sounds:")
sub.label(text="Temp:")
+ sub.label(text="Render Cache:")
sub.label(text="I18n Branches:")
sub.label(text="Image Editor:")
sub.label(text="Animation Player:")
@@ -876,6 +877,7 @@ class USERPREF_PT_file(Panel):
sub.prop(paths, "script_directory", text="")
sub.prop(paths, "sound_directory", text="")
sub.prop(paths, "temporary_directory", text="")
+ sub.prop(paths, "render_cache_directory", text="")
sub.prop(paths, "i18n_branches_directory", text="")
sub.prop(paths, "image_editor", text="")
subsplit = sub.split(percentage=0.3)
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 4d391874f9b..8e556378803 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -90,6 +90,8 @@ void IMAGE_OT_curves_point_set(struct wmOperatorType *ot);
void IMAGE_OT_change_frame(struct wmOperatorType *ot);
+void IMAGE_OT_read_renderlayers(struct wmOperatorType *ot);
+
/* image_panels.c */
struct ImageUser *ntree_get_active_iuser(struct bNodeTree *ntree);
void image_buttons_register(struct ARegionType *art);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index cc769f13b82..7c021cf6645 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2997,3 +2997,35 @@ void IMAGE_OT_change_frame(wmOperatorType *ot)
/* rna */
RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
}
+
+/* Reload cached render results... */
+/* goes over all scenes, reads render layers */
+static int image_read_renderlayers_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *ima;
+
+ ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
+ if (sima->image == NULL) {
+ ED_space_image_set(sima, scene, NULL, ima);
+ }
+
+ RE_ReadRenderResult(scene, scene);
+
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_read_renderlayers(wmOperatorType *ot)
+{
+ ot->name = "Read Render Layers";
+ ot->idname = "IMAGE_OT_read_renderlayers";
+ ot->description = "Read all the current scene's render layers from cache, as needed";
+
+ ot->poll = space_image_main_area_poll;
+ ot->exec = image_read_renderlayers_exec;
+
+ /* flags */
+ ot->flag = 0;
+}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index d1868951987..0fb93ad27ee 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -255,6 +255,8 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_toolshelf);
WM_operatortype_append(IMAGE_OT_change_frame);
+
+ WM_operatortype_append(IMAGE_OT_read_renderlayers);
}
static void image_keymap(struct wmKeyConfig *keyconf)
@@ -266,6 +268,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_read_renderlayers", RKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_save", SKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c95cdb5c1f8..6b1cad120a7 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1377,6 +1377,7 @@ typedef struct Scene {
/* #define R_RECURS_PROTECTION 0x20000 */
#define R_TEXNODE_PREVIEW 0x40000
#define R_VIEWPORT_PREVIEW 0x80000
+#define R_EXR_CACHE_FILE 0x100000
/* r->stamp */
#define R_STAMP_TIME 0x0001
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 987985f0ba7..cb2341b0b7f 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -422,6 +422,8 @@ typedef struct UserDef {
char tempdir[768]; /* FILE_MAXDIR length */
char fontdir[768];
char renderdir[1024]; /* FILE_MAX length */
+ /* EXR cache path */
+ char render_cachedir[768]; /* 768 = FILE_MAXDIR */
char textudir[768];
char pythondir[768];
char sounddir[768];
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index bcdb469dd85..bce7d0062f2 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -4811,6 +4811,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"and length of frame numbers");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ /* Render result EXR cache. */
+ prop = RNA_def_property(srna, "use_render_cache", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXR_CACHE_FILE);
+ RNA_def_property_ui_text(prop, "Cache Result",
+ "Save render cache to EXR files (useful for heavy compositing, "
+ "Note: affects indirectly rendered scenes)");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
/* Bake */
prop = RNA_def_property(srna, "bake_type", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index f69e768670e..f4974266f60 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -4272,6 +4272,10 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Temporary Directory", "The directory for storing temporary save files");
RNA_def_property_update(prop, 0, "rna_userdef_temp_update");
+ prop = RNA_def_property(srna, "render_cache_directory", PROP_STRING, PROP_DIRPATH);
+ RNA_def_property_string_sdna(prop, NULL, "render_cachedir");
+ RNA_def_property_ui_text(prop, "Render Cache Path", "Where to cache raw render results");
+
prop = RNA_def_property(srna, "image_editor", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "image_editor");
RNA_def_property_ui_text(prop, "Image Editor", "Path to an image editor");
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 457f1377e9b..90ff69dbfbe 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -81,9 +81,14 @@ void render_result_exr_file_end(struct Render *re);
void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart);
void render_result_exr_file_path(struct Scene *scene, const char *layname, int sample, char *filepath);
-int render_result_exr_file_read(struct Render *re, int sample);
+int render_result_exr_file_read_sample(struct Render *re, int sample);
int render_result_exr_file_read_path(struct RenderResult *rr, struct RenderLayer *rl_single, const char *filepath);
+/* EXR cache */
+
+void render_result_exr_file_cache_write(struct Render *re);
+bool render_result_exr_file_cache_read(struct Render *re);
+
/* Combined Pixel Rect */
struct ImBuf *render_result_rect_to_ibuf(struct RenderResult *rr, struct RenderData *rd);
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 1df701c48eb..95ff68dadb3 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -664,6 +664,12 @@ int RE_engine_render(Render *re, int do_all)
BLI_rw_mutex_unlock(&re->resultmutex);
}
+ if (re->r.scemode & R_EXR_CACHE_FILE) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_exr_file_cache_write(re);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
+
RE_parts_free(re);
if (BKE_reports_contain(re->reports, RPT_ERROR))
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index bdd911df33b..9f27021d23e 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1229,7 +1229,13 @@ static void threaded_tile_processor(Render *re)
render_result_exr_file_end(re);
BLI_rw_mutex_unlock(&re->resultmutex);
}
-
+
+ if (re->r.scemode & R_EXR_CACHE_FILE) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_exr_file_cache_write(re);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
+
/* unset threadsafety */
g_break = 0;
@@ -1662,7 +1668,10 @@ static void render_scene(Render *re, Scene *sce, int cfra)
/* initial setup */
RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect);
-
+
+ /* We still want to use 'rendercache' setting from org (main) scene... */
+ resc->r.scemode = (resc->r.scemode & ~R_EXR_CACHE_FILE) | (re->r.scemode & R_EXR_CACHE_FILE);
+
/* still unsure entity this... */
resc->main = re->main;
resc->scene = sce;
@@ -1967,7 +1976,7 @@ static void composite_freestyle_renders(Render *re, int sample)
/* may be NULL in case of empty render layer */
if (freestyle_render) {
- render_result_exr_file_read(freestyle_render, sample);
+ render_result_exr_file_read_sample(freestyle_render, sample);
FRS_composite_result(re, srl, freestyle_render);
RE_FreeRenderResult(freestyle_render->result);
freestyle_render->result = NULL;
@@ -2041,7 +2050,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
if (re1 && (re1->r.scemode & R_FULL_SAMPLE)) {
if (sample) {
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- render_result_exr_file_read(re1, sample);
+ render_result_exr_file_read_sample(re1, sample);
#ifdef WITH_FREESTYLE
if (re1->r.mode & R_EDGE_FRS)
composite_freestyle_renders(re1, sample);
@@ -3108,7 +3117,7 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
re->scene_color_manage = BKE_scene_check_color_management_enabled(scene);
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- success = render_result_exr_file_read(re, 0);
+ success = render_result_exr_file_cache_read(re);
BLI_rw_mutex_unlock(&re->resultmutex);
return success;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index dd867852bdb..d8410fbe257 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -37,6 +37,7 @@
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
+#include "BLI_md5.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
@@ -1012,7 +1013,7 @@ void render_result_exr_file_end(Render *re)
render_result_free_list(&re->fullresult, re->result);
re->result = NULL;
- render_result_exr_file_read(re, 0);
+ render_result_exr_file_read_sample(re, 0);
}
/* save part into exr file */
@@ -1038,25 +1039,23 @@ void render_result_exr_file_path(Scene *scene, const char *layname, int sample,
BLI_make_file_string("/", filepath, BLI_temp_dir_session(), name);
}
-/* only for temp buffer files, makes exact copy of render result */
-int render_result_exr_file_read(Render *re, int sample)
+/* only for temp buffer, makes exact copy of render result */
+int render_result_exr_file_read_sample(Render *re, int sample)
{
RenderLayer *rl;
- char str[FILE_MAX];
+ char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
bool success = true;
RE_FreeRenderResult(re->result);
re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
for (rl = re->result->layers.first; rl; rl = rl->next) {
-
render_result_exr_file_path(re->scene, rl->name, sample, str);
printf("read exr tmp file: %s\n", str);
if (!render_result_exr_file_read_path(re->result, rl, str)) {
printf("cannot read: %s\n", str);
success = false;
-
}
}
@@ -1115,6 +1114,65 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
return 1;
}
+static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path)
+{
+ char filename_full[FILE_MAX + MAX_ID_NAME + 100], filename[FILE_MAXFILE], dirname[FILE_MAXDIR];
+ char path_digest[16] = {0};
+ char path_hexdigest[33];
+
+ /* If root is relative, use either current .blend file dir, or temp one if not saved. */
+ if (G.main->name[0]) {
+ BLI_split_dirfile(G.main->name, dirname, filename, sizeof(dirname), sizeof(filename));
+ BLI_replace_extension(filename, sizeof(filename), ""); /* strip '.blend' */
+ md5_buffer(G.main->name, strlen(G.main->name), path_digest);
+ }
+ else {
+ BLI_strncpy(dirname, BLI_temp_dir_base(), sizeof(dirname));
+ BLI_strncpy(filename, "UNSAVED", sizeof(filename));
+ }
+ md5_to_hexdigest(path_digest, path_hexdigest);
+
+ /* Default to *non-volatile* tmp dir. */
+ if (*root == '\0') {
+ root = BLI_temp_dir_base();
+ }
+
+ BLI_snprintf(filename_full, sizeof(filename_full), "cached_RR_%s_%s_%s.exr",
+ filename, sce->id.name + 2, path_hexdigest);
+ BLI_make_file_string(dirname, r_path, root, filename_full);
+}
+
+void render_result_exr_file_cache_write(Render *re)
+{
+ RenderResult *rr = re->result;
+ char str[FILE_MAXFILE + FILE_MAXFILE + MAX_ID_NAME + 100];
+ char *root = U.render_cachedir;
+
+ render_result_exr_file_cache_path(re->scene, root, str);
+ printf("Caching exr file, %dx%d, %s\n", rr->rectx, rr->recty, str);
+ RE_WriteRenderResult(NULL, rr, str, 0);
+}
+
+/* For cache, makes exact copy of render result */
+bool render_result_exr_file_cache_read(Render *re)
+{
+ char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
+ char *root = U.render_cachedir;
+
+ RE_FreeRenderResult(re->result);
+ re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS);
+
+ /* First try cache. */
+ render_result_exr_file_cache_path(re->scene, root, str);
+
+ printf("read exr cache file: %s\n", str);
+ if (!render_result_exr_file_read_path(re->result, NULL, str)) {
+ printf("cannot read: %s\n", str);
+ return false;
+ }
+ return true;
+}
+
/*************************** Combined Pixel Rect *****************************/
ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)