8#if defined(WITH_OPENCOLORIO)
27static OCIO_NAMESPACE::ConstColorSpaceRcPtr get_display_view_colorspace(
28 const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config,
const char *display,
const char *
view)
30 const char *display_colorspace = ocio_config->getDisplayViewColorSpaceName(display,
view);
31 if (display_colorspace ==
nullptr) {
37 if (
STREQ(display_colorspace,
"<USE_DISPLAY_NAME>")) {
38 return ocio_config->getColorSpace(display);
41 return ocio_config->getColorSpace(display_colorspace);
44LibOCIODisplay::LibOCIODisplay(
const int index,
const LibOCIOConfig &config) : config_(&config)
46 const OCIO_NAMESPACE::ConstConfigRcPtr &ocio_config = config.get_ocio_config();
50 name_ = ocio_config->getDisplay(index);
55 const int num_views = ocio_config->getNumViews(name_.c_str());
57 report_error(
"Invalid OpenColorIO configuration: negative number of views");
63 OCIO_NAMESPACE::ConstColorSpaceRcPtr ocio_fallback_display_colorspace;
64 for (
const int view_index :
IndexRange(num_views)) {
65 const char *view_name = ocio_config->getView(name_.c_str(), view_index);
66 ocio_fallback_display_colorspace = get_display_view_colorspace(
67 ocio_config, name_.c_str(), view_name);
68 if (ocio_fallback_display_colorspace &&
69 ocio_fallback_display_colorspace->getReferenceSpaceType() ==
70 OCIO_NAMESPACE::REFERENCE_SPACE_DISPLAY)
74 ocio_fallback_display_colorspace.reset();
77 bool support_emulation = config.get_color_space(OCIO_NAMESPACE::ROLE_INTERCHANGE_DISPLAY) !=
80 views_.reserve(num_views);
81 for (
const int view_index :
IndexRange(num_views)) {
82 const char *view_name = ocio_config->getView(name_.c_str(), view_index);
84 OCIO_NAMESPACE::ConstColorSpaceRcPtr ocio_display_colorspace = get_display_view_colorspace(
85 ocio_config, name_.c_str(), view_name);
86 if (!ocio_display_colorspace) {
87 ocio_display_colorspace = ocio_fallback_display_colorspace;
92 if (description_.is_empty() && ocio_display_colorspace &&
93 ocio_display_colorspace->getReferenceSpaceType() ==
94 OCIO_NAMESPACE::REFERENCE_SPACE_DISPLAY)
96 description_ = ocio_display_colorspace->getDescription();
99 const char *view_description =
nullptr;
100 const char *view_transform_name = ocio_config->getDisplayViewTransformName(name_.c_str(),
102 if (view_transform_name) {
103 const OCIO_NAMESPACE::ConstViewTransformRcPtr view_transform = ocio_config->getViewTransform(
104 view_transform_name);
105 if (view_transform) {
106 view_description = view_transform->getDescription();
109 if (view_description ==
nullptr) {
110 view_description =
"";
114 bool view_is_hdr =
false;
115 if (ocio_display_colorspace) {
116 StringRefNull encoding = ocio_display_colorspace->getEncoding();
117 view_is_hdr = encoding ==
"hdr-video" || encoding ==
"edr-video";
118 is_hdr_ |= view_is_hdr;
122 bool view_support_emulation = support_emulation && ocio_display_colorspace &&
123 ocio_display_colorspace->getReferenceSpaceType() ==
124 OCIO_NAMESPACE::REFERENCE_SPACE_DISPLAY;
128 Gamut gamut = Gamut::Unknown;
131 const LibOCIOColorSpace *display_colorspace =
132 (ocio_display_colorspace) ?
static_cast<const LibOCIOColorSpace *
>(config.get_color_space(
133 ocio_display_colorspace->getName())) :
135 StringRefNull display_interop_id = (display_colorspace) ? display_colorspace->interop_id() :
138 if (!display_interop_id.is_empty()) {
139 if (display_interop_id.endswith(
"_rec709_display") ||
140 display_interop_id.endswith(
"_rec709_scene"))
142 gamut = Gamut::Rec709;
144 else if (display_interop_id.endswith(
"_p3d65_display") ||
145 display_interop_id.endswith(
"_p3d65_scene"))
147 gamut = Gamut::P3D65;
149 else if (display_interop_id.endswith(
"_rec2020_display") ||
150 display_interop_id.endswith(
"_rec2020_scene"))
152 gamut = Gamut::Rec2020;
155 if (display_interop_id.startswith(
"srgb_")) {
156 transfer_function = TransferFunction::sRGB;
158 else if (display_interop_id.startswith(
"srgbe_")) {
159 transfer_function = TransferFunction::ExtendedsRGB;
161 else if (display_interop_id.startswith(
"pq_")) {
162 transfer_function = TransferFunction::PQ;
164 else if (display_interop_id.startswith(
"hlg_")) {
165 transfer_function = TransferFunction::HLG;
167 else if (display_interop_id.startswith(
"g18_")) {
168 transfer_function = TransferFunction::Gamma18;
170 else if (display_interop_id.startswith(
"g22_")) {
171 transfer_function = TransferFunction::Gamma22;
173 else if (display_interop_id.startswith(
"g24_")) {
174 transfer_function = TransferFunction::Gamma24;
176 else if (display_interop_id.startswith(
"g26_")) {
177 transfer_function = TransferFunction::Gamma26;
182 " Add view: %s (colorspace: %s, %s)",
184 display_colorspace ? display_colorspace->name().c_str() :
"<none>",
185 view_is_hdr ?
"HDR" :
"SDR");
187 views_.append_as(view_index,
191 view_support_emulation,
198 if (untonemapped_view_ ==
nullptr) {
200 for (
const LibOCIOView &
view : views_) {
201 if (
view.name() ==
"Un-tone-mapped" ||
view.name() ==
"Standard") {
202 untonemapped_view_ = &
view;
206 if (untonemapped_view_ ==
nullptr) {
209 const char *default_view_transform = ocio_config->getDefaultViewTransformName();
210 for (
const LibOCIOView &
view : views_) {
211 if (
view.name() == default_view_transform) {
212 untonemapped_view_ = &
view;
220 if (name_.endswith(
" - Display")) {
225const View *LibOCIODisplay::get_untonemapped_view()
const
227 return untonemapped_view_;
233 for (
const LibOCIOView &
view : views_) {
241int LibOCIODisplay::get_num_views()
const
243 return views_.size();
246const View *LibOCIODisplay::get_view_by_index(
const int index)
const
248 if (index < 0 || index >= views_.size()) {
251 return &views_[index];
254std::unique_ptr<LibOCIOCPUProcessor> LibOCIODisplay::create_scene_linear_cpu_processor(
255 const bool use_display_emulation,
const bool inverse)
const
257 const View *
view = get_untonemapped_view();
258 if (
view ==
nullptr) {
259 view = get_default_view();
262 DisplayParameters display_parameters;
263 display_parameters.from_colorspace = OCIO_NAMESPACE::ROLE_SCENE_LINEAR;
264 display_parameters.view =
view->name();
265 display_parameters.display = name_;
266 display_parameters.inverse =
inverse;
267 display_parameters.use_display_emulation = use_display_emulation;
268 OCIO_NAMESPACE::ConstProcessorRcPtr ocio_processor = create_ocio_display_processor(
269 *config_, display_parameters);
270 if (!ocio_processor) {
274 OCIO_NAMESPACE::ConstCPUProcessorRcPtr ocio_cpu_processor =
275 ocio_processor->getDefaultCPUProcessor();
276 if (!ocio_cpu_processor) {
280 return std::make_unique<LibOCIOCPUProcessor>(ocio_cpu_processor);
283const CPUProcessor *LibOCIODisplay::get_to_scene_linear_cpu_processor(
284 const bool use_display_emulation)
const
286 const CPUProcessorCache &cache = (use_display_emulation) ?
287 to_scene_linear_emulation_cpu_processor_ :
288 to_scene_linear_cpu_processor_;
289 return cache.get([&] {
return create_scene_linear_cpu_processor(use_display_emulation,
true); });
292const CPUProcessor *LibOCIODisplay::get_from_scene_linear_cpu_processor(
293 const bool use_display_emulation)
const
295 const CPUProcessorCache &cache = (use_display_emulation) ?
296 from_scene_linear_emulation_cpu_processor_ :
297 from_scene_linear_cpu_processor_;
299 [&] {
return create_scene_linear_cpu_processor(use_display_emulation,
false); });
302void LibOCIODisplay::clear_caches()
304 to_scene_linear_cpu_processor_ = CPUProcessorCache();
305 to_scene_linear_emulation_cpu_processor_ = CPUProcessorCache();
306 from_scene_linear_cpu_processor_ = CPUProcessorCache();
307 from_scene_linear_emulation_cpu_processor_ = CPUProcessorCache();
#define CLOG_TRACE(clg_ref,...)
static void View(GHOST_IWindow *window, bool stereo, int eye=0)
constexpr StringRef drop_known_suffix(StringRef suffix) const
MatBase< C, R > inverse(MatBase< C, R >) RET