From bf446419091949ab03af23acc3b46333374a645b Mon Sep 17 00:00:00 2001 From: David Beauchamp Date: Fri, 22 Oct 2021 17:02:55 -0400 Subject: [PATCH] extra/krita to 4.4.8-3 --- extra/krita/PKGBUILD | 13 +- extra/krita/krita-opencolorio1.patch | 18 - extra/krita/krita-opencolorio2.patch | 1080 ++++++++++++++++++++++++++ 3 files changed, 1085 insertions(+), 26 deletions(-) delete mode 100644 extra/krita/krita-opencolorio1.patch create mode 100644 extra/krita/krita-opencolorio2.patch diff --git a/extra/krita/PKGBUILD b/extra/krita/PKGBUILD index 0caff125f..a9456c6cf 100644 --- a/extra/krita/PKGBUILD +++ b/extra/krita/PKGBUILD @@ -6,13 +6,13 @@ pkgname=krita _pkgver=4.4.8 pkgver=${_pkgver/-/} -pkgrel=2 +pkgrel=3 pkgdesc='Edit and paint images' arch=(x86_64) url='https://krita.org' license=(GPL3) depends=(kitemviews kitemmodels ki18n kcompletion kguiaddons kcrash qt5-svg qt5-multimedia quazip - gsl libraw exiv2 openexr fftw giflib openjpeg2 opencolorio1 hicolor-icon-theme) + gsl libraw exiv2 openexr fftw giflib openjpeg2 opencolorio hicolor-icon-theme) makedepends=(extra-cmake-modules kdoctools boost eigen poppler-qt5 python-pyqt5 libheif qt5-tools sip kseexpr) optdepends=('poppler-qt5: PDF filter' 'ffmpeg: to save animations' @@ -20,21 +20,18 @@ optdepends=('poppler-qt5: PDF filter' 'ffmpeg: to save animations' 'kseexpr: SeExpr generator layer' 'kimageformats: PSD support') source=(https://download.kde.org/stable/krita/$_pkgver/$pkgname-$_pkgver.tar.gz{,.sig} krita-openexr3.patch - https://invent.kde.org/graphics/krita/-/commit/86dc361a.patch - krita-opencolorio1.patch) + krita-opencolorio2.patch) sha256sums=('bcc68a5711d92515d6553611a0bddd53f3259843fd3534b9b3e535d7ed430df8' 'SKIP' '3825dac0317f4501c8dd8b0844540bbd0841702cd15903ce3a659755eaa226f5' - '00c4e519bbef9575f8d4ae2183aff1da3ad9f44d324c1c1d45a7803368a1a008' - '2f892449e20abc370fe3dc8b5dd12f9964d1d402a909e775641e28685b1719b3') + 'ca24ada0e2bd620e8abe74eff7adda3526925a9b61a968849d3885084bc13816') validpgpkeys=('05D00A8B73A686789E0A156858B9596C722EA3BD' # Boudewijn Rempt 'E9FB29E74ADEACC5E3035B8AB69EB4CF7468332F' # Dmitry Kazakov (main key) '064182440C674D9F8D0F6F8B4DA79EDA231C852B') # Stichting Krita Foundation prepare() { patch -d $pkgname-$_pkgver -p1 < krita-openexr3.patch # Fix build with OpenEXR 3 - patch -d $pkgname-$_pkgver -p1 < 86dc361a.patch # Fix OCIO include dir detection - patch -d $pkgname-$_pkgver -p1 < krita-opencolorio1.patch # Fix build with renamed OCIO library + patch -d $pkgname-$_pkgver -p1 < krita-opencolorio2.patch # Fix build with OCIO 2 } build() { diff --git a/extra/krita/krita-opencolorio1.patch b/extra/krita/krita-opencolorio1.patch deleted file mode 100644 index 92ae9a775..000000000 --- a/extra/krita/krita-opencolorio1.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/cmake/modules/FindOCIO.cmake b/cmake/modules/FindOCIO.cmake -index 89b404088c..02a8753221 100644 ---- a/cmake/modules/FindOCIO.cmake -+++ b/cmake/modules/FindOCIO.cmake -@@ -34,11 +34,11 @@ find_path(OCIO_INCLUDE_DIR OpenColorIO.h - /usr/local/include - /sw/include - /opt/local/include -- PATH_SUFFIXES OpenColorIO -+ PATH_SUFFIXES OpenColorIO1 - DOC "The directory where OpenColorIO/OpenColorIO.h resides" - ) - --find_library(OCIO_LIBRARIES OpenColorIO -+find_library(OCIO_LIBRARIES OpenColorIO1 - PATHS - ${OCIO_LIBRARY_PATH} - ${OCIO_PATH}/lib/ diff --git a/extra/krita/krita-opencolorio2.patch b/extra/krita/krita-opencolorio2.patch new file mode 100644 index 000000000..260e8bb2e --- /dev/null +++ b/extra/krita/krita-opencolorio2.patch @@ -0,0 +1,1080 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e06a3bd0ab..e02b1ad196 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -705,13 +705,13 @@ if (FFTW3_FOUND) + list (APPEND ANDROID_EXTRA_LIBS ${FFTW3_LIBRARY}) + endif() + +-find_package(OCIO) +-set_package_properties(OCIO PROPERTIES ++find_package(OpenColorIO) ++set_package_properties(OpenColorIO PROPERTIES + DESCRIPTION "The OpenColorIO Library" + URL "https://www.opencolorio.org" + TYPE OPTIONAL + PURPOSE "Required by the Krita LUT docker") +-macro_bool_to_01(OCIO_FOUND HAVE_OCIO) ++macro_bool_to_01(OpenColorIO_FOUND HAVE_OCIO) + + set_package_properties(PythonLibrary PROPERTIES + DESCRIPTION "Python Library" +diff --git a/krita/data/shaders/highq_downscale.frag b/krita/data/shaders/highq_downscale.frag +index bb2a47c2a3..73c95ebfa8 100644 +--- a/krita/data/shaders/highq_downscale.frag ++++ b/krita/data/shaders/highq_downscale.frag +@@ -3,10 +3,6 @@ + */ + uniform sampler2D texture0; + +-#ifdef USE_OCIO +-uniform sampler3D texture1; +-#endif +- + in vec4 v_textureCoordinate; + out vec4 fragColor; + +@@ -119,7 +115,7 @@ void main() { + } + + #ifdef USE_OCIO +- fragColor = OCIODisplay(col, texture1); ++ fragColor = OCIODisplay(col); + #else /* USE_OCIO */ + fragColor = col; + #endif /* USE_OCIO */ +diff --git a/libs/ui/canvas/kis_display_filter.h b/libs/ui/canvas/kis_display_filter.h +index a2ae5ab584..e96506d892 100644 +--- a/libs/ui/canvas/kis_display_filter.h ++++ b/libs/ui/canvas/kis_display_filter.h +@@ -26,6 +26,9 @@ + + struct KisExposureGammaCorrectionInterface; + ++class QOpenGLFunctions; ++class QOpenGLShaderProgram; ++ + /** + * @brief The KisDisplayFilter class is the base class for filters that + * are applied by the canvas to the projection before displaying. +@@ -37,7 +40,7 @@ public: + explicit KisDisplayFilter(QObject *parent = 0); + + virtual QString program() const = 0; +- virtual GLuint lutTexture() const = 0; ++ virtual void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const = 0; + virtual void filter(quint8 *pixels, quint32 numPixels) = 0; + virtual void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) = 0; + virtual void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) = 0; +diff --git a/libs/ui/opengl/kis_opengl_canvas2.cpp b/libs/ui/opengl/kis_opengl_canvas2.cpp +index 69bd84000f..50acab76bf 100644 +--- a/libs/ui/opengl/kis_opengl_canvas2.cpp ++++ b/libs/ui/opengl/kis_opengl_canvas2.cpp +@@ -947,9 +947,7 @@ void KisOpenGLCanvas2::drawImage(const QRect &updateRect) + } + + if (d->displayFilter) { +- glActiveTexture(GL_TEXTURE0 + 1); +- glBindTexture(GL_TEXTURE_3D, d->displayFilter->lutTexture()); +- d->displayShader->setUniformValue(d->displayShader->location(Uniform::Texture1), 1); ++ d->displayFilter->setupTextures(this, d->displayShader); + } + + glActiveTexture(GL_TEXTURE0); +diff --git a/libs/ui/opengl/kis_opengl_shader_loader.cpp b/libs/ui/opengl/kis_opengl_shader_loader.cpp +index 8513617815..75a4f08ba3 100644 +--- a/libs/ui/opengl/kis_opengl_shader_loader.cpp ++++ b/libs/ui/opengl/kis_opengl_shader_loader.cpp +@@ -150,6 +150,7 @@ KisShaderProgram *KisOpenGLShaderLoader::loadDisplayShader(QSharedPointerprogram().isEmpty(); + if (haveDisplayFilter) { + fragHeader.append("#define USE_OCIO\n"); ++ fragHeader.append("#define USE_OCIO_V2\n"); + fragHeader.append(displayFilter->program().toLatin1()); + } + +diff --git a/plugins/dockers/lut/CMakeLists.txt b/plugins/dockers/lut/CMakeLists.txt +index 01844be146..795c99162d 100644 +--- a/plugins/dockers/lut/CMakeLists.txt ++++ b/plugins/dockers/lut/CMakeLists.txt +@@ -17,5 +17,5 @@ ki18n_wrap_ui(KRITA_LUTDOCKER_SOURCES + + add_library(kritalutdocker MODULE ${KRITA_LUTDOCKER_SOURCES}) + +-target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} ${OCIO_LIBRARIES}) ++target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} OpenColorIO::OpenColorIO) + install(TARGETS kritalutdocker DESTINATION ${KRITA_PLUGIN_INSTALL_DIR}) +diff --git a/plugins/dockers/lut/lutdocker_dock.cpp b/plugins/dockers/lut/lutdocker_dock.cpp +index c7e68dce06..3c57144c9d 100644 +--- a/plugins/dockers/lut/lutdocker_dock.cpp ++++ b/plugins/dockers/lut/lutdocker_dock.cpp +@@ -56,12 +56,12 @@ + #include + #include "kis_signals_blocker.h" + #include "krita_utils.h" ++#include + +-#include "ocio_display_filter.h" +-#include "black_white_point_chooser.h" +-#include "KisOcioConfiguration.h" + #include + ++#include "black_white_point_chooser.h" ++ + + OCIO::ConstConfigRcPtr defaultRawProfile() + { +@@ -231,6 +231,8 @@ void LutDockerDock::slotUpdateIcons() + { + m_btnConvertCurrentColor->setIcon(KisIconUtils::loadIcon("krita_tool_freehand")); + m_btmShowBWConfiguration->setIcon(KisIconUtils::loadIcon("properties")); ++ m_lblOcioVersion->setText(OCIO_VERSION_FULL_STR); ++ m_lblOcioVersion->setEnabled(false); + } + + void LutDockerDock::slotShowBWConfiguration() +diff --git a/plugins/dockers/lut/ocio_display_filter.cpp b/plugins/dockers/lut/ocio_display_filter.cpp +index 33afb01f1e..e429e3c2f4 100644 +--- a/plugins/dockers/lut/ocio_display_filter.cpp ++++ b/plugins/dockers/lut/ocio_display_filter.cpp +@@ -1,38 +1,29 @@ + /* +- * Copyright (c) 2012 Boudewijn Rempt ++ * SPDX-FileCopyrightText: 2012 Boudewijn Rempt ++ * SPDX-FileCopyrightText: 2021 L. E. Segovia + * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ ++ + #include "ocio_display_filter.h" +-#include +-#include ++ ++#include ++#include ++#include ++#include ++#include ++ + #include +-#include + #include +-#include +-#include +-#include + + #include +- ++#include + #include +-#include +-#include +-#include +-#include +-#include ++ ++#if defined(QT_OPENGL_ES_2) ++#define GL_RGBA32F_ARB GL_RGBA32F_EXT ++#define GL_RGB32F_ARB GL_RGB32F_EXT ++#endif + + OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent) + : KisDisplayFilter(parent) +@@ -42,7 +33,8 @@ OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interf + , look(0) + , swizzle(RGBA) + , m_interface(interface) +- , m_lut3dTexID(0) ++ , m_lut3dTexIDs() ++ , m_lut3dUniforms() + , m_shaderDirty(true) + { + } +@@ -51,7 +43,7 @@ OcioDisplayFilter::~OcioDisplayFilter() + { + } + +-KisExposureGammaCorrectionInterface* OcioDisplayFilter::correctionInterface() const ++KisExposureGammaCorrectionInterface *OcioDisplayFilter::correctionInterface() const + { + return m_interface; + } +@@ -60,8 +52,8 @@ void OcioDisplayFilter::filter(quint8 *pixels, quint32 numPixels) + { + // processes that data _in_ place + if (m_processor) { +- OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); +- m_processor->apply(img); ++ OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); ++ m_processor->getDefaultCPUProcessor()->apply(img); + } + } + +@@ -69,8 +61,8 @@ void OcioDisplayFilter::approximateInverseTransformation(quint8 *pixels, quint32 + { + // processes that data _in_ place + if (m_revereseApproximationProcessor) { +- OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); +- m_revereseApproximationProcessor->apply(img); ++ OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); ++ m_revereseApproximationProcessor->getDefaultCPUProcessor()->apply(img); + } + } + +@@ -78,8 +70,8 @@ void OcioDisplayFilter::approximateForwardTransformation(quint8 *pixels, quint32 + { + // processes that data _in_ place + if (m_forwardApproximationProcessor) { +- OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); +- m_forwardApproximationProcessor->apply(img); ++ OCIO::PackedImageDesc img(reinterpret_cast(pixels), numPixels, 1, 4); ++ m_forwardApproximationProcessor->getDefaultCPUProcessor()->apply(img); + } + } + +@@ -103,11 +95,6 @@ QString OcioDisplayFilter::program() const + return m_program; + } + +-GLuint OcioDisplayFilter::lutTexture() const +-{ +- return m_lut3dTexID; +-} +- + void OcioDisplayFilter::updateProcessor() + { + if (!config) { +@@ -126,18 +113,22 @@ void OcioDisplayFilter::updateProcessor() + inputColorSpaceName = config->getColorSpaceNameByIndex(0); + } + if (!look) { +- look = config->getLookNameByIndex(0); ++ look = config->getLookNameByIndex(0); + } + + if (!displayDevice || !view || !inputColorSpaceName) { + return; + } + +- OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create(); +- transform->setInputColorSpaceName(inputColorSpaceName); ++ OCIO::DisplayViewTransformRcPtr transform = OCIO::DisplayViewTransform::Create(); ++ transform->setSrc(inputColorSpaceName); + transform->setDisplay(displayDevice); + transform->setView(view); + ++ OCIO::LegacyViewingPipelineRcPtr vpt = OCIO::LegacyViewingPipeline::Create(); ++ ++ vpt->setDisplayViewTransform(transform); ++ + /** + * Look support: + * As the OCIO docs will tell you, looks are a aesthetic transform that is +@@ -155,36 +146,37 @@ void OcioDisplayFilter::updateProcessor() + * override is all we can offer. + */ + if (config->getLook(look)) { +- transform->setLooksOverride(look); +- transform->setLooksOverrideEnabled(true); ++ vpt->setLooksOverride(look); ++ vpt->setLooksOverrideEnabled(true); + } + + OCIO::GroupTransformRcPtr approximateTransform = OCIO::GroupTransform::Create(); + + // fstop exposure control -- not sure how that translates to our exposure + { +- float exposureGain = powf(2.0f, exposure); ++ const double exposureGain = pow(2.0, exposure); + +- const qreal minRange = 0.001; ++ const double minRange = 0.001; + if (qAbs(blackPoint - whitePoint) < minRange) { + whitePoint = blackPoint + minRange; + } + +- const float oldMin[] = { blackPoint, blackPoint, blackPoint, 0.0f }; +- const float oldMax[] = { whitePoint, whitePoint, whitePoint, 1.0f }; ++ const double oldMin[] = {blackPoint, blackPoint, blackPoint, 0.0}; ++ const double oldMax[] = {whitePoint, whitePoint, whitePoint, 1.0}; + +- const float newMin[] = { 0.0f, 0.0f, 0.0f, 0.0f }; +- const float newMax[] = { exposureGain, exposureGain, exposureGain, 1.0f }; ++ const double newMin[] = {0.0, 0.0, 0.0, 0.0}; ++ const double newMax[] = {exposureGain, exposureGain, exposureGain, 1.0}; + +- float m44[16]; +- float offset4[4]; ++ double m44[16]; ++ double offset4[4]; + OCIO::MatrixTransform::Fit(m44, offset4, oldMin, oldMax, newMin, newMax); +- OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create(); +- mtx->setValue(m44, offset4); +- transform->setLinearCC(mtx); ++ OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create(); ++ mtx->setMatrix(m44); ++ mtx->setOffset(offset4); ++ vpt->setLinearCC(mtx); + + // approximation (no color correction); +- approximateTransform->push_back(mtx); ++ approximateTransform->appendTransform(mtx); + } + + // channel swizzle +@@ -226,32 +218,39 @@ void OcioDisplayFilter::updateProcessor() + channelHot[1] = 0; + channelHot[2] = 0; + channelHot[3] = 1; +- default: +- ; ++ default:; + } +- float lumacoef[3]; ++ double lumacoef[3]; + config->getDefaultLumaCoefs(lumacoef); +- float m44[16]; +- float offset[4]; ++ double m44[16]; ++ double offset[4]; + OCIO::MatrixTransform::View(m44, offset, channelHot, lumacoef); + OCIO::MatrixTransformRcPtr swizzleTransform = OCIO::MatrixTransform::Create(); +- swizzleTransform->setValue(m44, offset); +- transform->setChannelView(swizzleTransform); ++ swizzleTransform->setMatrix(m44); ++ swizzleTransform->setOffset(offset); ++ vpt->setChannelView(swizzleTransform); + } + + // Post-display transform gamma + { +- float exponent = 1.0f/std::max(1e-6f, static_cast(gamma)); +- const float exponent4f[] = { exponent, exponent, exponent, exponent }; +- OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); ++ double exponent = 1.0 / std::max(1e-6, gamma); ++ const double exponent4f[] = {exponent, exponent, exponent, exponent}; ++ OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create(); + expTransform->setValue(exponent4f); +- transform->setDisplayCC(expTransform); ++ vpt->setDisplayCC(expTransform); + + // approximation (no color correction); +- approximateTransform->push_back(expTransform); ++ approximateTransform->appendTransform(expTransform); + } + +- m_processor = config->getProcessor(transform); ++ try { ++ m_processor = vpt->getProcessor(config, config->getCurrentContext()); ++ } catch (OCIO::Exception &e) { ++ // XXX: How to not break the OCIO shader now? ++ errKrita << "OCIO exception while parsing the current context:" << e.what(); ++ m_shaderDirty = false; ++ return; ++ } + + m_forwardApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_FORWARD); + +@@ -259,7 +258,7 @@ void OcioDisplayFilter::updateProcessor() + m_revereseApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_INVERSE); + } catch (...) { + warnKrita << "OCIO inverted matrix does not exist!"; +- //m_revereseApproximationProcessor; ++ // m_revereseApproximationProcessor; + } + + m_shaderDirty = true; +@@ -272,16 +271,19 @@ bool OcioDisplayFilter::updateShader() + if (f) { + return updateShaderImpl(f); + } ++#if defined(QT_OPENGL_3) + } else if (KisOpenGL::hasOpenGL3()) { + QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions(); + if (f) { + return updateShaderImpl(f); + } ++#endif + } + + // XXX This option can be removed once we move to Qt 5.7+ + if (KisOpenGL::supportsLoD()) { +-#ifdef Q_OS_MAC ++#if defined(QT_OPENGL_3) ++#if defined(Q_OS_MAC) && defined(QT_OPENGL_3_2) + QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions(); + #else + QOpenGLFunctions_3_0 *f = QOpenGLContext::currentContext()->versionFunctions(); +@@ -289,23 +291,29 @@ bool OcioDisplayFilter::updateShader() + if (f) { + return updateShaderImpl(f); + } ++#endif + } +- QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions(); ++#if !defined(QT_OPENGL_ES_2) ++ QOpenGLFunctions_2_0 *f = QOpenGLContext::currentContext()->versionFunctions(); + if (f) { + return updateShaderImpl(f); + } ++#endif + + return false; + } + +-template +-bool OcioDisplayFilter::updateShaderImpl(F *f) { ++template ++bool OcioDisplayFilter::updateShaderImpl(F *f) ++{ + // check whether we are allowed to use shaders -- though that should + // work for everyone these days + KisConfig cfg(true); +- if (!cfg.useOpenGL()) return false; ++ if (!cfg.useOpenGL()) ++ return false; + +- if (!m_shaderDirty) return false; ++ if (!m_shaderDirty) ++ return false; + + if (!f) { + qWarning() << "Failed to get valid OpenGL functions for OcioDisplayFilter!"; +@@ -316,71 +324,272 @@ bool OcioDisplayFilter::updateShaderImpl(F *f) { + + bool shouldRecompileShader = false; + +- const int lut3DEdgeSize = cfg.ocioLutEdgeSize(); ++ // Step 1: Create a GPU Shader Description ++ OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc(); + +- if (m_lut3d.size() == 0) { +- //dbgKrita << "generating lut"; +- f->glGenTextures(1, &m_lut3dTexID); ++#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000 ++ if (KisOpenGL::supportsLoD()) { ++ shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_3_0); ++ } else { ++ shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_1_0); ++ } ++#else ++ if (KisOpenGL::supportsLoD()) { ++ shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3); ++ } else { ++ shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2); ++ } ++#endif + +- int num3Dentries = 3 * lut3DEdgeSize * lut3DEdgeSize * lut3DEdgeSize; +- m_lut3d.fill(0.0, num3Dentries); ++ shaderDesc->setFunctionName("OCIODisplay"); ++ shaderDesc->setResourcePrefix("ocio_"); + +- f->glActiveTexture(GL_TEXTURE1); +- f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID); ++ // Step 2: Compute the 3D LUT ++#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000 ++ // ensure the new GPU pipeline is used with our GLES3 patch ++ // this way users won't run into errors when using Angle along with OCIO ++ const auto gpu = m_processor->getOptimizedGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT); ++#else ++ const int lut3DEdgeSize = cfg.ocioLutEdgeSize(); ++ const auto gpu = ++ m_processor->getOptimizedLegacyGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT, lut3DEdgeSize); ++#endif + +- f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +- f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +- f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); +- f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +- f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +- f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, +- lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize, +- 0, GL_RGB, GL_FLOAT, &m_lut3d.constData()[0]); ++ gpu->extractGpuShaderInfo(shaderDesc); ++ ++ // OCIO v2 assumes you'll use the OglApp helpers ++ // these are unusable from a Qt backend, because they rely on GLUT/GLFW ++ // ociodisplay original pipeline: ++ // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/508b3f4a0618435aeed2f45058208bdfa99e0887/src/apps/ociodisplay/main.cpp ++ // ociodisplay new pipeline is a single call: ++ // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/ffddc3341f5775c7866fe2c93275e1d5e0b0540f/src/apps/ociodisplay/main.cpp#L427 ++ // we need to replicate this loop: ++ // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/oglapp.cpp#L191-L223 ++ // calls functions from here: ++ // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/glsl.cpp ++ ++ for (const auto &tex : m_lut3dTexIDs) { ++ f->glDeleteTextures(1, &tex.m_uid); + } + +- // Step 1: Create a GPU Shader Description +- OCIO::GpuShaderDesc shaderDesc; ++ m_lut3dTexIDs.clear(); + +- if (KisOpenGL::supportsLoD()) { +- shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3); +- } +- else { +- shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); ++ // This is the first available index for the textures. ++ unsigned currIndex = 1; ++ ++ // Process the 3D LUT first. ++ ++ const unsigned maxTexture3D = shaderDesc->getNum3DTextures(); ++ for (unsigned idx = 0; idx < maxTexture3D; ++idx) { ++ // 1. Get the information of the 3D LUT. ++ ++ const char *textureName = nullptr; ++ const char *samplerName = nullptr; ++ unsigned edgelen = 0; ++ OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR; ++ shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, interpolation); ++ ++ if (!textureName || !*textureName || !samplerName || !*samplerName || edgelen == 0) { ++ errOpenGL << "The texture data is corrupted"; ++ return false; ++ } ++ ++ const float *values = nullptr; ++ shaderDesc->get3DTextureValues(idx, values); ++ if (!values) { ++ errOpenGL << "The texture values are missing"; ++ return false; ++ } ++ ++ // 2. Allocate the 3D LUT. ++ ++ unsigned texId = 0; ++ { ++ if (values == nullptr) { ++ errOpenGL << "3D LUT" << idx << "Missing texture data"; ++ return false; ++ } ++ ++ f->glGenTextures(1, &texId); ++ ++ f->glActiveTexture(GL_TEXTURE0 + currIndex); ++ ++ f->glBindTexture(GL_TEXTURE_3D, texId); ++ ++ { ++ if (interpolation == OCIO::INTERP_NEAREST) { ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); ++ } else { ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ } ++ ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); ++ } ++ ++ f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F_ARB, edgelen, edgelen, edgelen, 0, GL_RGB, GL_FLOAT, values); ++ } ++ ++ // 3. Keep the texture id & name for the later enabling. ++ ++ m_lut3dTexIDs.push_back({texId, textureName, samplerName, GL_TEXTURE_3D}); ++ ++ currIndex++; + } + ++ // Process the 1D LUTs. + +- shaderDesc.setFunctionName("OCIODisplay"); +- shaderDesc.setLut3DEdgeLen(lut3DEdgeSize); ++ const unsigned maxTexture2D = shaderDesc->getNumTextures(); ++ for (unsigned idx = 0; idx < maxTexture2D; ++idx) { ++ // 1. Get the information of the 1D LUT. + ++ const char *textureName = nullptr; ++ const char *samplerName = nullptr; ++ unsigned width = 0; ++ unsigned height = 0; ++ OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL; ++ OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR; ++ shaderDesc->getTexture(idx, textureName, samplerName, width, height, channel, interpolation); + +- // Step 2: Compute the 3D LUT +- QString lut3dCacheID = QString::fromLatin1(m_processor->getGpuLut3DCacheID(shaderDesc)); +- if (lut3dCacheID != m_lut3dcacheid) { +- //dbgKrita << "Computing 3DLut " << m_lut3dcacheid; +- m_lut3dcacheid = lut3dCacheID; +- m_processor->getGpuLut3D(&m_lut3d[0], shaderDesc); +- +- f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID); +- f->glTexSubImage3D(GL_TEXTURE_3D, 0, +- 0, 0, 0, +- lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize, +- GL_RGB, GL_FLOAT, &m_lut3d[0]); ++ if (!textureName || !*textureName || !samplerName || !*samplerName || width == 0) { ++ errOpenGL << "The texture data is corrupted"; ++ return false; ++ } ++ ++ const float *values = nullptr; ++ shaderDesc->getTextureValues(idx, values); ++ if (!values) { ++ errOpenGL << "The texture values are missing"; ++ return false; ++ } ++ ++ // 2. Allocate the 1D LUT (a 2D texture is needed to hold large LUTs). ++ ++ unsigned texId = 0; ++ { ++ if (values == nullptr) { ++ errOpenGL << "1D LUT" << idx << "Missing texture data."; ++ return false; ++ } ++ ++ unsigned internalformat = GL_RGB32F_ARB; ++ unsigned format = GL_RGB; ++ ++ if (channel == OCIO::GpuShaderCreator::TEXTURE_RED_CHANNEL) { ++ internalformat = GL_R32F; ++ format = GL_RED; ++ } ++ ++ f->glGenTextures(1, &texId); ++ ++ f->glActiveTexture(GL_TEXTURE0 + currIndex); ++ ++#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000 ++#else ++ // 1D Textures are unsupported by OpenGL ES. ++ // https://github.com/AcademySoftwareFoundation/OpenColorIO/issues/1486 ++ if (height > 1) { ++#endif ++ f->glBindTexture(GL_TEXTURE_2D, texId); ++ ++ { ++ if (interpolation == OCIO::INTERP_NEAREST) { ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); ++ } else { ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ++ } ++ ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ++ f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); ++ } ++ ++ f->glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, GL_FLOAT, values); ++#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000 ++#else ++ } else { ++ errOpenGL << "1D texture detected @" << idx << ", not supported by OpenGLES"; ++ return false; ++ } ++#endif ++ } ++ ++ // 3. Keep the texture id & name for the later enabling. ++ ++ unsigned type = GL_TEXTURE_2D; ++ m_lut3dTexIDs.push_back({texId, textureName, samplerName, type}); ++ currIndex++; + } + + // Step 3: Generate the shader text +- QString shaderCacheID = QString::fromLatin1(m_processor->getGpuShaderTextCacheID(shaderDesc)); ++ QString shaderCacheID = QString::fromLatin1(shaderDesc->getCacheID()); + if (m_program.isEmpty() || shaderCacheID != m_shadercacheid) { +- //dbgKrita << "Computing Shader " << m_shadercacheid; ++ // dbgKrita << "Computing Shader " << m_shadercacheid; + + m_shadercacheid = shaderCacheID; + +- std::ostringstream os; +- os << m_processor->getGpuShaderText(shaderDesc) << "\n"; +- +- m_program = QString::fromLatin1(os.str().c_str()); ++ m_program = QString::fromLatin1("%1\n").arg(shaderDesc->getShaderText()); + shouldRecompileShader = true; + } + ++ // Step 4: mirror and bind uniforms ++ m_lut3dUniforms.clear(); ++ ++ const unsigned maxUniforms = shaderDesc->getNumUniforms(); ++ for (unsigned idx = 0; idx < maxUniforms; ++idx) { ++ OCIO::GpuShaderDesc::UniformData data; ++ const char *name = shaderDesc->getUniform(idx, data); ++ if (data.m_type == OCIO::UNIFORM_UNKNOWN) { ++ errOpenGL << "Uniform" << idx << "has an unknown type"; ++ return false; ++ } ++ // Transfer uniform. ++ m_lut3dUniforms.push_back({name, data}); ++ } ++ + m_shaderDirty = false; + return shouldRecompileShader; + } ++ ++void OcioDisplayFilter::setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const ++{ ++ for (unsigned int idx = 0; idx < m_lut3dTexIDs.size(); ++idx) { ++ const auto &data = m_lut3dTexIDs[idx]; ++ f->glActiveTexture(GL_TEXTURE0 + 1 + idx); ++ f->glBindTexture(data.m_type, data.m_uid); ++ program->setUniformValue(program->uniformLocation(data.m_samplerName), GLint(1 + idx)); ++ } ++ ++ for (const KisTextureUniform &uniform : m_lut3dUniforms) { ++ const int m_handle = program->uniformLocation(uniform.m_name); ++ ++ const OCIO::GpuShaderDesc::UniformData &m_data = uniform.m_data; ++ ++ // Update value. ++ if (m_data.m_getDouble) { ++ program->setUniformValue(m_handle, static_cast(m_data.m_getDouble())); ++ } else if (m_data.m_getBool) { ++ program->setUniformValue(m_handle, static_cast(m_data.m_getBool() ? 1.0f : 0.0f)); ++ } else if (m_data.m_getFloat3) { ++ program->setUniformValue(m_handle, ++ m_data.m_getFloat3()[0], ++ m_data.m_getFloat3()[1], ++ m_data.m_getFloat3()[2]); ++ } else if (m_data.m_vectorFloat.m_getSize && m_data.m_vectorFloat.m_getVector) { ++ program->setUniformValueArray(m_handle, ++ m_data.m_vectorFloat.m_getVector(), ++ m_data.m_vectorFloat.m_getSize(), ++ 1); ++ } else if (m_data.m_vectorInt.m_getSize && m_data.m_vectorInt.m_getVector) { ++ program->setUniformValueArray(m_handle, m_data.m_vectorInt.m_getVector(), m_data.m_vectorInt.m_getSize()); ++ } else { ++ errOpenGL << "Uniform" << uniform.m_name << "is not linked to any value"; ++ continue; ++ } ++ } ++} +diff --git a/plugins/dockers/lut/ocio_display_filter.h b/plugins/dockers/lut/ocio_display_filter.h +index 48d896a4c0..963fcf5f93 100644 +--- a/plugins/dockers/lut/ocio_display_filter.h ++++ b/plugins/dockers/lut/ocio_display_filter.h +@@ -1,38 +1,56 @@ + /* +- * Copyright (c) 2012 Boudewijn Rempt ++ * SPDX-FileCopyrightText: 2012 Boudewijn Rempt ++ * SPDX-FileCopyrightText: 2021 L. E. Segovia + * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License as published by +- * the Free Software Foundation; either version 2 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * You should have received a copy of the GNU General Public License +- * along with this program; if not, write to the Free Software +- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ * SPDX-License-Identifier: GPL-2.0-or-later + */ ++ + #ifndef OCIO_DISPLAY_FILTER_H + #define OCIO_DISPLAY_FILTER_H + ++#include ++ ++#include ++ ++#include ++#include ++#include ++ + #include +-#include +-#include +-#include +-#include "kis_exposure_gamma_correction_interface.h" ++#include + + namespace OCIO = OCIO_NAMESPACE; + +-enum OCIO_CHANNEL_SWIZZLE { +- LUMINANCE, +- RGBA, +- R, +- G, +- B, +- A ++enum OCIO_CHANNEL_SWIZZLE { LUMINANCE, RGBA, R, G, B, A }; ++ ++struct KisTextureUniform { ++public: ++ KisTextureUniform(const QString &name, const OCIO::GpuShaderDesc::UniformData &data) ++ : m_name(name) ++ , m_data(data) ++ { ++ } ++ ++ QString m_name; ++ OCIO::GpuShaderDesc::UniformData m_data; ++ ++private: ++ KisTextureUniform() = delete; ++}; ++ ++struct KisTextureEntry { ++ unsigned m_uid = -1; ++ QString m_textureName; ++ QString m_samplerName; ++ unsigned m_type = -1; ++ ++ KisTextureEntry(unsigned uid, const QString &textureName, const QString &samplerName, unsigned type) ++ : m_uid(uid) ++ , m_textureName(textureName) ++ , m_samplerName(samplerName) ++ , m_type(type) ++ { ++ } + }; + + class OcioDisplayFilter : public KisDisplayFilter +@@ -42,21 +60,23 @@ public: + explicit OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent = 0); + ~OcioDisplayFilter(); + +- void filter(quint8 *pixels, quint32 numPixels); +- void approximateInverseTransformation(quint8 *pixels, quint32 numPixels); +- void approximateForwardTransformation(quint8 *pixels, quint32 numPixels); +- bool useInternalColorManagement() const; +- bool lockCurrentColorVisualRepresentation() const; ++ void filter(quint8 *pixels, quint32 numPixels) override; ++ void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) override; ++ void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) override; ++ bool useInternalColorManagement() const override; ++ bool lockCurrentColorVisualRepresentation() const override; + void setLockCurrentColorVisualRepresentation(bool value); + +- bool updateShader(); +- template ++ bool updateShader() override; ++ ++ template + bool updateShaderImpl(F *f); + +- KisExposureGammaCorrectionInterface *correctionInterface() const; ++ void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const override; + +- virtual QString program() const; +- GLuint lutTexture() const; ++ KisExposureGammaCorrectionInterface *correctionInterface() const override; ++ ++ QString program() const override; + + void updateProcessor(); + +@@ -67,14 +87,13 @@ public: + const char *view; + const char *look; + OCIO_CHANNEL_SWIZZLE swizzle; +- float exposure; +- float gamma; +- float blackPoint; +- float whitePoint; ++ double exposure; ++ double gamma; ++ double blackPoint; ++ double whitePoint; + bool forceInternalColorManagement; + + private: +- + OCIO::ConstProcessorRcPtr m_processor; + OCIO::ConstProcessorRcPtr m_revereseApproximationProcessor; + OCIO::ConstProcessorRcPtr m_forwardApproximationProcessor; +@@ -84,10 +103,10 @@ private: + bool m_lockCurrentColorVisualRepresentation; + + QString m_program; +- GLuint m_lut3dTexID; +- QVector m_lut3d; ++ std::vector m_lut3dTexIDs; + QString m_lut3dcacheid; + QString m_shadercacheid; ++ std::vector m_lut3dUniforms; + + bool m_shaderDirty; + }; +diff --git a/plugins/dockers/lut/tests/CMakeLists.txt b/plugins/dockers/lut/tests/CMakeLists.txt +index 85cd5ecbc6..8891b8b683 100644 +--- a/plugins/dockers/lut/tests/CMakeLists.txt ++++ b/plugins/dockers/lut/tests/CMakeLists.txt +@@ -11,5 +11,5 @@ krita_add_broken_unit_test(kis_ocio_display_filter_test.cpp + ../ocio_display_filter.cpp + ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp + TEST_NAME KisOcioDisplayFilterTest +- LINK_LIBRARIES kritaui ${OCIO_LIBRARIES} KF5::I18n Qt5::Test ++ LINK_LIBRARIES kritaui OpenColorIO::OpenColorIO KF5::I18n Qt5::Test + NAME_PREFIX "plugins-dockers-lut-") +diff --git a/plugins/dockers/lut/wdglut.ui b/plugins/dockers/lut/wdglut.ui +index 2ba3c2b073..403e5c26a3 100644 +--- a/plugins/dockers/lut/wdglut.ui ++++ b/plugins/dockers/lut/wdglut.ui +@@ -7,7 +7,7 @@ + 0 + 0 + 357 +- 286 ++ 328 + + + +@@ -338,7 +338,7 @@ + + + +- ++ + + 2 + +@@ -348,6 +348,13 @@ + + 2 + ++ ++ ++ ++ TextLabel ++ ++ ++ + + + +diff --git a/cmake/modules/FindOpenColorIO.cmake b/cmake/modules/FindOpenColorIO.cmake +new file mode 100644 +index 0000000000..2a9e9310b1 +--- /dev/null ++++ b/cmake/modules/FindOpenColorIO.cmake +@@ -0,0 +1,104 @@ ++# Module to find OpenColorIO ++# ++# This module will first look into the directories hinted by the variables: ++# - OpenColorIO_ROOT ++# ++# This module defines the following variables: ++# ++# OPENCOLORIO_FOUND - True if OpenColorIO was found. ++# OPENCOLORIO_INCLUDES - where to find OpenColorIO.h ++# OPENCOLORIO_LIBRARIES - list of libraries to link against when using OpenColorIO ++# OPENCOLORIO_DEFINITIONS - Definitions needed when using OpenColorIO ++# ++# SPDX-FileCopyrightText: 2008 Contributors to the OpenImageIO project ++# SPDX-FileCopyrightText: 2021 L. E. Segovia ++# SPDX-License-Identifier: BSD-3-Clause ++ ++include (FindPackageHandleStandardArgs) ++include (FindPackageMessage) ++ ++find_path (OPENCOLORIO_INCLUDE_DIR ++ OpenColorIO.h ++ HINTS ++ ${OPENCOLORIO_INCLUDE_PATH} ++ ENV OPENCOLORIO_INCLUDE_PATH ++ PATHS ++ /sw/include ++ /opt/local/include ++ PATH_SUFFIXES OpenColorIO OpenColorIO1 ++ DOC "The directory where OpenColorIO.h resides") ++ ++if (EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h") ++ # Search twice, because this symbol changed between OCIO 1.x and 2.x ++ file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP ++ REGEX "^#define OCIO_VERSION_STR[ \t].*$") ++ if (NOT TMP) ++ file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP ++ REGEX "^#define OCIO_VERSION[ \t].*$") ++ endif () ++ string (REGEX MATCHALL "([0-9]+)\\.([0-9]+)\\.[0-9]+" OPENCOLORIO_VERSION ${TMP}) ++ set (OPENCOLORIO_VERSION_MAJOR ${CMAKE_MATCH_1}) ++ set (OPENCOLORIO_VERSION_MINOR ${CMAKE_MATCH_2}) ++endif () ++ ++find_library (OPENCOLORIO_LIBRARY ++ NAMES ++ OpenColorIO ++ OpenColorIO_${OPENCOLORIO_VERSION_MAJOR}_${OPENCOLORIO_VERSION_MINOR} ++ OpenColorIO${OPENCOLORIO_VERSION_MAJOR} ++ HINTS ++ ${OPENCOLORIO_LIBRARY_PATH} ++ ENV OPENCOLORIO_LIBRARY_PATH ++ PATHS ++ /usr/lib64 ++ /usr/local/lib64 ++ /sw/lib ++ /opt/local/lib ++ DOC "The OCIO library") ++ ++find_package_handle_standard_args (OpenColorIO ++ REQUIRED_VARS OPENCOLORIO_INCLUDE_DIR OPENCOLORIO_LIBRARY ++ FOUND_VAR OPENCOLORIO_FOUND ++ VERSION_VAR OPENCOLORIO_VERSION ++ ) ++ ++if (OpenColorIO_FOUND) ++ set (OPENCOLORIO_INCLUDES ${OPENCOLORIO_INCLUDE_DIR}) ++ set (OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARY}) ++ set (OPENCOLORIO_DEFINITIONS "") ++ if (NOT TARGET OpenColorIO::OpenColorIO) ++ add_library(OpenColorIO::OpenColorIO UNKNOWN IMPORTED) ++ set_target_properties(OpenColorIO::OpenColorIO PROPERTIES ++ INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}") ++ ++ set_property(TARGET OpenColorIO::OpenColorIO APPEND PROPERTY ++ IMPORTED_LOCATION "${OPENCOLORIO_LIBRARIES}") ++ if (LINKSTATIC) ++ target_compile_definitions(OpenColorIO::OpenColorIO ++ INTERFACE "-DOpenColorIO_STATIC") ++ endif() ++ endif () ++ if (NOT TARGET OpenColorIO::OpenColorIOHeaders) ++ add_library(OpenColorIO::OpenColorIOHeaders INTERFACE IMPORTED) ++ set_target_properties(OpenColorIO::OpenColorIOHeaders PROPERTIES ++ INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}") ++ endif () ++endif () ++ ++if (OpenColorIO_FOUND AND LINKSTATIC) ++ # Is this necessary? ++ set (OPENCOLORIO_DEFINITIONS "-DOpenColorIO_STATIC") ++ find_library (TINYXML_LIBRARY NAMES tinyxml) ++ if (TINYXML_LIBRARY) ++ set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${TINYXML_LIBRARY}" CACHE STRING "" FORCE) ++ endif () ++ find_library (YAML_LIBRARY NAMES yaml-cpp) ++ if (YAML_LIBRARY) ++ set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${YAML_LIBRARY}" CACHE STRING "" FORCE) ++ endif () ++ find_library (LCMS2_LIBRARY NAMES lcms2) ++ if (LCMS2_LIBRARY) ++ set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${LCMS2_LIBRARY}" CACHE STRING "" FORCE) ++ endif () ++endif () ++