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
This commit is contained in:
Brecht Van Lommel
2025-08-31 03:02:17 +02:00
parent 099ad9aee6
commit b4c3685313
11 changed files with 82 additions and 0 deletions

View File

@@ -135,6 +135,14 @@ class Config {
/** \} */
/* -------------------------------------------------------------------- */
/** \name Working colorspace API
* \{ */
virtual void set_scene_linear_role(StringRefNull name) = 0;
/** \} */
/* -------------------------------------------------------------------- */
/** \name Display API
* \{ */

View File

@@ -97,6 +97,11 @@ class GPUShaderBinder {
*/
void unbind() const;
/**
* Clear caches when configuration changes.
*/
void clear_caches() const;
protected:
const Config &config_;

View File

@@ -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
* \{ */

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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_NAMESPACE::Config *>(
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
* \{ */

View File

@@ -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;

View File

@@ -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

View File

@@ -81,6 +81,8 @@ class LibOCIODisplay : public Display {
return is_hdr_;
}
void clear_caches();
MEM_CXX_CLASS_ALLOC_FUNCS("LibOCIOConfig");
protected: