archrelease: copy trunk to extra-x86_64
[arch-packages.git] / krita / repos / extra-x86_64 / krita-opencolorio2.patch
blob260e8bb2e1973ff4a31e4ee12e0b9d70787bfcb7
1 diff --git a/CMakeLists.txt b/CMakeLists.txt
2 index e06a3bd0ab..e02b1ad196 100644
3 --- a/CMakeLists.txt
4 +++ b/CMakeLists.txt
5 @@ -705,13 +705,13 @@ if (FFTW3_FOUND)
6 list (APPEND ANDROID_EXTRA_LIBS ${FFTW3_LIBRARY})
7 endif()
9 -find_package(OCIO)
10 -set_package_properties(OCIO PROPERTIES
11 +find_package(OpenColorIO)
12 +set_package_properties(OpenColorIO PROPERTIES
13 DESCRIPTION "The OpenColorIO Library"
14 URL "https://www.opencolorio.org"
15 TYPE OPTIONAL
16 PURPOSE "Required by the Krita LUT docker")
17 -macro_bool_to_01(OCIO_FOUND HAVE_OCIO)
18 +macro_bool_to_01(OpenColorIO_FOUND HAVE_OCIO)
20 set_package_properties(PythonLibrary PROPERTIES
21 DESCRIPTION "Python Library"
22 diff --git a/krita/data/shaders/highq_downscale.frag b/krita/data/shaders/highq_downscale.frag
23 index bb2a47c2a3..73c95ebfa8 100644
24 --- a/krita/data/shaders/highq_downscale.frag
25 +++ b/krita/data/shaders/highq_downscale.frag
26 @@ -3,10 +3,6 @@
28 uniform sampler2D texture0;
30 -#ifdef USE_OCIO
31 -uniform sampler3D texture1;
32 -#endif
34 in vec4 v_textureCoordinate;
35 out vec4 fragColor;
37 @@ -119,7 +115,7 @@ void main() {
40 #ifdef USE_OCIO
41 - fragColor = OCIODisplay(col, texture1);
42 + fragColor = OCIODisplay(col);
43 #else /* USE_OCIO */
44 fragColor = col;
45 #endif /* USE_OCIO */
46 diff --git a/libs/ui/canvas/kis_display_filter.h b/libs/ui/canvas/kis_display_filter.h
47 index a2ae5ab584..e96506d892 100644
48 --- a/libs/ui/canvas/kis_display_filter.h
49 +++ b/libs/ui/canvas/kis_display_filter.h
50 @@ -26,6 +26,9 @@
52 struct KisExposureGammaCorrectionInterface;
54 +class QOpenGLFunctions;
55 +class QOpenGLShaderProgram;
57 /**
58 * @brief The KisDisplayFilter class is the base class for filters that
59 * are applied by the canvas to the projection before displaying.
60 @@ -37,7 +40,7 @@ public:
61 explicit KisDisplayFilter(QObject *parent = 0);
63 virtual QString program() const = 0;
64 - virtual GLuint lutTexture() const = 0;
65 + virtual void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const = 0;
66 virtual void filter(quint8 *pixels, quint32 numPixels) = 0;
67 virtual void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) = 0;
68 virtual void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) = 0;
69 diff --git a/libs/ui/opengl/kis_opengl_canvas2.cpp b/libs/ui/opengl/kis_opengl_canvas2.cpp
70 index 69bd84000f..50acab76bf 100644
71 --- a/libs/ui/opengl/kis_opengl_canvas2.cpp
72 +++ b/libs/ui/opengl/kis_opengl_canvas2.cpp
73 @@ -947,9 +947,7 @@ void KisOpenGLCanvas2::drawImage(const QRect &updateRect)
76 if (d->displayFilter) {
77 - glActiveTexture(GL_TEXTURE0 + 1);
78 - glBindTexture(GL_TEXTURE_3D, d->displayFilter->lutTexture());
79 - d->displayShader->setUniformValue(d->displayShader->location(Uniform::Texture1), 1);
80 + d->displayFilter->setupTextures(this, d->displayShader);
83 glActiveTexture(GL_TEXTURE0);
84 diff --git a/libs/ui/opengl/kis_opengl_shader_loader.cpp b/libs/ui/opengl/kis_opengl_shader_loader.cpp
85 index 8513617815..75a4f08ba3 100644
86 --- a/libs/ui/opengl/kis_opengl_shader_loader.cpp
87 +++ b/libs/ui/opengl/kis_opengl_shader_loader.cpp
88 @@ -150,6 +150,7 @@ KisShaderProgram *KisOpenGLShaderLoader::loadDisplayShader(QSharedPointer<KisDis
89 bool haveDisplayFilter = displayFilter && !displayFilter->program().isEmpty();
90 if (haveDisplayFilter) {
91 fragHeader.append("#define USE_OCIO\n");
92 + fragHeader.append("#define USE_OCIO_V2\n");
93 fragHeader.append(displayFilter->program().toLatin1());
96 diff --git a/plugins/dockers/lut/CMakeLists.txt b/plugins/dockers/lut/CMakeLists.txt
97 index 01844be146..795c99162d 100644
98 --- a/plugins/dockers/lut/CMakeLists.txt
99 +++ b/plugins/dockers/lut/CMakeLists.txt
100 @@ -17,5 +17,5 @@ ki18n_wrap_ui(KRITA_LUTDOCKER_SOURCES
102 add_library(kritalutdocker MODULE ${KRITA_LUTDOCKER_SOURCES})
104 -target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} ${OCIO_LIBRARIES})
105 +target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} OpenColorIO::OpenColorIO)
106 install(TARGETS kritalutdocker DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
107 diff --git a/plugins/dockers/lut/lutdocker_dock.cpp b/plugins/dockers/lut/lutdocker_dock.cpp
108 index c7e68dce06..3c57144c9d 100644
109 --- a/plugins/dockers/lut/lutdocker_dock.cpp
110 +++ b/plugins/dockers/lut/lutdocker_dock.cpp
111 @@ -56,12 +56,12 @@
112 #include <KisSqueezedComboBox.h>
113 #include "kis_signals_blocker.h"
114 #include "krita_utils.h"
115 +#include <KisOcioConfiguration.h>
117 -#include "ocio_display_filter.h"
118 -#include "black_white_point_chooser.h"
119 -#include "KisOcioConfiguration.h"
120 #include <opengl/KisOpenGLModeProber.h>
122 +#include "black_white_point_chooser.h"
125 OCIO::ConstConfigRcPtr defaultRawProfile()
127 @@ -231,6 +231,8 @@ void LutDockerDock::slotUpdateIcons()
129 m_btnConvertCurrentColor->setIcon(KisIconUtils::loadIcon("krita_tool_freehand"));
130 m_btmShowBWConfiguration->setIcon(KisIconUtils::loadIcon("properties"));
131 + m_lblOcioVersion->setText(OCIO_VERSION_FULL_STR);
132 + m_lblOcioVersion->setEnabled(false);
135 void LutDockerDock::slotShowBWConfiguration()
136 diff --git a/plugins/dockers/lut/ocio_display_filter.cpp b/plugins/dockers/lut/ocio_display_filter.cpp
137 index 33afb01f1e..e429e3c2f4 100644
138 --- a/plugins/dockers/lut/ocio_display_filter.cpp
139 +++ b/plugins/dockers/lut/ocio_display_filter.cpp
140 @@ -1,38 +1,29 @@
142 - * Copyright (c) 2012 Boudewijn Rempt <boud@valdyas.org>
143 + * SPDX-FileCopyrightText: 2012 Boudewijn Rempt <boud@valdyas.org>
144 + * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
146 - * This program is free software; you can redistribute it and/or modify
147 - * it under the terms of the GNU General Public License as published by
148 - * the Free Software Foundation; either version 2 of the License, or
149 - * (at your option) any later version.
151 - * This program is distributed in the hope that it will be useful,
152 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
153 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
154 - * GNU General Public License for more details.
156 - * You should have received a copy of the GNU General Public License
157 - * along with this program; if not, write to the Free Software
158 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
159 + * SPDX-License-Identifier: GPL-2.0-or-later
162 #include "ocio_display_filter.h"
163 -#include <math.h>
164 -#include <cstdlib>
166 +#include <QOpenGLContext>
167 +#include <QOpenGLExtraFunctions>
168 +#include <QOpenGLFunctions_2_0>
169 +#include <QOpenGLFunctions_3_0>
170 +#include <QOpenGLFunctions_3_2_Core>
172 #include <cmath>
173 -#include <cstdio>
174 #include <cstring>
175 -#include <iostream>
176 -#include <fstream>
177 -#include <sstream>
179 #include <kis_config.h>
181 +#include <kis_debug.h>
182 #include <opengl/kis_opengl.h>
183 -#include <QOpenGLContext>
184 -#include <QOpenGLFunctions_3_2_Core>
185 -#include <QOpenGLFunctions_3_0>
186 -#include <QOpenGLFunctions_2_0>
187 -#include <QOpenGLExtraFunctions>
189 +#if defined(QT_OPENGL_ES_2)
190 +#define GL_RGBA32F_ARB GL_RGBA32F_EXT
191 +#define GL_RGB32F_ARB GL_RGB32F_EXT
192 +#endif
194 OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent)
195 : KisDisplayFilter(parent)
196 @@ -42,7 +33,8 @@ OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interf
197 , look(0)
198 , swizzle(RGBA)
199 , m_interface(interface)
200 - , m_lut3dTexID(0)
201 + , m_lut3dTexIDs()
202 + , m_lut3dUniforms()
203 , m_shaderDirty(true)
206 @@ -51,7 +43,7 @@ OcioDisplayFilter::~OcioDisplayFilter()
210 -KisExposureGammaCorrectionInterface* OcioDisplayFilter::correctionInterface() const
211 +KisExposureGammaCorrectionInterface *OcioDisplayFilter::correctionInterface() const
213 return m_interface;
215 @@ -60,8 +52,8 @@ void OcioDisplayFilter::filter(quint8 *pixels, quint32 numPixels)
217 // processes that data _in_ place
218 if (m_processor) {
219 - OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
220 - m_processor->apply(img);
221 + OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
222 + m_processor->getDefaultCPUProcessor()->apply(img);
226 @@ -69,8 +61,8 @@ void OcioDisplayFilter::approximateInverseTransformation(quint8 *pixels, quint32
228 // processes that data _in_ place
229 if (m_revereseApproximationProcessor) {
230 - OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
231 - m_revereseApproximationProcessor->apply(img);
232 + OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
233 + m_revereseApproximationProcessor->getDefaultCPUProcessor()->apply(img);
237 @@ -78,8 +70,8 @@ void OcioDisplayFilter::approximateForwardTransformation(quint8 *pixels, quint32
239 // processes that data _in_ place
240 if (m_forwardApproximationProcessor) {
241 - OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
242 - m_forwardApproximationProcessor->apply(img);
243 + OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
244 + m_forwardApproximationProcessor->getDefaultCPUProcessor()->apply(img);
248 @@ -103,11 +95,6 @@ QString OcioDisplayFilter::program() const
249 return m_program;
252 -GLuint OcioDisplayFilter::lutTexture() const
254 - return m_lut3dTexID;
257 void OcioDisplayFilter::updateProcessor()
259 if (!config) {
260 @@ -126,18 +113,22 @@ void OcioDisplayFilter::updateProcessor()
261 inputColorSpaceName = config->getColorSpaceNameByIndex(0);
263 if (!look) {
264 - look = config->getLookNameByIndex(0);
265 + look = config->getLookNameByIndex(0);
268 if (!displayDevice || !view || !inputColorSpaceName) {
269 return;
272 - OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
273 - transform->setInputColorSpaceName(inputColorSpaceName);
274 + OCIO::DisplayViewTransformRcPtr transform = OCIO::DisplayViewTransform::Create();
275 + transform->setSrc(inputColorSpaceName);
276 transform->setDisplay(displayDevice);
277 transform->setView(view);
279 + OCIO::LegacyViewingPipelineRcPtr vpt = OCIO::LegacyViewingPipeline::Create();
281 + vpt->setDisplayViewTransform(transform);
284 * Look support:
285 * As the OCIO docs will tell you, looks are a aesthetic transform that is
286 @@ -155,36 +146,37 @@ void OcioDisplayFilter::updateProcessor()
287 * override is all we can offer.
289 if (config->getLook(look)) {
290 - transform->setLooksOverride(look);
291 - transform->setLooksOverrideEnabled(true);
292 + vpt->setLooksOverride(look);
293 + vpt->setLooksOverrideEnabled(true);
296 OCIO::GroupTransformRcPtr approximateTransform = OCIO::GroupTransform::Create();
298 // fstop exposure control -- not sure how that translates to our exposure
300 - float exposureGain = powf(2.0f, exposure);
301 + const double exposureGain = pow(2.0, exposure);
303 - const qreal minRange = 0.001;
304 + const double minRange = 0.001;
305 if (qAbs(blackPoint - whitePoint) < minRange) {
306 whitePoint = blackPoint + minRange;
309 - const float oldMin[] = { blackPoint, blackPoint, blackPoint, 0.0f };
310 - const float oldMax[] = { whitePoint, whitePoint, whitePoint, 1.0f };
311 + const double oldMin[] = {blackPoint, blackPoint, blackPoint, 0.0};
312 + const double oldMax[] = {whitePoint, whitePoint, whitePoint, 1.0};
314 - const float newMin[] = { 0.0f, 0.0f, 0.0f, 0.0f };
315 - const float newMax[] = { exposureGain, exposureGain, exposureGain, 1.0f };
316 + const double newMin[] = {0.0, 0.0, 0.0, 0.0};
317 + const double newMax[] = {exposureGain, exposureGain, exposureGain, 1.0};
319 - float m44[16];
320 - float offset4[4];
321 + double m44[16];
322 + double offset4[4];
323 OCIO::MatrixTransform::Fit(m44, offset4, oldMin, oldMax, newMin, newMax);
324 - OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create();
325 - mtx->setValue(m44, offset4);
326 - transform->setLinearCC(mtx);
327 + OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create();
328 + mtx->setMatrix(m44);
329 + mtx->setOffset(offset4);
330 + vpt->setLinearCC(mtx);
332 // approximation (no color correction);
333 - approximateTransform->push_back(mtx);
334 + approximateTransform->appendTransform(mtx);
337 // channel swizzle
338 @@ -226,32 +218,39 @@ void OcioDisplayFilter::updateProcessor()
339 channelHot[1] = 0;
340 channelHot[2] = 0;
341 channelHot[3] = 1;
342 - default:
344 + default:;
346 - float lumacoef[3];
347 + double lumacoef[3];
348 config->getDefaultLumaCoefs(lumacoef);
349 - float m44[16];
350 - float offset[4];
351 + double m44[16];
352 + double offset[4];
353 OCIO::MatrixTransform::View(m44, offset, channelHot, lumacoef);
354 OCIO::MatrixTransformRcPtr swizzleTransform = OCIO::MatrixTransform::Create();
355 - swizzleTransform->setValue(m44, offset);
356 - transform->setChannelView(swizzleTransform);
357 + swizzleTransform->setMatrix(m44);
358 + swizzleTransform->setOffset(offset);
359 + vpt->setChannelView(swizzleTransform);
362 // Post-display transform gamma
364 - float exponent = 1.0f/std::max(1e-6f, static_cast<float>(gamma));
365 - const float exponent4f[] = { exponent, exponent, exponent, exponent };
366 - OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create();
367 + double exponent = 1.0 / std::max(1e-6, gamma);
368 + const double exponent4f[] = {exponent, exponent, exponent, exponent};
369 + OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create();
370 expTransform->setValue(exponent4f);
371 - transform->setDisplayCC(expTransform);
372 + vpt->setDisplayCC(expTransform);
374 // approximation (no color correction);
375 - approximateTransform->push_back(expTransform);
376 + approximateTransform->appendTransform(expTransform);
379 - m_processor = config->getProcessor(transform);
380 + try {
381 + m_processor = vpt->getProcessor(config, config->getCurrentContext());
382 + } catch (OCIO::Exception &e) {
383 + // XXX: How to not break the OCIO shader now?
384 + errKrita << "OCIO exception while parsing the current context:" << e.what();
385 + m_shaderDirty = false;
386 + return;
389 m_forwardApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_FORWARD);
391 @@ -259,7 +258,7 @@ void OcioDisplayFilter::updateProcessor()
392 m_revereseApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_INVERSE);
393 } catch (...) {
394 warnKrita << "OCIO inverted matrix does not exist!";
395 - //m_revereseApproximationProcessor;
396 + // m_revereseApproximationProcessor;
399 m_shaderDirty = true;
400 @@ -272,16 +271,19 @@ bool OcioDisplayFilter::updateShader()
401 if (f) {
402 return updateShaderImpl(f);
404 +#if defined(QT_OPENGL_3)
405 } else if (KisOpenGL::hasOpenGL3()) {
406 QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
407 if (f) {
408 return updateShaderImpl(f);
410 +#endif
413 // XXX This option can be removed once we move to Qt 5.7+
414 if (KisOpenGL::supportsLoD()) {
415 -#ifdef Q_OS_MAC
416 +#if defined(QT_OPENGL_3)
417 +#if defined(Q_OS_MAC) && defined(QT_OPENGL_3_2)
418 QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
419 #else
420 QOpenGLFunctions_3_0 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_0>();
421 @@ -289,23 +291,29 @@ bool OcioDisplayFilter::updateShader()
422 if (f) {
423 return updateShaderImpl(f);
425 +#endif
427 - QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
428 +#if !defined(QT_OPENGL_ES_2)
429 + QOpenGLFunctions_2_0 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_0>();
430 if (f) {
431 return updateShaderImpl(f);
433 +#endif
435 return false;
438 -template <class F>
439 -bool OcioDisplayFilter::updateShaderImpl(F *f) {
440 +template<class F>
441 +bool OcioDisplayFilter::updateShaderImpl(F *f)
443 // check whether we are allowed to use shaders -- though that should
444 // work for everyone these days
445 KisConfig cfg(true);
446 - if (!cfg.useOpenGL()) return false;
447 + if (!cfg.useOpenGL())
448 + return false;
450 - if (!m_shaderDirty) return false;
451 + if (!m_shaderDirty)
452 + return false;
454 if (!f) {
455 qWarning() << "Failed to get valid OpenGL functions for OcioDisplayFilter!";
456 @@ -316,71 +324,272 @@ bool OcioDisplayFilter::updateShaderImpl(F *f) {
458 bool shouldRecompileShader = false;
460 - const int lut3DEdgeSize = cfg.ocioLutEdgeSize();
461 + // Step 1: Create a GPU Shader Description
462 + OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
464 - if (m_lut3d.size() == 0) {
465 - //dbgKrita << "generating lut";
466 - f->glGenTextures(1, &m_lut3dTexID);
467 +#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
468 + if (KisOpenGL::supportsLoD()) {
469 + shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_3_0);
470 + } else {
471 + shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_1_0);
473 +#else
474 + if (KisOpenGL::supportsLoD()) {
475 + shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
476 + } else {
477 + shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2);
479 +#endif
481 - int num3Dentries = 3 * lut3DEdgeSize * lut3DEdgeSize * lut3DEdgeSize;
482 - m_lut3d.fill(0.0, num3Dentries);
483 + shaderDesc->setFunctionName("OCIODisplay");
484 + shaderDesc->setResourcePrefix("ocio_");
486 - f->glActiveTexture(GL_TEXTURE1);
487 - f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID);
488 + // Step 2: Compute the 3D LUT
489 +#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
490 + // ensure the new GPU pipeline is used with our GLES3 patch
491 + // this way users won't run into errors when using Angle along with OCIO
492 + const auto gpu = m_processor->getOptimizedGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT);
493 +#else
494 + const int lut3DEdgeSize = cfg.ocioLutEdgeSize();
495 + const auto gpu =
496 + m_processor->getOptimizedLegacyGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT, lut3DEdgeSize);
497 +#endif
499 - f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
500 - f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
501 - f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
502 - f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
503 - f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
504 - f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
505 - lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize,
506 - 0, GL_RGB, GL_FLOAT, &m_lut3d.constData()[0]);
507 + gpu->extractGpuShaderInfo(shaderDesc);
509 + // OCIO v2 assumes you'll use the OglApp helpers
510 + // these are unusable from a Qt backend, because they rely on GLUT/GLFW
511 + // ociodisplay original pipeline:
512 + // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/508b3f4a0618435aeed2f45058208bdfa99e0887/src/apps/ociodisplay/main.cpp
513 + // ociodisplay new pipeline is a single call:
514 + // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/ffddc3341f5775c7866fe2c93275e1d5e0b0540f/src/apps/ociodisplay/main.cpp#L427
515 + // we need to replicate this loop:
516 + // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/oglapp.cpp#L191-L223
517 + // calls functions from here:
518 + // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/glsl.cpp
520 + for (const auto &tex : m_lut3dTexIDs) {
521 + f->glDeleteTextures(1, &tex.m_uid);
524 - // Step 1: Create a GPU Shader Description
525 - OCIO::GpuShaderDesc shaderDesc;
526 + m_lut3dTexIDs.clear();
528 - if (KisOpenGL::supportsLoD()) {
529 - shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
531 - else {
532 - shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
533 + // This is the first available index for the textures.
534 + unsigned currIndex = 1;
536 + // Process the 3D LUT first.
538 + const unsigned maxTexture3D = shaderDesc->getNum3DTextures();
539 + for (unsigned idx = 0; idx < maxTexture3D; ++idx) {
540 + // 1. Get the information of the 3D LUT.
542 + const char *textureName = nullptr;
543 + const char *samplerName = nullptr;
544 + unsigned edgelen = 0;
545 + OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
546 + shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, interpolation);
548 + if (!textureName || !*textureName || !samplerName || !*samplerName || edgelen == 0) {
549 + errOpenGL << "The texture data is corrupted";
550 + return false;
553 + const float *values = nullptr;
554 + shaderDesc->get3DTextureValues(idx, values);
555 + if (!values) {
556 + errOpenGL << "The texture values are missing";
557 + return false;
560 + // 2. Allocate the 3D LUT.
562 + unsigned texId = 0;
564 + if (values == nullptr) {
565 + errOpenGL << "3D LUT" << idx << "Missing texture data";
566 + return false;
569 + f->glGenTextures(1, &texId);
571 + f->glActiveTexture(GL_TEXTURE0 + currIndex);
573 + f->glBindTexture(GL_TEXTURE_3D, texId);
576 + if (interpolation == OCIO::INTERP_NEAREST) {
577 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
578 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
579 + } else {
580 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
581 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
584 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
585 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
586 + f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
589 + f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F_ARB, edgelen, edgelen, edgelen, 0, GL_RGB, GL_FLOAT, values);
592 + // 3. Keep the texture id & name for the later enabling.
594 + m_lut3dTexIDs.push_back({texId, textureName, samplerName, GL_TEXTURE_3D});
596 + currIndex++;
599 + // Process the 1D LUTs.
601 - shaderDesc.setFunctionName("OCIODisplay");
602 - shaderDesc.setLut3DEdgeLen(lut3DEdgeSize);
603 + const unsigned maxTexture2D = shaderDesc->getNumTextures();
604 + for (unsigned idx = 0; idx < maxTexture2D; ++idx) {
605 + // 1. Get the information of the 1D LUT.
607 + const char *textureName = nullptr;
608 + const char *samplerName = nullptr;
609 + unsigned width = 0;
610 + unsigned height = 0;
611 + OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
612 + OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
613 + shaderDesc->getTexture(idx, textureName, samplerName, width, height, channel, interpolation);
615 - // Step 2: Compute the 3D LUT
616 - QString lut3dCacheID = QString::fromLatin1(m_processor->getGpuLut3DCacheID(shaderDesc));
617 - if (lut3dCacheID != m_lut3dcacheid) {
618 - //dbgKrita << "Computing 3DLut " << m_lut3dcacheid;
619 - m_lut3dcacheid = lut3dCacheID;
620 - m_processor->getGpuLut3D(&m_lut3d[0], shaderDesc);
622 - f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID);
623 - f->glTexSubImage3D(GL_TEXTURE_3D, 0,
624 - 0, 0, 0,
625 - lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize,
626 - GL_RGB, GL_FLOAT, &m_lut3d[0]);
627 + if (!textureName || !*textureName || !samplerName || !*samplerName || width == 0) {
628 + errOpenGL << "The texture data is corrupted";
629 + return false;
632 + const float *values = nullptr;
633 + shaderDesc->getTextureValues(idx, values);
634 + if (!values) {
635 + errOpenGL << "The texture values are missing";
636 + return false;
639 + // 2. Allocate the 1D LUT (a 2D texture is needed to hold large LUTs).
641 + unsigned texId = 0;
643 + if (values == nullptr) {
644 + errOpenGL << "1D LUT" << idx << "Missing texture data.";
645 + return false;
648 + unsigned internalformat = GL_RGB32F_ARB;
649 + unsigned format = GL_RGB;
651 + if (channel == OCIO::GpuShaderCreator::TEXTURE_RED_CHANNEL) {
652 + internalformat = GL_R32F;
653 + format = GL_RED;
656 + f->glGenTextures(1, &texId);
658 + f->glActiveTexture(GL_TEXTURE0 + currIndex);
660 +#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
661 +#else
662 + // 1D Textures are unsupported by OpenGL ES.
663 + // https://github.com/AcademySoftwareFoundation/OpenColorIO/issues/1486
664 + if (height > 1) {
665 +#endif
666 + f->glBindTexture(GL_TEXTURE_2D, texId);
669 + if (interpolation == OCIO::INTERP_NEAREST) {
670 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
671 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
672 + } else {
673 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
674 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
677 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
678 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
679 + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
682 + f->glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, GL_FLOAT, values);
683 +#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
684 +#else
685 + } else {
686 + errOpenGL << "1D texture detected @" << idx << ", not supported by OpenGLES";
687 + return false;
689 +#endif
692 + // 3. Keep the texture id & name for the later enabling.
694 + unsigned type = GL_TEXTURE_2D;
695 + m_lut3dTexIDs.push_back({texId, textureName, samplerName, type});
696 + currIndex++;
699 // Step 3: Generate the shader text
700 - QString shaderCacheID = QString::fromLatin1(m_processor->getGpuShaderTextCacheID(shaderDesc));
701 + QString shaderCacheID = QString::fromLatin1(shaderDesc->getCacheID());
702 if (m_program.isEmpty() || shaderCacheID != m_shadercacheid) {
703 - //dbgKrita << "Computing Shader " << m_shadercacheid;
704 + // dbgKrita << "Computing Shader " << m_shadercacheid;
706 m_shadercacheid = shaderCacheID;
708 - std::ostringstream os;
709 - os << m_processor->getGpuShaderText(shaderDesc) << "\n";
711 - m_program = QString::fromLatin1(os.str().c_str());
712 + m_program = QString::fromLatin1("%1\n").arg(shaderDesc->getShaderText());
713 shouldRecompileShader = true;
716 + // Step 4: mirror and bind uniforms
717 + m_lut3dUniforms.clear();
719 + const unsigned maxUniforms = shaderDesc->getNumUniforms();
720 + for (unsigned idx = 0; idx < maxUniforms; ++idx) {
721 + OCIO::GpuShaderDesc::UniformData data;
722 + const char *name = shaderDesc->getUniform(idx, data);
723 + if (data.m_type == OCIO::UNIFORM_UNKNOWN) {
724 + errOpenGL << "Uniform" << idx << "has an unknown type";
725 + return false;
727 + // Transfer uniform.
728 + m_lut3dUniforms.push_back({name, data});
731 m_shaderDirty = false;
732 return shouldRecompileShader;
735 +void OcioDisplayFilter::setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const
737 + for (unsigned int idx = 0; idx < m_lut3dTexIDs.size(); ++idx) {
738 + const auto &data = m_lut3dTexIDs[idx];
739 + f->glActiveTexture(GL_TEXTURE0 + 1 + idx);
740 + f->glBindTexture(data.m_type, data.m_uid);
741 + program->setUniformValue(program->uniformLocation(data.m_samplerName), GLint(1 + idx));
744 + for (const KisTextureUniform &uniform : m_lut3dUniforms) {
745 + const int m_handle = program->uniformLocation(uniform.m_name);
747 + const OCIO::GpuShaderDesc::UniformData &m_data = uniform.m_data;
749 + // Update value.
750 + if (m_data.m_getDouble) {
751 + program->setUniformValue(m_handle, static_cast<const GLfloat>(m_data.m_getDouble()));
752 + } else if (m_data.m_getBool) {
753 + program->setUniformValue(m_handle, static_cast<const GLfloat>(m_data.m_getBool() ? 1.0f : 0.0f));
754 + } else if (m_data.m_getFloat3) {
755 + program->setUniformValue(m_handle,
756 + m_data.m_getFloat3()[0],
757 + m_data.m_getFloat3()[1],
758 + m_data.m_getFloat3()[2]);
759 + } else if (m_data.m_vectorFloat.m_getSize && m_data.m_vectorFloat.m_getVector) {
760 + program->setUniformValueArray(m_handle,
761 + m_data.m_vectorFloat.m_getVector(),
762 + m_data.m_vectorFloat.m_getSize(),
763 + 1);
764 + } else if (m_data.m_vectorInt.m_getSize && m_data.m_vectorInt.m_getVector) {
765 + program->setUniformValueArray(m_handle, m_data.m_vectorInt.m_getVector(), m_data.m_vectorInt.m_getSize());
766 + } else {
767 + errOpenGL << "Uniform" << uniform.m_name << "is not linked to any value";
768 + continue;
772 diff --git a/plugins/dockers/lut/ocio_display_filter.h b/plugins/dockers/lut/ocio_display_filter.h
773 index 48d896a4c0..963fcf5f93 100644
774 --- a/plugins/dockers/lut/ocio_display_filter.h
775 +++ b/plugins/dockers/lut/ocio_display_filter.h
776 @@ -1,38 +1,56 @@
778 - * Copyright (c) 2012 Boudewijn Rempt <boud@valdyas.org>
779 + * SPDX-FileCopyrightText: 2012 Boudewijn Rempt <boud@valdyas.org>
780 + * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
782 - * This program is free software; you can redistribute it and/or modify
783 - * it under the terms of the GNU General Public License as published by
784 - * the Free Software Foundation; either version 2 of the License, or
785 - * (at your option) any later version.
787 - * This program is distributed in the hope that it will be useful,
788 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
789 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
790 - * GNU General Public License for more details.
792 - * You should have received a copy of the GNU General Public License
793 - * along with this program; if not, write to the Free Software
794 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
795 + * SPDX-License-Identifier: GPL-2.0-or-later
798 #ifndef OCIO_DISPLAY_FILTER_H
799 #define OCIO_DISPLAY_FILTER_H
801 +#include <vector>
803 +#include <QOpenGLShaderProgram>
805 +#include <OpenColorIO.h>
806 +#include <OpenColorTransforms.h>
807 +#include <OpenColorTypes.h>
809 #include <kis_display_filter.h>
810 -#include <OpenColorIO/OpenColorIO.h>
811 -#include <OpenColorIO/OpenColorTransforms.h>
812 -#include <QVector>
813 -#include "kis_exposure_gamma_correction_interface.h"
814 +#include <kis_exposure_gamma_correction_interface.h>
816 namespace OCIO = OCIO_NAMESPACE;
818 -enum OCIO_CHANNEL_SWIZZLE {
819 - LUMINANCE,
820 - RGBA,
821 - R,
822 - G,
823 - B,
825 +enum OCIO_CHANNEL_SWIZZLE { LUMINANCE, RGBA, R, G, B, A };
827 +struct KisTextureUniform {
828 +public:
829 + KisTextureUniform(const QString &name, const OCIO::GpuShaderDesc::UniformData &data)
830 + : m_name(name)
831 + , m_data(data)
835 + QString m_name;
836 + OCIO::GpuShaderDesc::UniformData m_data;
838 +private:
839 + KisTextureUniform() = delete;
842 +struct KisTextureEntry {
843 + unsigned m_uid = -1;
844 + QString m_textureName;
845 + QString m_samplerName;
846 + unsigned m_type = -1;
848 + KisTextureEntry(unsigned uid, const QString &textureName, const QString &samplerName, unsigned type)
849 + : m_uid(uid)
850 + , m_textureName(textureName)
851 + , m_samplerName(samplerName)
852 + , m_type(type)
857 class OcioDisplayFilter : public KisDisplayFilter
858 @@ -42,21 +60,23 @@ public:
859 explicit OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent = 0);
860 ~OcioDisplayFilter();
862 - void filter(quint8 *pixels, quint32 numPixels);
863 - void approximateInverseTransformation(quint8 *pixels, quint32 numPixels);
864 - void approximateForwardTransformation(quint8 *pixels, quint32 numPixels);
865 - bool useInternalColorManagement() const;
866 - bool lockCurrentColorVisualRepresentation() const;
867 + void filter(quint8 *pixels, quint32 numPixels) override;
868 + void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) override;
869 + void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) override;
870 + bool useInternalColorManagement() const override;
871 + bool lockCurrentColorVisualRepresentation() const override;
872 void setLockCurrentColorVisualRepresentation(bool value);
874 - bool updateShader();
875 - template <class F>
876 + bool updateShader() override;
878 + template<class F>
879 bool updateShaderImpl(F *f);
881 - KisExposureGammaCorrectionInterface *correctionInterface() const;
882 + void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const override;
884 - virtual QString program() const;
885 - GLuint lutTexture() const;
886 + KisExposureGammaCorrectionInterface *correctionInterface() const override;
888 + QString program() const override;
890 void updateProcessor();
892 @@ -67,14 +87,13 @@ public:
893 const char *view;
894 const char *look;
895 OCIO_CHANNEL_SWIZZLE swizzle;
896 - float exposure;
897 - float gamma;
898 - float blackPoint;
899 - float whitePoint;
900 + double exposure;
901 + double gamma;
902 + double blackPoint;
903 + double whitePoint;
904 bool forceInternalColorManagement;
906 private:
908 OCIO::ConstProcessorRcPtr m_processor;
909 OCIO::ConstProcessorRcPtr m_revereseApproximationProcessor;
910 OCIO::ConstProcessorRcPtr m_forwardApproximationProcessor;
911 @@ -84,10 +103,10 @@ private:
912 bool m_lockCurrentColorVisualRepresentation;
914 QString m_program;
915 - GLuint m_lut3dTexID;
916 - QVector<float> m_lut3d;
917 + std::vector<KisTextureEntry> m_lut3dTexIDs;
918 QString m_lut3dcacheid;
919 QString m_shadercacheid;
920 + std::vector<KisTextureUniform> m_lut3dUniforms;
922 bool m_shaderDirty;
924 diff --git a/plugins/dockers/lut/tests/CMakeLists.txt b/plugins/dockers/lut/tests/CMakeLists.txt
925 index 85cd5ecbc6..8891b8b683 100644
926 --- a/plugins/dockers/lut/tests/CMakeLists.txt
927 +++ b/plugins/dockers/lut/tests/CMakeLists.txt
928 @@ -11,5 +11,5 @@ krita_add_broken_unit_test(kis_ocio_display_filter_test.cpp
929 ../ocio_display_filter.cpp
930 ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp
931 TEST_NAME KisOcioDisplayFilterTest
932 - LINK_LIBRARIES kritaui ${OCIO_LIBRARIES} KF5::I18n Qt5::Test
933 + LINK_LIBRARIES kritaui OpenColorIO::OpenColorIO KF5::I18n Qt5::Test
934 NAME_PREFIX "plugins-dockers-lut-")
935 diff --git a/plugins/dockers/lut/wdglut.ui b/plugins/dockers/lut/wdglut.ui
936 index 2ba3c2b073..403e5c26a3 100644
937 --- a/plugins/dockers/lut/wdglut.ui
938 +++ b/plugins/dockers/lut/wdglut.ui
939 @@ -7,7 +7,7 @@
940 <x>0</x>
941 <y>0</y>
942 <width>357</width>
943 - <height>286</height>
944 + <height>328</height>
945 </rect>
946 </property>
947 <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
948 @@ -338,7 +338,7 @@
949 </layout>
950 </item>
951 <item>
952 - <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
953 + <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0">
954 <property name="spacing">
955 <number>2</number>
956 </property>
957 @@ -348,6 +348,13 @@
958 <property name="rightMargin">
959 <number>2</number>
960 </property>
961 + <item>
962 + <widget class="QLabel" name="m_lblOcioVersion">
963 + <property name="text">
964 + <string>TextLabel</string>
965 + </property>
966 + </widget>
967 + </item>
968 <item>
969 <spacer name="horizontalSpacer">
970 <property name="orientation">
971 diff --git a/cmake/modules/FindOpenColorIO.cmake b/cmake/modules/FindOpenColorIO.cmake
972 new file mode 100644
973 index 0000000000..2a9e9310b1
974 --- /dev/null
975 +++ b/cmake/modules/FindOpenColorIO.cmake
976 @@ -0,0 +1,104 @@
977 +# Module to find OpenColorIO
979 +# This module will first look into the directories hinted by the variables:
980 +# - OpenColorIO_ROOT
982 +# This module defines the following variables:
984 +# OPENCOLORIO_FOUND - True if OpenColorIO was found.
985 +# OPENCOLORIO_INCLUDES - where to find OpenColorIO.h
986 +# OPENCOLORIO_LIBRARIES - list of libraries to link against when using OpenColorIO
987 +# OPENCOLORIO_DEFINITIONS - Definitions needed when using OpenColorIO
989 +# SPDX-FileCopyrightText: 2008 Contributors to the OpenImageIO project
990 +# SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
991 +# SPDX-License-Identifier: BSD-3-Clause
993 +include (FindPackageHandleStandardArgs)
994 +include (FindPackageMessage)
996 +find_path (OPENCOLORIO_INCLUDE_DIR
997 + OpenColorIO.h
998 + HINTS
999 + ${OPENCOLORIO_INCLUDE_PATH}
1000 + ENV OPENCOLORIO_INCLUDE_PATH
1001 + PATHS
1002 + /sw/include
1003 + /opt/local/include
1004 + PATH_SUFFIXES OpenColorIO OpenColorIO1
1005 + DOC "The directory where OpenColorIO.h resides")
1007 +if (EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h")
1008 + # Search twice, because this symbol changed between OCIO 1.x and 2.x
1009 + file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP
1010 + REGEX "^#define OCIO_VERSION_STR[ \t].*$")
1011 + if (NOT TMP)
1012 + file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP
1013 + REGEX "^#define OCIO_VERSION[ \t].*$")
1014 + endif ()
1015 + string (REGEX MATCHALL "([0-9]+)\\.([0-9]+)\\.[0-9]+" OPENCOLORIO_VERSION ${TMP})
1016 + set (OPENCOLORIO_VERSION_MAJOR ${CMAKE_MATCH_1})
1017 + set (OPENCOLORIO_VERSION_MINOR ${CMAKE_MATCH_2})
1018 +endif ()
1020 +find_library (OPENCOLORIO_LIBRARY
1021 + NAMES
1022 + OpenColorIO
1023 + OpenColorIO_${OPENCOLORIO_VERSION_MAJOR}_${OPENCOLORIO_VERSION_MINOR}
1024 + OpenColorIO${OPENCOLORIO_VERSION_MAJOR}
1025 + HINTS
1026 + ${OPENCOLORIO_LIBRARY_PATH}
1027 + ENV OPENCOLORIO_LIBRARY_PATH
1028 + PATHS
1029 + /usr/lib64
1030 + /usr/local/lib64
1031 + /sw/lib
1032 + /opt/local/lib
1033 + DOC "The OCIO library")
1035 +find_package_handle_standard_args (OpenColorIO
1036 + REQUIRED_VARS OPENCOLORIO_INCLUDE_DIR OPENCOLORIO_LIBRARY
1037 + FOUND_VAR OPENCOLORIO_FOUND
1038 + VERSION_VAR OPENCOLORIO_VERSION
1041 +if (OpenColorIO_FOUND)
1042 + set (OPENCOLORIO_INCLUDES ${OPENCOLORIO_INCLUDE_DIR})
1043 + set (OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARY})
1044 + set (OPENCOLORIO_DEFINITIONS "")
1045 + if (NOT TARGET OpenColorIO::OpenColorIO)
1046 + add_library(OpenColorIO::OpenColorIO UNKNOWN IMPORTED)
1047 + set_target_properties(OpenColorIO::OpenColorIO PROPERTIES
1048 + INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}")
1050 + set_property(TARGET OpenColorIO::OpenColorIO APPEND PROPERTY
1051 + IMPORTED_LOCATION "${OPENCOLORIO_LIBRARIES}")
1052 + if (LINKSTATIC)
1053 + target_compile_definitions(OpenColorIO::OpenColorIO
1054 + INTERFACE "-DOpenColorIO_STATIC")
1055 + endif()
1056 + endif ()
1057 + if (NOT TARGET OpenColorIO::OpenColorIOHeaders)
1058 + add_library(OpenColorIO::OpenColorIOHeaders INTERFACE IMPORTED)
1059 + set_target_properties(OpenColorIO::OpenColorIOHeaders PROPERTIES
1060 + INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}")
1061 + endif ()
1062 +endif ()
1064 +if (OpenColorIO_FOUND AND LINKSTATIC)
1065 + # Is this necessary?
1066 + set (OPENCOLORIO_DEFINITIONS "-DOpenColorIO_STATIC")
1067 + find_library (TINYXML_LIBRARY NAMES tinyxml)
1068 + if (TINYXML_LIBRARY)
1069 + set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${TINYXML_LIBRARY}" CACHE STRING "" FORCE)
1070 + endif ()
1071 + find_library (YAML_LIBRARY NAMES yaml-cpp)
1072 + if (YAML_LIBRARY)
1073 + set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${YAML_LIBRARY}" CACHE STRING "" FORCE)
1074 + endif ()
1075 + find_library (LCMS2_LIBRARY NAMES lcms2)
1076 + if (LCMS2_LIBRARY)
1077 + set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${LCMS2_LIBRARY}" CACHE STRING "" FORCE)
1078 + endif ()
1079 +endif ()