From efc8970015daea137eeb238f4484fac3ffb47069 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 31 Aug 2025 03:03:19 +0200 Subject: [PATCH] Fix: Cycles: Invalidate caches when scene linear colorspace changes Don't assume the configuration remains the same. Pull Request: https://projects.blender.org/blender/blender/pulls/145755 --- intern/cycles/scene/colorspace.cpp | 40 +++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/intern/cycles/scene/colorspace.cpp b/intern/cycles/scene/colorspace.cpp index 596ebadd7be..4bc25d44d72 100644 --- a/intern/cycles/scene/colorspace.cpp +++ b/intern/cycles/scene/colorspace.cpp @@ -27,11 +27,44 @@ ustring u_colorspace_srgb("__builtin_srgb"); /* Cached data. */ #ifdef WITH_OCIO static thread_mutex cache_colorspaces_mutex; -static thread_mutex cache_processors_mutex; static unordered_map cached_colorspaces; + +static thread_mutex cache_processors_mutex; static unordered_map cached_processors; + +static thread_mutex cache_scene_linear_mutex; +static string cache_scene_linear_name; #endif +static void check_invalidate_caches() +{ + /* Invalidate cached processors and colorspace, in case Blender changed it. + * Note this should not happen during rendering, all render should be stopped + * before it is changed. */ + const thread_scoped_lock cache_scene_linear_lock(cache_scene_linear_mutex); + OCIO::ConstConfigRcPtr config = nullptr; + try { + config = OCIO::GetCurrentConfig(); + } + catch (const OCIO::Exception &exception) { + LOG_WARNING << "OCIO config error: " << exception.what(); + return; + } + + const OCIO::ConstColorSpaceRcPtr scene_linear_colorspace = config->getColorSpace("scene_linear"); + if (scene_linear_colorspace && cache_scene_linear_name != scene_linear_colorspace->getName()) { + cache_scene_linear_name = scene_linear_colorspace->getName(); + { + const thread_scoped_lock cache_processors_lock(cache_processors_mutex); + cached_processors.clear(); + } + { + const thread_scoped_lock cache_lock(cache_colorspaces_mutex); + cached_colorspaces.clear(); + } + } +} + ColorSpaceProcessor *ColorSpaceManager::get_processor(ustring colorspace) { #ifdef WITH_OCIO @@ -55,9 +88,12 @@ ColorSpaceProcessor *ColorSpaceManager::get_processor(ustring colorspace) return nullptr; } + check_invalidate_caches(); + /* Cache processor until free_memory(), memory overhead is expected to be * small and the processor is likely to be reused. */ const thread_scoped_lock cache_processors_lock(cache_processors_mutex); + if (cached_processors.find(colorspace) == cached_processors.end()) { try { cached_processors[colorspace] = config->getProcessor(colorspace.c_str(), "scene_linear"); @@ -138,6 +174,8 @@ ustring ColorSpaceManager::detect_known_colorspace(ustring colorspace, /* Use OpenColorIO. */ #ifdef WITH_OCIO + check_invalidate_caches(); + { const thread_scoped_lock cache_lock(cache_colorspaces_mutex); /* Cached lookup. */