[Bf-blender-cvs] [ffb3365fb20] master: Fix T63588: Cycles unnecessarily updates background importance sampling map

Tautvydas Andrikys noreply at git.blender.org
Tue Jun 2 19:55:22 CEST 2020


Commit: ffb3365fb2063966ead370d8668a259a5525175f
Author: Tautvydas Andrikys
Date:   Thu May 14 17:41:37 2020 +0200
Branches: master
https://developer.blender.org/rBffb3365fb2063966ead370d8668a259a5525175f

Fix T63588: Cycles unnecessarily updates background importance sampling map

With modifications by Brecht to solve T77273, crash enabling portal lights.

===================================================================

M	intern/cycles/render/light.cpp
M	intern/cycles/render/light.h
M	intern/cycles/render/shader.cpp

===================================================================

diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 76a2f17bd1b..cb7474017fa 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -182,7 +182,10 @@ bool Light::has_contribution(Scene *scene)
 LightManager::LightManager()
 {
   need_update = true;
+  need_update_background = true;
   use_light_visibility = false;
+  last_background_enabled = false;
+  last_background_resolution = 0;
 }
 
 LightManager::~LightManager()
@@ -202,7 +205,7 @@ bool LightManager::has_background_light(Scene *scene)
   return false;
 }
 
-void LightManager::disable_ineffective_light(Scene *scene)
+void LightManager::test_enabled_lights(Scene *scene)
 {
   /* Make all lights enabled by default, and perform some preliminary checks
    * needed for finer-tuning of settings (for example, check whether we've
@@ -215,6 +218,9 @@ void LightManager::disable_ineffective_light(Scene *scene)
     has_background |= light->type == LIGHT_BACKGROUND;
   }
 
+  bool background_enabled = false;
+  int background_resolution = 0;
+
   if (has_background) {
     /* Ignore background light if:
      * - If unsupported on a device
@@ -226,9 +232,18 @@ void LightManager::disable_ineffective_light(Scene *scene)
     foreach (Light *light, scene->lights) {
       if (light->type == LIGHT_BACKGROUND) {
         light->is_enabled = !disable_mis;
+        background_enabled = !disable_mis;
+        background_resolution = light->map_resolution;
       }
     }
   }
+
+  if (last_background_enabled != background_enabled ||
+      last_background_resolution != background_resolution) {
+    last_background_enabled = background_enabled;
+    last_background_resolution = background_resolution;
+    need_update_background = true;
+  }
 }
 
 bool LightManager::object_usable_as_light(Object *object)
@@ -902,11 +917,12 @@ void LightManager::device_update(Device *device,
 
   VLOG(1) << "Total " << scene->lights.size() << " lights.";
 
-  device_free(device, dscene);
+  /* Detect which lights are enabled, also determins if we need to update the background. */
+  test_enabled_lights(scene);
 
-  use_light_visibility = false;
+  device_free(device, dscene, need_update_background);
 
-  disable_ineffective_light(scene);
+  use_light_visibility = false;
 
   device_update_points(device, dscene, scene);
   if (progress.get_cancel())
@@ -916,9 +932,11 @@ void LightManager::device_update(Device *device,
   if (progress.get_cancel())
     return;
 
-  device_update_background(device, dscene, scene, progress);
-  if (progress.get_cancel())
-    return;
+  if (need_update_background) {
+    device_update_background(device, dscene, scene, progress);
+    if (progress.get_cancel())
+      return;
+  }
 
   device_update_ies(dscene);
   if (progress.get_cancel())
@@ -930,14 +948,17 @@ void LightManager::device_update(Device *device,
   }
 
   need_update = false;
+  need_update_background = false;
 }
 
-void LightManager::device_free(Device *, DeviceScene *dscene)
+void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background)
 {
   dscene->light_distribution.free();
   dscene->lights.free();
-  dscene->light_background_marginal_cdf.free();
-  dscene->light_background_conditional_cdf.free();
+  if (free_background) {
+    dscene->light_background_marginal_cdf.free();
+    dscene->light_background_conditional_cdf.free();
+  }
   dscene->ies_lights.free();
 }
 
@@ -990,6 +1011,7 @@ int LightManager::add_ies(const string &content)
   ies_slots[slot]->hash = hash;
 
   need_update = true;
+  need_update_background = true;
 
   return slot;
 }
@@ -1008,6 +1030,7 @@ void LightManager::remove_ies(int slot)
 
   /* If the slot has no more users, update the device to remove it. */
   need_update |= (ies_slots[slot]->users == 0);
+  need_update_background |= need_update;
 }
 
 void LightManager::device_update_ies(DeviceScene *dscene)
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 4f3048c1f32..d136e8f1a08 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -88,6 +88,9 @@ class LightManager {
   bool use_light_visibility;
   bool need_update;
 
+  /* Need to update background (including multiple importance map) */
+  bool need_update_background;
+
   LightManager();
   ~LightManager();
 
@@ -97,7 +100,7 @@ class LightManager {
   void remove_ies(int slot);
 
   void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
-  void device_free(Device *device, DeviceScene *dscene);
+  void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
 
   void tag_update(Scene *scene);
 
@@ -109,7 +112,7 @@ class LightManager {
    * which doesn't contribute to the scene or which is only used for MIS
    * and scene doesn't need MIS.
    */
-  void disable_ineffective_light(Scene *scene);
+  void test_enabled_lights(Scene *scene);
 
   void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
   void device_update_distribution(Device *device,
@@ -133,6 +136,9 @@ class LightManager {
 
   vector<IESSlot *> ies_slots;
   thread_mutex ies_mutex;
+
+  bool last_background_enabled;
+  int last_background_resolution;
 };
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 8403a636e1c..39ba45a751a 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -318,9 +318,11 @@ void Shader::tag_update(Scene *scene)
    * has use_mis set to false. We are quite close to release now, so
    * better to be safe.
    */
-  if (this == scene->background->get_shader(scene) &&
-      scene->light_manager->has_background_light(scene)) {
-    scene->light_manager->need_update = true;
+  if (this == scene->background->get_shader(scene)) {
+    scene->light_manager->need_update_background = true;
+    if (scene->light_manager->has_background_light(scene)) {
+      scene->light_manager->need_update = true;
+    }
   }
 
   /* quick detection of which kind of shaders we have to avoid loading



More information about the Bf-blender-cvs mailing list