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
path: root/intern
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2021-05-17 19:23:44 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2021-05-18 11:13:09 +0300
commit97f1e4782a6fbc350f23a7f5c8520ffdf391f26c (patch)
treeff9c9aa7117c96d28fecb46c1853753741bf54ce /intern
parent1c1fa15ce1de68690da9bd0eec7ea50b683d2352 (diff)
Cycles: Avoid unnecessary data updates in viewport
The BlenderSync will do quite a bit of work on every sync_data() call even if there is nothing changed in the scene. There will be early outputs done deeper in the call graph, but this is not really enough to ensure best performance during viewport navigation. This change makes it so sync_data() is only used when dependency graph has any update tags: if something changed in the scene the dependency graph will know it. If nothing changed there will be no IDs tagged for an update in the dependency graph. There are two weak parts in the current change: - With the persistent data there is a special call to ignore the check of the dependency graph tags. This is more of a safety, because it is not immediately clear what the correct state of recalc flags is. - Deletion of objects is detected indirectly, via tags of scene and collections. It might not be bad for the first version of the change. The test file used: {F10117322} Simply open the file, start viewport render, and navigate the viewport. On my computer this avoids 0.2sec spend on data_sync() on every up[date of viewport navigation. We can do way more granular updates in the future: for example, avoid heavy objects sync when it is only camera object which changed. This will need an extended support from the dependency graph API. Doing nothing if nothing is changed is something we would want to do anyway. Differential Revision: https://developer.blender.org/D11279
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_sync.cpp21
-rw-r--r--intern/cycles/blender/blender_sync.h6
2 files changed, 25 insertions, 2 deletions
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 4af8da402b1..9d0f9f29f94 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -69,7 +69,8 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
experimental(false),
dicing_rate(1.0f),
max_subdivisions(12),
- progress(progress)
+ progress(progress),
+ has_updates_(true)
{
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") :
@@ -84,7 +85,9 @@ BlenderSync::~BlenderSync()
void BlenderSync::reset(BL::BlendData &b_data, BL::Scene &b_scene)
{
/* Update data and scene pointers in case they change in session reset,
- * for example after undo. */
+ * for example after undo.
+ * Note that we do not modify the `has_updates_` flag here because the sync
+ * reset is also used during viewport navigation. */
this->b_data = b_data;
this->b_scene = b_scene;
}
@@ -117,6 +120,8 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
if (dicing_prop_changed) {
+ has_updates_ = true;
+
for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) {
Geometry *geom = iter.second;
if (geom->is_mesh()) {
@@ -133,6 +138,12 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Iterate over all IDs in this depsgraph. */
for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
+ /* TODO(sergey): Can do more selective filter here. For example, ignore changes made to
+ * screen datablock. Note that sync_data() needs to be called after object deletion, and
+ * currently this is ensured by the scene ID tagged for update, which sets the `has_updates_`
+ * flag. */
+ has_updates_ = true;
+
BL::ID b_id(b_update.id());
/* Material */
@@ -227,6 +238,10 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
int height,
void **python_thread_state)
{
+ if (!has_updates_) {
+ return;
+ }
+
scoped_timer timer;
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
@@ -254,6 +269,8 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
free_data_after_sync(b_depsgraph);
VLOG(1) << "Total time spent synchronizing data: " << timer.get_time();
+
+ has_updates_ = false;
}
/* Integrator */
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index a222c5e490e..15a10f2b46b 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -264,6 +264,12 @@ class BlenderSync {
} view_layer;
Progress &progress;
+
+ protected:
+ /* Indicates that `sync_recalc()` detected changes in the scene.
+ * If this flag is false then the data is considered to be up-to-date and will not be
+ * synchronized at all. */
+ bool has_updates_ = true;
};
CCL_NAMESPACE_END