Fix T63588: Cycles unnecessarily updates background importance sampling map
With modifications by Brecht to solve T77273, crash enabling portal lights.
This commit is contained in:
parent
0465086223
commit
ffb3365fb2
@ -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,12 +917,13 @@ 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);
|
||||
|
||||
device_free(device, dscene, need_update_background);
|
||||
|
||||
use_light_visibility = false;
|
||||
|
||||
disable_ineffective_light(scene);
|
||||
|
||||
device_update_points(device, dscene, scene);
|
||||
if (progress.get_cancel())
|
||||
return;
|
||||
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user