From b4c368531313ae22d289c92bff97663e9c809e1f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 31 Aug 2025 03:02:17 +0200 Subject: [PATCH] Refactor: Color Management: Add function to change scene linear role There is a bad const cast here, but seems to work ok in practice. Creating a whole new config would be tricky, though something we should support in the future for other reasons. Pull Request: https://projects.blender.org/blender/blender/pulls/145476 --- .../blender/imbuf/opencolorio/OCIO_config.hh | 8 +++++ .../opencolorio/OCIO_gpu_shader_binder.hh | 5 ++++ .../intern/fallback/fallback_config.cc | 8 +++++ .../intern/fallback/fallback_config.hh | 3 ++ .../opencolorio/intern/gpu_shader_binder.cc | 6 ++++ .../intern/libocio/libocio_colorspace.cc | 7 +++++ .../intern/libocio/libocio_colorspace.hh | 2 ++ .../intern/libocio/libocio_config.cc | 30 +++++++++++++++++++ .../intern/libocio/libocio_config.hh | 3 ++ .../intern/libocio/libocio_display.cc | 8 +++++ .../intern/libocio/libocio_display.hh | 2 ++ 11 files changed, 82 insertions(+) diff --git a/source/blender/imbuf/opencolorio/OCIO_config.hh b/source/blender/imbuf/opencolorio/OCIO_config.hh index 669d2fb1e3c..626bb83dd0f 100644 --- a/source/blender/imbuf/opencolorio/OCIO_config.hh +++ b/source/blender/imbuf/opencolorio/OCIO_config.hh @@ -135,6 +135,14 @@ class Config { /** \} */ + /* -------------------------------------------------------------------- */ + /** \name Working colorspace API + * \{ */ + + virtual void set_scene_linear_role(StringRefNull name) = 0; + + /** \} */ + /* -------------------------------------------------------------------- */ /** \name Display API * \{ */ diff --git a/source/blender/imbuf/opencolorio/OCIO_gpu_shader_binder.hh b/source/blender/imbuf/opencolorio/OCIO_gpu_shader_binder.hh index 80901864eef..94104e17fc2 100644 --- a/source/blender/imbuf/opencolorio/OCIO_gpu_shader_binder.hh +++ b/source/blender/imbuf/opencolorio/OCIO_gpu_shader_binder.hh @@ -97,6 +97,11 @@ class GPUShaderBinder { */ void unbind() const; + /** + * Clear caches when configuration changes. + */ + void clear_caches() const; + protected: const Config &config_; diff --git a/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.cc b/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.cc index 3be89b04ea9..3045bfc1623 100644 --- a/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.cc +++ b/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.cc @@ -115,6 +115,14 @@ const ColorSpace *FallbackConfig::get_color_space_by_interop_id(StringRefNull in /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Working space API + * \{ */ + +void FallbackConfig::set_scene_linear_role(StringRefNull /*name*/) {} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Display API * \{ */ diff --git a/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.hh b/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.hh index 66745c72ce8..cda29699068 100644 --- a/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.hh +++ b/source/blender/imbuf/opencolorio/intern/fallback/fallback_config.hh @@ -51,6 +51,9 @@ class FallbackConfig : public Config { const ColorSpace *get_sorted_color_space_by_index(int index) const override; const ColorSpace *get_color_space_by_interop_id(StringRefNull interop_id) const override; + /* Working space API. */ + void set_scene_linear_role(StringRefNull name) override; + /* Display API. */ const Display *get_default_display() const override; const Display *get_display_by_name(StringRefNull name) const override; diff --git a/source/blender/imbuf/opencolorio/intern/gpu_shader_binder.cc b/source/blender/imbuf/opencolorio/intern/gpu_shader_binder.cc index df248a07cb8..2e470defd4b 100644 --- a/source/blender/imbuf/opencolorio/intern/gpu_shader_binder.cc +++ b/source/blender/imbuf/opencolorio/intern/gpu_shader_binder.cc @@ -594,4 +594,10 @@ bool GPUShaderBinder::create_gpu_shader( return (display_shader.shader != nullptr); } +void GPUShaderBinder::clear_caches() const +{ + scene_linear_cache_->clear(); + display_cache_->clear(); +} + } // namespace blender::ocio diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.cc b/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.cc index d22b29da55d..37ddcc2c345 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.cc +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.cc @@ -230,6 +230,13 @@ void LibOCIOColorSpace::ensure_srgb_scene_linear_info() const is_info_cached_ = true; } +void LibOCIOColorSpace::clear_caches() +{ + from_scene_linear_cpu_processor_ = CPUProcessorCache(); + to_scene_linear_cpu_processor_ = CPUProcessorCache(); + is_info_cached_ = false; +} + } // namespace blender::ocio #endif diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.hh b/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.hh index fa4f600185a..fe5d56a90d2 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.hh +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_colorspace.hh @@ -70,6 +70,8 @@ class LibOCIOColorSpace : public ColorSpace { const CPUProcessor *get_to_scene_linear_cpu_processor() const override; const CPUProcessor *get_from_scene_linear_cpu_processor() const override; + void clear_caches(); + MEM_CXX_CLASS_ALLOC_FUNCS("LibOCIOColorSpace"); private: diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.cc b/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.cc index 3a633076b06..b4e423bc095 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.cc +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.cc @@ -366,6 +366,36 @@ const ColorSpace *LibOCIOConfig::get_color_space_by_interop_id(StringRefNull int /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Working space API + * \{ */ + +void LibOCIOConfig::set_scene_linear_role(StringRefNull name) +{ + if (ocio_config_->getRoleColorSpace(OCIO_NAMESPACE::ROLE_SCENE_LINEAR) == name) { + return; + } + + /* This is a bad const cast, but seems to work ok, and reloading the whole config is + * something we don't support yet. When we do this could be changed. */ + OCIO_NAMESPACE::Config *mutable_ocio_config = const_cast( + ocio_config_.get()); + mutable_ocio_config->setRole(OCIO_NAMESPACE::ROLE_SCENE_LINEAR, name.c_str()); + + for (LibOCIOColorSpace &color_space : color_spaces_) { + color_space.clear_caches(); + } + for (LibOCIOColorSpace &color_space : inactive_color_spaces_) { + color_space.clear_caches(); + } + for (LibOCIODisplay &display : displays_) { + display.clear_caches(); + } + gpu_shader_binder_.clear_caches(); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Display API * \{ */ diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.hh b/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.hh index 7488f4282d9..d5feb3d9e41 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.hh +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_config.hh @@ -61,6 +61,9 @@ class LibOCIOConfig : public Config { const ColorSpace *get_sorted_color_space_by_index(int index) const override; const ColorSpace *get_color_space_by_interop_id(StringRefNull interop_id) const override; + /* Working space API. */ + void set_scene_linear_role(StringRefNull name) override; + /* Display API. */ const Display *get_default_display() const override; const Display *get_display_by_name(StringRefNull name) const override; diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.cc b/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.cc index 10847806582..3c4e117023e 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.cc +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.cc @@ -230,6 +230,14 @@ const CPUProcessor *LibOCIODisplay::get_from_scene_linear_cpu_processor( [&] { return create_scene_linear_cpu_processor(use_display_emulation, false); }); } +void LibOCIODisplay::clear_caches() +{ + to_scene_linear_cpu_processor_ = CPUProcessorCache(); + to_scene_linear_emulation_cpu_processor_ = CPUProcessorCache(); + from_scene_linear_cpu_processor_ = CPUProcessorCache(); + from_scene_linear_emulation_cpu_processor_ = CPUProcessorCache(); +} + } // namespace blender::ocio #endif diff --git a/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.hh b/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.hh index d3a5a2e167f..1fb2cc57e79 100644 --- a/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.hh +++ b/source/blender/imbuf/opencolorio/intern/libocio/libocio_display.hh @@ -81,6 +81,8 @@ class LibOCIODisplay : public Display { return is_hdr_; } + void clear_caches(); + MEM_CXX_CLASS_ALLOC_FUNCS("LibOCIOConfig"); protected: