From 66c1b23aa10ded34869c2efabbe815ea254d4b09 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 15 Aug 2017 00:11:52 +0200 Subject: Cycles/BI: Add a pixel size option for speeding up viewport rendering This patch adds "Pixel Size" to the performance options, which allows to render in a smaller resolution, which is especially useful for displays with high DPI. Reviewers: Severin, dingto, sergey, brecht Reviewed By: brecht Subscribers: Severin, venomgfx, eyecandy, brecht Differential Revision: https://developer.blender.org/D1619 --- intern/cycles/blender/addon/ui.py | 1 + intern/cycles/blender/blender_sync.cpp | 2 ++ intern/cycles/render/session.cpp | 2 +- intern/cycles/render/session.h | 3 +++ intern/cycles/render/tile.cpp | 12 +++++++----- intern/cycles/render/tile.h | 3 ++- release/scripts/startup/bl_ui/properties_render.py | 1 + source/blender/blenkernel/BKE_scene.h | 2 ++ source/blender/blenkernel/intern/scene.c | 8 ++++++++ source/blender/editors/render/render_internal.c | 9 +++++---- source/blender/makesdna/DNA_scene_types.h | 3 +-- source/blender/makesrna/intern/rna_render.c | 14 ++++++++++++++ source/blender/makesrna/intern/rna_scene.c | 22 ++++++++++++++++++++++ 13 files changed, 69 insertions(+), 13 deletions(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index debc8e76e54..d8c2bde0b02 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -402,6 +402,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): col.prop(cscene, "debug_bvh_type", text="") col.separator() col.prop(cscene, "preview_start_resolution") + col.prop(rd, "preview_pixel_size", text="") col.separator() diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index f5e8d0633bc..a858af253d4 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -776,6 +776,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine, } params.start_resolution = get_int(cscene, "preview_start_resolution"); + params.pixel_size = b_engine.get_preview_pixel_size(b_scene); /* other parameters */ if(b_scene.render().threads_mode() == BL::RenderSettings::threads_mode_FIXED) @@ -796,6 +797,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine, params.progressive = false; params.start_resolution = INT_MAX; + params.pixel_size = 1; } else params.progressive = true; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index ca3aefcb5e6..3798483aa9c 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -46,7 +46,7 @@ Session::Session(const SessionParams& params_) : params(params_), tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution, params.background == false || params.progressive_refine, params.background, params.tile_order, - max(params.device.multi_devices.size(), 1)), + max(params.device.multi_devices.size(), 1), params.pixel_size), stats() { device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background); diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 9f8bb8c42fa..980eda0876d 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -53,6 +53,7 @@ public: int2 tile_size; TileOrder tile_order; int start_resolution; + int pixel_size; int threads; bool display_buffer_linear; @@ -81,6 +82,7 @@ public: samples = INT_MAX; tile_size = make_int2(64, 64); start_resolution = INT_MAX; + pixel_size = 1; threads = 0; use_denoising = false; @@ -110,6 +112,7 @@ public: && experimental == params.experimental && tile_size == params.tile_size && start_resolution == params.start_resolution + && pixel_size == params.pixel_size && threads == params.threads && display_buffer_linear == params.display_buffer_linear && cancel_timeout == params.cancel_timeout diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 176a1f4f0f3..4f3479c52ae 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -88,12 +88,14 @@ enum SpiralDirection { } /* namespace */ TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, - bool preserve_tile_device_, bool background_, TileOrder tile_order_, int num_devices_) + bool preserve_tile_device_, bool background_, TileOrder tile_order_, + int num_devices_, int pixel_size_) { progressive = progressive_; tile_size = tile_size_; tile_order = tile_order_; start_resolution = start_resolution_; + pixel_size = pixel_size_; num_samples = num_samples_; num_devices = num_devices_; preserve_tile_device = preserve_tile_device_; @@ -471,7 +473,7 @@ bool TileManager::done() int end_sample = (range_num_samples == -1) ? num_samples : range_start_sample + range_num_samples; - return (state.resolution_divider == 1) && + return (state.resolution_divider == pixel_size) && (state.sample+state.num_samples >= end_sample); } @@ -480,9 +482,9 @@ bool TileManager::next() if(done()) return false; - if(progressive && state.resolution_divider > 1) { + if(progressive && state.resolution_divider > pixel_size) { state.sample = 0; - state.resolution_divider /= 2; + state.resolution_divider = max(state.resolution_divider/2, pixel_size); state.num_samples = 1; set_tiles(); } @@ -496,7 +498,7 @@ bool TileManager::next() else state.num_samples = range_num_samples; - state.resolution_divider = 1; + state.resolution_divider = pixel_size; set_tiles(); } diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index e39a8f0627a..4cd57b7b30c 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -88,7 +88,7 @@ public: int num_samples; TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution, - bool preserve_tile_device, bool background, TileOrder tile_order, int num_devices = 1); + bool preserve_tile_device, bool background, TileOrder tile_order, int num_devices = 1, int pixel_size = 1); ~TileManager(); void free_device(); @@ -122,6 +122,7 @@ protected: int2 tile_size; TileOrder tile_order; int start_resolution; + int pixel_size; int num_devices; /* in some cases it is important that the same tile will be returned for the same diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index a7e8d9273ad..98aa4057a6e 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -275,6 +275,7 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel): col.separator() col.prop(rd, "preview_start_resolution") + col.prop(rd, "preview_pixel_size", text="") col = split.column() col.label(text="Memory:") diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index f1680b6ccbf..b7ecb85819e 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -152,6 +152,8 @@ bool BKE_scene_check_rigidbody_active(const struct Scene *scene); int BKE_scene_num_threads(const struct Scene *scene); int BKE_render_num_threads(const struct RenderData *r); +int BKE_render_preview_pixel_size(const struct RenderData *r); + double BKE_scene_unit_scale(const struct UnitSettings *unit, const int unit_type, double value); /* multiview */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b7fc6e70e65..b8ad54dc533 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -2411,6 +2411,14 @@ int BKE_scene_num_threads(const Scene *scene) return BKE_render_num_threads(&scene->r); } +int BKE_render_preview_pixel_size(const RenderData *r) +{ + if (r->preview_pixel_size == 0) { + return (U.pixelsize > 1.5f)? 2 : 1; + } + return r->preview_pixel_size; +} + /* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently) * and unit->scale_length. */ diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 9d98a3676ac..da14e72f887 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1171,7 +1171,7 @@ static void render_update_resolution(Render *re, const RenderPreview *rp, } if (rp->has_freestyle) { - if (rp->resolution_divider == 1) { + if (rp->resolution_divider == BKE_render_preview_pixel_size(&rp->scene->r)) { RE_ChangeModeFlag(re, R_EDGE_FRS, false); } else { @@ -1312,11 +1312,12 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda RE_updateRenderInstances(re, ob_inst_update_flag); for (;;) { + int pixel_size = BKE_render_preview_pixel_size(&rp->scene->r); if (first_time == false) { if (restore) RE_DataBase_IncrementalView(re, rp->viewmat, 1); - rp->resolution_divider /= 2; + rp->resolution_divider = MAX2(rp->resolution_divider/2, pixel_size); *do_update = 1; render_update_resolution(re, rp, use_border, &cliprct); @@ -1333,7 +1334,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda first_time = false; - if (*stop || rp->resolution_divider == 1) { + if (*stop || rp->resolution_divider == pixel_size) { break; } } @@ -1435,7 +1436,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C) Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); int width = ar->winx, height = ar->winy; - int divider = 1; + int divider = BKE_render_preview_pixel_size(&scene->r); int resolution_threshold = scene->r.preview_start_resolution * scene->r.preview_start_resolution; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 2bca5565553..de516dc0f1f 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -790,14 +790,13 @@ typedef struct RenderData { struct BakeData bake; int preview_start_resolution; + short preview_pixel_size; /* Type of the debug pass to use. * Only used when built with debug passes support. */ short debug_pass_type; - short pad; - /* MultiView */ ListBase views; /* SceneRenderView */ short actview; diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index c30765d8857..a66c160ed1a 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -33,6 +33,8 @@ #include "BLI_utildefines.h" #include "BLI_path_util.h" +#include "BKE_scene.h" + #include "RNA_define.h" #include "RNA_enum_types.h" @@ -123,6 +125,11 @@ static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Sce return IMB_colormanagement_support_glsl_draw(&scene->view_settings); } +static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *scene) +{ + return BKE_render_preview_pixel_size(&scene->r); +} + static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene) { IMB_colormanagement_setup_glsl_draw(&scene->view_settings, @@ -647,6 +654,13 @@ static void rna_def_render_engine(BlenderRNA *brna) parm = RNA_def_boolean(func, "supported", 0, "Supported", ""); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "get_preview_pixel_size", "engine_get_preview_pixel_size"); + RNA_def_function_ui_description(func, "Get the pixel size that should be used for preview rendering"); + parm = RNA_def_pointer(func, "scene", "Scene", "", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_int(func, "pixel_size", 0, 1, 8, "Pixel Size", "", 1, 8); + RNA_def_function_return(func, parm); + RNA_define_verify_sdna(0); prop = RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 2722f8759b8..71350edeb94 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1846,6 +1846,13 @@ static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), Pointer rna_Scene_use_simplify_update(bmain, sce, ptr); } +static void rna_SceneRenderData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Scene *sce = ptr->id.data; + + DAG_id_tag_update(&sce->id, 0); +} + static void rna_Scene_use_persistent_data_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *sce = ptr->id.data; @@ -5895,6 +5902,15 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem pixel_size_items[] = { + {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"}, + {1, "1", 0, "1x", "Render at full resolution"}, + {2, "2", 0, "2x", "Render at 50% resolution"}, + {4, "4", 0, "4x", "Render at 25% resolution"}, + {8, "8", 0, "8x", "Render at 12.5% resolution"}, + {0, NULL, 0, NULL, NULL} + }; + static EnumPropertyItem octree_resolution_items[] = { {64, "64", 0, "64", ""}, {128, "128", 0, "128", ""}, @@ -6018,6 +6034,12 @@ static void rna_def_scene_render_data(BlenderRNA *brna) "progressively increasing it to the full viewport size"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "preview_pixel_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "preview_pixel_size"); + RNA_def_property_enum_items(prop, pixel_size_items); + RNA_def_property_ui_text(prop, "Pixel Size", "Pixel size for viewport rendering"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderData_update"); + prop = RNA_def_property(srna, "pixel_aspect_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xasp"); RNA_def_property_flag(prop, PROP_PROPORTIONAL); -- cgit v1.2.3