Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 821244
Collapse All | Expand All

(-)a/CMakeLists.txt (-3 / +3 lines)
Lines 705-717 if (FFTW3_FOUND) Link Here
705
    list (APPEND ANDROID_EXTRA_LIBS ${FFTW3_LIBRARY})
705
    list (APPEND ANDROID_EXTRA_LIBS ${FFTW3_LIBRARY})
706
endif()
706
endif()
707
707
708
find_package(OCIO)
708
find_package(OpenColorIO)
709
set_package_properties(OCIO PROPERTIES
709
set_package_properties(OpenColorIO PROPERTIES
710
    DESCRIPTION "The OpenColorIO Library"
710
    DESCRIPTION "The OpenColorIO Library"
711
    URL "https://www.opencolorio.org"
711
    URL "https://www.opencolorio.org"
712
    TYPE OPTIONAL
712
    TYPE OPTIONAL
713
    PURPOSE "Required by the Krita LUT docker")
713
    PURPOSE "Required by the Krita LUT docker")
714
macro_bool_to_01(OCIO_FOUND HAVE_OCIO)
714
macro_bool_to_01(OpenColorIO_FOUND HAVE_OCIO)
715
715
716
set_package_properties(PythonLibrary PROPERTIES
716
set_package_properties(PythonLibrary PROPERTIES
717
    DESCRIPTION "Python Library"
717
    DESCRIPTION "Python Library"
(-)a/krita/data/shaders/highq_downscale.frag (-5 / +1 lines)
Lines 3-12 Link Here
3
 */
3
 */
4
uniform sampler2D texture0;
4
uniform sampler2D texture0;
5
5
6
#ifdef USE_OCIO
7
uniform sampler3D texture1;
8
#endif
9
10
in vec4 v_textureCoordinate;
6
in vec4 v_textureCoordinate;
11
out vec4 fragColor;
7
out vec4 fragColor;
12
8
Lines 119-125 void main() { Link Here
119
    }
115
    }
120
116
121
#ifdef USE_OCIO
117
#ifdef USE_OCIO
122
    fragColor = OCIODisplay(col, texture1);
118
    fragColor = OCIODisplay(col);
123
#else /* USE_OCIO */
119
#else /* USE_OCIO */
124
    fragColor = col;
120
    fragColor = col;
125
#endif /* USE_OCIO */
121
#endif /* USE_OCIO */
(-)a/libs/ui/canvas/kis_display_filter.h (-1 / +4 lines)
Lines 26-31 Link Here
26
26
27
struct KisExposureGammaCorrectionInterface;
27
struct KisExposureGammaCorrectionInterface;
28
28
29
class QOpenGLFunctions;
30
class QOpenGLShaderProgram;
31
29
/**
32
/**
30
 * @brief The KisDisplayFilter class is the base class for filters that
33
 * @brief The KisDisplayFilter class is the base class for filters that
31
 * are applied by the canvas to the projection before displaying.
34
 * are applied by the canvas to the projection before displaying.
Lines 37-43 public: Link Here
37
    explicit KisDisplayFilter(QObject *parent = 0);
40
    explicit KisDisplayFilter(QObject *parent = 0);
38
41
39
    virtual QString program() const = 0;
42
    virtual QString program() const = 0;
40
    virtual GLuint lutTexture() const = 0;
43
    virtual void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const = 0;
41
    virtual void filter(quint8 *pixels, quint32 numPixels) = 0;
44
    virtual void filter(quint8 *pixels, quint32 numPixels) = 0;
42
    virtual void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) = 0;
45
    virtual void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) = 0;
43
    virtual void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) = 0;
46
    virtual void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) = 0;
(-)a/libs/ui/opengl/kis_opengl_canvas2.cpp (-3 / +1 lines)
Lines 947-955 void KisOpenGLCanvas2::drawImage(const QRect &updateRect) Link Here
947
            }
947
            }
948
948
949
            if (d->displayFilter) {
949
            if (d->displayFilter) {
950
                glActiveTexture(GL_TEXTURE0 + 1);
950
                d->displayFilter->setupTextures(this, d->displayShader);
951
                glBindTexture(GL_TEXTURE_3D, d->displayFilter->lutTexture());
952
                d->displayShader->setUniformValue(d->displayShader->location(Uniform::Texture1), 1);
953
            }
951
            }
954
952
955
            glActiveTexture(GL_TEXTURE0);
953
            glActiveTexture(GL_TEXTURE0);
(-)a/libs/ui/opengl/kis_opengl_shader_loader.cpp (+1 lines)
Lines 150-155 KisShaderProgram *KisOpenGLShaderLoader::loadDisplayShader(QSharedPointer<KisDis Link Here
150
    bool haveDisplayFilter = displayFilter && !displayFilter->program().isEmpty();
150
    bool haveDisplayFilter = displayFilter && !displayFilter->program().isEmpty();
151
    if (haveDisplayFilter) {
151
    if (haveDisplayFilter) {
152
        fragHeader.append("#define USE_OCIO\n");
152
        fragHeader.append("#define USE_OCIO\n");
153
        fragHeader.append("#define USE_OCIO_V2\n");
153
        fragHeader.append(displayFilter->program().toLatin1());
154
        fragHeader.append(displayFilter->program().toLatin1());
154
    }
155
    }
155
156
(-)a/plugins/dockers/lut/CMakeLists.txt (-1 / +1 lines)
Lines 17-21 ki18n_wrap_ui(KRITA_LUTDOCKER_SOURCES Link Here
17
17
18
add_library(kritalutdocker MODULE ${KRITA_LUTDOCKER_SOURCES})
18
add_library(kritalutdocker MODULE ${KRITA_LUTDOCKER_SOURCES})
19
19
20
target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} ${OCIO_LIBRARIES})
20
target_link_libraries(kritalutdocker kritaui ${Boost_SYSTEM_LIBRARY} OpenColorIO::OpenColorIO)
21
install(TARGETS kritalutdocker  DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
21
install(TARGETS kritalutdocker  DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
(-)a/plugins/dockers/lut/lutdocker_dock.cpp (-3 / +5 lines)
Lines 56-67 Link Here
56
#include <KisSqueezedComboBox.h>
56
#include <KisSqueezedComboBox.h>
57
#include "kis_signals_blocker.h"
57
#include "kis_signals_blocker.h"
58
#include "krita_utils.h"
58
#include "krita_utils.h"
59
#include <KisOcioConfiguration.h>
59
60
60
#include "ocio_display_filter.h"
61
#include "black_white_point_chooser.h"
62
#include "KisOcioConfiguration.h"
63
#include <opengl/KisOpenGLModeProber.h>
61
#include <opengl/KisOpenGLModeProber.h>
64
62
63
#include "black_white_point_chooser.h"
64
65
65
66
OCIO::ConstConfigRcPtr defaultRawProfile()
66
OCIO::ConstConfigRcPtr defaultRawProfile()
67
{
67
{
Lines 231-236 void LutDockerDock::slotUpdateIcons() Link Here
231
{
231
{
232
    m_btnConvertCurrentColor->setIcon(KisIconUtils::loadIcon("krita_tool_freehand"));
232
    m_btnConvertCurrentColor->setIcon(KisIconUtils::loadIcon("krita_tool_freehand"));
233
    m_btmShowBWConfiguration->setIcon(KisIconUtils::loadIcon("properties"));
233
    m_btmShowBWConfiguration->setIcon(KisIconUtils::loadIcon("properties"));
234
    m_lblOcioVersion->setText(OCIO_VERSION_FULL_STR);
235
    m_lblOcioVersion->setEnabled(false);
234
}
236
}
235
237
236
void LutDockerDock::slotShowBWConfiguration()
238
void LutDockerDock::slotShowBWConfiguration()
(-)a/plugins/dockers/lut/ocio_display_filter.cpp (-119 / +328 lines)
Lines 1-38 Link Here
1
/*
1
/*
2
 *  Copyright (c) 2012 Boudewijn Rempt <boud@valdyas.org>
2
 *  SPDX-FileCopyrightText: 2012 Boudewijn Rempt <boud@valdyas.org>
3
 *  SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
3
 *
4
 *
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  SPDX-License-Identifier: GPL-2.0-or-later
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
 */
6
 */
7
18
#include "ocio_display_filter.h"
8
#include "ocio_display_filter.h"
19
#include <math.h>
9
20
#include <cstdlib>
10
#include <QOpenGLContext>
11
#include <QOpenGLExtraFunctions>
12
#include <QOpenGLFunctions_2_0>
13
#include <QOpenGLFunctions_3_0>
14
#include <QOpenGLFunctions_3_2_Core>
15
21
#include <cmath>
16
#include <cmath>
22
#include <cstdio>
23
#include <cstring>
17
#include <cstring>
24
#include <iostream>
25
#include <fstream>
26
#include <sstream>
27
18
28
#include <kis_config.h>
19
#include <kis_config.h>
29
20
#include <kis_debug.h>
30
#include <opengl/kis_opengl.h>
21
#include <opengl/kis_opengl.h>
31
#include <QOpenGLContext>
22
32
#include <QOpenGLFunctions_3_2_Core>
23
#if defined(QT_OPENGL_ES_2)
33
#include <QOpenGLFunctions_3_0>
24
#define GL_RGBA32F_ARB GL_RGBA32F_EXT
34
#include <QOpenGLFunctions_2_0>
25
#define GL_RGB32F_ARB GL_RGB32F_EXT
35
#include <QOpenGLExtraFunctions>
26
#endif
36
27
37
OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent)
28
OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent)
38
    : KisDisplayFilter(parent)
29
    : KisDisplayFilter(parent)
Lines 42-48 OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interf Link Here
42
    , look(0)
33
    , look(0)
43
    , swizzle(RGBA)
34
    , swizzle(RGBA)
44
    , m_interface(interface)
35
    , m_interface(interface)
45
    , m_lut3dTexID(0)
36
    , m_lut3dTexIDs()
37
    , m_lut3dUniforms()
46
    , m_shaderDirty(true)
38
    , m_shaderDirty(true)
47
{
39
{
48
}
40
}
Lines 51-57 OcioDisplayFilter::~OcioDisplayFilter() Link Here
51
{
43
{
52
}
44
}
53
45
54
KisExposureGammaCorrectionInterface* OcioDisplayFilter::correctionInterface() const
46
KisExposureGammaCorrectionInterface *OcioDisplayFilter::correctionInterface() const
55
{
47
{
56
    return m_interface;
48
    return m_interface;
57
}
49
}
Lines 60-67 void OcioDisplayFilter::filter(quint8 *pixels, quint32 numPixels) Link Here
60
{
52
{
61
    // processes that data _in_ place
53
    // processes that data _in_ place
62
    if (m_processor) {
54
    if (m_processor) {
63
        OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
55
        OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
64
        m_processor->apply(img);
56
        m_processor->getDefaultCPUProcessor()->apply(img);
65
    }
57
    }
66
}
58
}
67
59
Lines 69-76 void OcioDisplayFilter::approximateInverseTransformation(quint8 *pixels, quint32 Link Here
69
{
61
{
70
    // processes that data _in_ place
62
    // processes that data _in_ place
71
    if (m_revereseApproximationProcessor) {
63
    if (m_revereseApproximationProcessor) {
72
        OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
64
        OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
73
        m_revereseApproximationProcessor->apply(img);
65
        m_revereseApproximationProcessor->getDefaultCPUProcessor()->apply(img);
74
    }
66
    }
75
}
67
}
76
68
Lines 78-85 void OcioDisplayFilter::approximateForwardTransformation(quint8 *pixels, quint32 Link Here
78
{
70
{
79
    // processes that data _in_ place
71
    // processes that data _in_ place
80
    if (m_forwardApproximationProcessor) {
72
    if (m_forwardApproximationProcessor) {
81
        OCIO::PackedImageDesc img(reinterpret_cast<float*>(pixels), numPixels, 1, 4);
73
        OCIO::PackedImageDesc img(reinterpret_cast<float *>(pixels), numPixels, 1, 4);
82
        m_forwardApproximationProcessor->apply(img);
74
        m_forwardApproximationProcessor->getDefaultCPUProcessor()->apply(img);
83
    }
75
    }
84
}
76
}
85
77
Lines 103-113 QString OcioDisplayFilter::program() const Link Here
103
    return m_program;
95
    return m_program;
104
}
96
}
105
97
106
GLuint OcioDisplayFilter::lutTexture() const
107
{
108
    return m_lut3dTexID;
109
}
110
111
void OcioDisplayFilter::updateProcessor()
98
void OcioDisplayFilter::updateProcessor()
112
{
99
{
113
    if (!config) {
100
    if (!config) {
Lines 126-143 void OcioDisplayFilter::updateProcessor() Link Here
126
        inputColorSpaceName = config->getColorSpaceNameByIndex(0);
113
        inputColorSpaceName = config->getColorSpaceNameByIndex(0);
127
    }
114
    }
128
    if (!look) {
115
    if (!look) {
129
    look = config->getLookNameByIndex(0);
116
        look = config->getLookNameByIndex(0);
130
    }
117
    }
131
118
132
    if (!displayDevice || !view || !inputColorSpaceName) {
119
    if (!displayDevice || !view || !inputColorSpaceName) {
133
        return;
120
        return;
134
    }
121
    }
135
122
136
    OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
123
    OCIO::DisplayViewTransformRcPtr transform = OCIO::DisplayViewTransform::Create();
137
    transform->setInputColorSpaceName(inputColorSpaceName);
124
    transform->setSrc(inputColorSpaceName);
138
    transform->setDisplay(displayDevice);
125
    transform->setDisplay(displayDevice);
139
    transform->setView(view);
126
    transform->setView(view);
140
127
128
    OCIO::LegacyViewingPipelineRcPtr vpt = OCIO::LegacyViewingPipeline::Create();
129
130
    vpt->setDisplayViewTransform(transform);
131
141
    /**
132
    /**
142
     * Look support:
133
     * Look support:
143
     * As the OCIO docs will tell you, looks are a aesthetic transform that is
134
     * As the OCIO docs will tell you, looks are a aesthetic transform that is
Lines 155-190 void OcioDisplayFilter::updateProcessor() Link Here
155
     * override is all we can offer.
146
     * override is all we can offer.
156
     */
147
     */
157
    if (config->getLook(look)) {
148
    if (config->getLook(look)) {
158
       transform->setLooksOverride(look);
149
        vpt->setLooksOverride(look);
159
       transform->setLooksOverrideEnabled(true);
150
        vpt->setLooksOverrideEnabled(true);
160
    }
151
    }
161
152
162
    OCIO::GroupTransformRcPtr approximateTransform = OCIO::GroupTransform::Create();
153
    OCIO::GroupTransformRcPtr approximateTransform = OCIO::GroupTransform::Create();
163
154
164
    // fstop exposure control -- not sure how that translates to our exposure
155
    // fstop exposure control -- not sure how that translates to our exposure
165
    {
156
    {
166
        float exposureGain = powf(2.0f, exposure);
157
        const double exposureGain = pow(2.0, exposure);
167
158
168
        const qreal minRange = 0.001;
159
        const double minRange = 0.001;
169
        if (qAbs(blackPoint - whitePoint) < minRange) {
160
        if (qAbs(blackPoint - whitePoint) < minRange) {
170
            whitePoint = blackPoint + minRange;
161
            whitePoint = blackPoint + minRange;
171
        }
162
        }
172
163
173
        const float oldMin[] = { blackPoint, blackPoint, blackPoint, 0.0f };
164
        const double oldMin[] = {blackPoint, blackPoint, blackPoint, 0.0};
174
        const float oldMax[] = { whitePoint, whitePoint, whitePoint, 1.0f };
165
        const double oldMax[] = {whitePoint, whitePoint, whitePoint, 1.0};
175
166
176
        const float newMin[] = { 0.0f, 0.0f, 0.0f, 0.0f };
167
        const double newMin[] = {0.0, 0.0, 0.0, 0.0};
177
        const float newMax[] = { exposureGain, exposureGain, exposureGain, 1.0f };
168
        const double newMax[] = {exposureGain, exposureGain, exposureGain, 1.0};
178
169
179
        float m44[16];
170
        double m44[16];
180
        float offset4[4];
171
        double offset4[4];
181
        OCIO::MatrixTransform::Fit(m44, offset4, oldMin, oldMax, newMin, newMax);
172
        OCIO::MatrixTransform::Fit(m44, offset4, oldMin, oldMax, newMin, newMax);
182
        OCIO::MatrixTransformRcPtr mtx =  OCIO::MatrixTransform::Create();
173
        OCIO::MatrixTransformRcPtr mtx = OCIO::MatrixTransform::Create();
183
        mtx->setValue(m44, offset4);
174
        mtx->setMatrix(m44);
184
        transform->setLinearCC(mtx);
175
        mtx->setOffset(offset4);
176
        vpt->setLinearCC(mtx);
185
177
186
        // approximation (no color correction);
178
        // approximation (no color correction);
187
        approximateTransform->push_back(mtx);
179
        approximateTransform->appendTransform(mtx);
188
    }
180
    }
189
181
190
    // channel swizzle
182
    // channel swizzle
Lines 226-257 void OcioDisplayFilter::updateProcessor() Link Here
226
            channelHot[1] = 0;
218
            channelHot[1] = 0;
227
            channelHot[2] = 0;
219
            channelHot[2] = 0;
228
            channelHot[3] = 1;
220
            channelHot[3] = 1;
229
        default:
221
        default:;
230
            ;
231
        }
222
        }
232
        float lumacoef[3];
223
        double lumacoef[3];
233
        config->getDefaultLumaCoefs(lumacoef);
224
        config->getDefaultLumaCoefs(lumacoef);
234
        float m44[16];
225
        double m44[16];
235
        float offset[4];
226
        double offset[4];
236
        OCIO::MatrixTransform::View(m44, offset, channelHot, lumacoef);
227
        OCIO::MatrixTransform::View(m44, offset, channelHot, lumacoef);
237
        OCIO::MatrixTransformRcPtr swizzleTransform = OCIO::MatrixTransform::Create();
228
        OCIO::MatrixTransformRcPtr swizzleTransform = OCIO::MatrixTransform::Create();
238
        swizzleTransform->setValue(m44, offset);
229
        swizzleTransform->setMatrix(m44);
239
        transform->setChannelView(swizzleTransform);
230
        swizzleTransform->setOffset(offset);
231
        vpt->setChannelView(swizzleTransform);
240
    }
232
    }
241
233
242
    // Post-display transform gamma
234
    // Post-display transform gamma
243
    {
235
    {
244
        float exponent = 1.0f/std::max(1e-6f, static_cast<float>(gamma));
236
        double exponent = 1.0 / std::max(1e-6, gamma);
245
        const float exponent4f[] = { exponent, exponent, exponent, exponent };
237
        const double exponent4f[] = {exponent, exponent, exponent, exponent};
246
        OCIO::ExponentTransformRcPtr expTransform =  OCIO::ExponentTransform::Create();
238
        OCIO::ExponentTransformRcPtr expTransform = OCIO::ExponentTransform::Create();
247
        expTransform->setValue(exponent4f);
239
        expTransform->setValue(exponent4f);
248
        transform->setDisplayCC(expTransform);
240
        vpt->setDisplayCC(expTransform);
249
241
250
        // approximation (no color correction);
242
        // approximation (no color correction);
251
        approximateTransform->push_back(expTransform);
243
        approximateTransform->appendTransform(expTransform);
252
    }
244
    }
253
245
254
    m_processor = config->getProcessor(transform);
246
    try {
247
        m_processor = vpt->getProcessor(config, config->getCurrentContext());
248
    } catch (OCIO::Exception &e) {
249
        // XXX: How to not break the OCIO shader now?
250
        errKrita << "OCIO exception while parsing the current context:" << e.what();
251
        m_shaderDirty = false;
252
        return;
253
    }
255
254
256
    m_forwardApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_FORWARD);
255
    m_forwardApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_FORWARD);
257
256
Lines 259-265 void OcioDisplayFilter::updateProcessor() Link Here
259
        m_revereseApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_INVERSE);
258
        m_revereseApproximationProcessor = config->getProcessor(approximateTransform, OCIO::TRANSFORM_DIR_INVERSE);
260
    } catch (...) {
259
    } catch (...) {
261
        warnKrita << "OCIO inverted matrix does not exist!";
260
        warnKrita << "OCIO inverted matrix does not exist!";
262
        //m_revereseApproximationProcessor;
261
        // m_revereseApproximationProcessor;
263
    }
262
    }
264
263
265
    m_shaderDirty = true;
264
    m_shaderDirty = true;
Lines 272-287 bool OcioDisplayFilter::updateShader() Link Here
272
        if (f) {
271
        if (f) {
273
            return updateShaderImpl(f);
272
            return updateShaderImpl(f);
274
        }
273
        }
274
#if defined(QT_OPENGL_3)
275
    } else if (KisOpenGL::hasOpenGL3()) {
275
    } else if (KisOpenGL::hasOpenGL3()) {
276
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
276
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
277
        if (f) {
277
        if (f) {
278
            return updateShaderImpl(f);
278
            return updateShaderImpl(f);
279
        }
279
        }
280
#endif
280
    }
281
    }
281
282
282
    // XXX This option can be removed once we move to Qt 5.7+
283
    // XXX This option can be removed once we move to Qt 5.7+
283
    if (KisOpenGL::supportsLoD()) {
284
    if (KisOpenGL::supportsLoD()) {
284
#ifdef Q_OS_MAC
285
#if defined(QT_OPENGL_3)
286
#if defined(Q_OS_MAC) && defined(QT_OPENGL_3_2)
285
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
287
        QOpenGLFunctions_3_2_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
286
#else
288
#else
287
        QOpenGLFunctions_3_0 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_0>();
289
        QOpenGLFunctions_3_0 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_0>();
Lines 289-311 bool OcioDisplayFilter::updateShader() Link Here
289
        if (f) {
291
        if (f) {
290
            return updateShaderImpl(f);
292
            return updateShaderImpl(f);
291
        }
293
        }
294
#endif
292
    }
295
    }
293
    QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
296
#if !defined(QT_OPENGL_ES_2)
297
    QOpenGLFunctions_2_0 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_2_0>();
294
    if (f) {
298
    if (f) {
295
        return updateShaderImpl(f);
299
        return updateShaderImpl(f);
296
    }
300
    }
301
#endif
297
302
298
    return false;
303
    return false;
299
}
304
}
300
305
301
template <class F>
306
template<class F>
302
bool OcioDisplayFilter::updateShaderImpl(F *f) {
307
bool OcioDisplayFilter::updateShaderImpl(F *f)
308
{
303
    // check whether we are allowed to use shaders -- though that should
309
    // check whether we are allowed to use shaders -- though that should
304
    // work for everyone these days
310
    // work for everyone these days
305
    KisConfig cfg(true);
311
    KisConfig cfg(true);
306
    if (!cfg.useOpenGL()) return false;
312
    if (!cfg.useOpenGL())
313
        return false;
307
314
308
    if (!m_shaderDirty) return false;
315
    if (!m_shaderDirty)
316
        return false;
309
317
310
    if (!f) {
318
    if (!f) {
311
        qWarning() << "Failed to get valid OpenGL functions for OcioDisplayFilter!";
319
        qWarning() << "Failed to get valid OpenGL functions for OcioDisplayFilter!";
Lines 316-386 bool OcioDisplayFilter::updateShaderImpl(F *f) { Link Here
316
324
317
    bool shouldRecompileShader = false;
325
    bool shouldRecompileShader = false;
318
326
319
    const int lut3DEdgeSize = cfg.ocioLutEdgeSize();
327
    // Step 1: Create a GPU Shader Description
328
    OCIO::GpuShaderDescRcPtr shaderDesc = OCIO::GpuShaderDesc::CreateShaderDesc();
320
329
321
    if (m_lut3d.size() == 0) {
330
#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
322
        //dbgKrita << "generating lut";
331
    if (KisOpenGL::supportsLoD()) {
323
        f->glGenTextures(1, &m_lut3dTexID);
332
        shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_3_0);
333
    } else {
334
        shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_ES_1_0);
335
    }
336
#else
337
    if (KisOpenGL::supportsLoD()) {
338
        shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
339
    } else {
340
        shaderDesc->setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_2);
341
    }
342
#endif
324
343
325
        int num3Dentries = 3 * lut3DEdgeSize * lut3DEdgeSize * lut3DEdgeSize;
344
    shaderDesc->setFunctionName("OCIODisplay");
326
        m_lut3d.fill(0.0, num3Dentries);
345
    shaderDesc->setResourcePrefix("ocio_");
327
346
328
        f->glActiveTexture(GL_TEXTURE1);
347
    // Step 2: Compute the 3D LUT
329
        f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID);
348
#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
349
    // ensure the new GPU pipeline is used with our GLES3 patch
350
    // this way users won't run into errors when using Angle along with OCIO
351
    const auto gpu = m_processor->getOptimizedGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT);
352
#else
353
    const int lut3DEdgeSize = cfg.ocioLutEdgeSize();
354
    const auto gpu =
355
        m_processor->getOptimizedLegacyGPUProcessor(OCIO::OptimizationFlags::OPTIMIZATION_DEFAULT, lut3DEdgeSize);
356
#endif
330
357
331
        f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
358
    gpu->extractGpuShaderInfo(shaderDesc);
332
        f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
359
333
        f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
360
    // OCIO v2 assumes you'll use the OglApp helpers
334
        f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
361
    // these are unusable from a Qt backend, because they rely on GLUT/GLFW
335
        f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
362
    // ociodisplay original pipeline:
336
        f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
363
    // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/508b3f4a0618435aeed2f45058208bdfa99e0887/src/apps/ociodisplay/main.cpp
337
                        lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize,
364
    // ociodisplay new pipeline is a single call:
338
                        0, GL_RGB, GL_FLOAT, &m_lut3d.constData()[0]);
365
    // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/ffddc3341f5775c7866fe2c93275e1d5e0b0540f/src/apps/ociodisplay/main.cpp#L427
366
    // we need to replicate this loop:
367
    // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/oglapp.cpp#L191-L223
368
    // calls functions from here:
369
    // https://github.com/AcademySoftwareFoundation/OpenColorIO/blob/dd59baf555656e09f52c3838e85ccf154497ec1d/src/libutils/oglapphelpers/glsl.cpp
370
371
    for (const auto &tex : m_lut3dTexIDs) {
372
        f->glDeleteTextures(1, &tex.m_uid);
339
    }
373
    }
340
374
341
    // Step 1: Create a GPU Shader Description
375
    m_lut3dTexIDs.clear();
342
    OCIO::GpuShaderDesc shaderDesc;
343
376
344
    if (KisOpenGL::supportsLoD()) {
377
    // This is the first available index for the textures.
345
        shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_3);
378
    unsigned currIndex = 1;
346
    }
379
347
    else {
380
    // Process the 3D LUT first.
348
        shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
381
382
    const unsigned maxTexture3D = shaderDesc->getNum3DTextures();
383
    for (unsigned idx = 0; idx < maxTexture3D; ++idx) {
384
        // 1. Get the information of the 3D LUT.
385
386
        const char *textureName = nullptr;
387
        const char *samplerName = nullptr;
388
        unsigned edgelen = 0;
389
        OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
390
        shaderDesc->get3DTexture(idx, textureName, samplerName, edgelen, interpolation);
391
392
        if (!textureName || !*textureName || !samplerName || !*samplerName || edgelen == 0) {
393
            errOpenGL << "The texture data is corrupted";
394
            return false;
395
        }
396
397
        const float *values = nullptr;
398
        shaderDesc->get3DTextureValues(idx, values);
399
        if (!values) {
400
            errOpenGL << "The texture values are missing";
401
            return false;
402
        }
403
404
        // 2. Allocate the 3D LUT.
405
406
        unsigned texId = 0;
407
        {
408
            if (values == nullptr) {
409
                errOpenGL << "3D LUT" << idx << "Missing texture data";
410
                return false;
411
            }
412
413
            f->glGenTextures(1, &texId);
414
415
            f->glActiveTexture(GL_TEXTURE0 + currIndex);
416
417
            f->glBindTexture(GL_TEXTURE_3D, texId);
418
419
            {
420
                if (interpolation == OCIO::INTERP_NEAREST) {
421
                    f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
422
                    f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
423
                } else {
424
                    f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
425
                    f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
426
                }
427
428
                f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
429
                f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
430
                f->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
431
            }
432
433
            f->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB32F_ARB, edgelen, edgelen, edgelen, 0, GL_RGB, GL_FLOAT, values);
434
        }
435
436
        // 3. Keep the texture id & name for the later enabling.
437
438
        m_lut3dTexIDs.push_back({texId, textureName, samplerName, GL_TEXTURE_3D});
439
440
        currIndex++;
349
    }
441
    }
350
442
443
    // Process the 1D LUTs.
351
444
352
    shaderDesc.setFunctionName("OCIODisplay");
445
    const unsigned maxTexture2D = shaderDesc->getNumTextures();
353
    shaderDesc.setLut3DEdgeLen(lut3DEdgeSize);
446
    for (unsigned idx = 0; idx < maxTexture2D; ++idx) {
447
        // 1. Get the information of the 1D LUT.
354
448
449
        const char *textureName = nullptr;
450
        const char *samplerName = nullptr;
451
        unsigned width = 0;
452
        unsigned height = 0;
453
        OCIO::GpuShaderDesc::TextureType channel = OCIO::GpuShaderDesc::TEXTURE_RGB_CHANNEL;
454
        OCIO::Interpolation interpolation = OCIO::INTERP_LINEAR;
455
        shaderDesc->getTexture(idx, textureName, samplerName, width, height, channel, interpolation);
355
456
356
    // Step 2: Compute the 3D LUT
457
        if (!textureName || !*textureName || !samplerName || !*samplerName || width == 0) {
357
    QString lut3dCacheID = QString::fromLatin1(m_processor->getGpuLut3DCacheID(shaderDesc));
458
            errOpenGL << "The texture data is corrupted";
358
    if (lut3dCacheID != m_lut3dcacheid) {
459
            return false;
359
        //dbgKrita << "Computing 3DLut " << m_lut3dcacheid;
460
        }
360
        m_lut3dcacheid = lut3dCacheID;
461
361
        m_processor->getGpuLut3D(&m_lut3d[0], shaderDesc);
462
        const float *values = nullptr;
362
463
        shaderDesc->getTextureValues(idx, values);
363
        f->glBindTexture(GL_TEXTURE_3D, m_lut3dTexID);
464
        if (!values) {
364
        f->glTexSubImage3D(GL_TEXTURE_3D, 0,
465
            errOpenGL << "The texture values are missing";
365
                                  0, 0, 0,
466
            return false;
366
                                  lut3DEdgeSize, lut3DEdgeSize, lut3DEdgeSize,
467
        }
367
                                  GL_RGB, GL_FLOAT, &m_lut3d[0]);
468
469
        // 2. Allocate the 1D LUT (a 2D texture is needed to hold large LUTs).
470
471
        unsigned texId = 0;
472
        {
473
            if (values == nullptr) {
474
                errOpenGL << "1D LUT" << idx << "Missing texture data.";
475
                return false;
476
            }
477
478
            unsigned internalformat = GL_RGB32F_ARB;
479
            unsigned format = GL_RGB;
480
481
            if (channel == OCIO::GpuShaderCreator::TEXTURE_RED_CHANNEL) {
482
                internalformat = GL_R32F;
483
                format = GL_RED;
484
            }
485
486
            f->glGenTextures(1, &texId);
487
488
            f->glActiveTexture(GL_TEXTURE0 + currIndex);
489
490
#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
491
#else
492
            // 1D Textures are unsupported by OpenGL ES.
493
            // https://github.com/AcademySoftwareFoundation/OpenColorIO/issues/1486
494
            if (height > 1) {
495
#endif
496
                f->glBindTexture(GL_TEXTURE_2D, texId);
497
498
                {
499
                    if (interpolation == OCIO::INTERP_NEAREST) {
500
                        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
501
                        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
502
                    } else {
503
                        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
504
                        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
505
                    }
506
507
                    f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
508
                    f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
509
                    f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
510
                }
511
512
                f->glTexImage2D(GL_TEXTURE_2D, 0, internalformat, width, height, 0, format, GL_FLOAT, values);
513
#if OCIO_VERSION_HEX >= 0x2010100 || OCIO_VERSION_HEX >= 0x2020000
514
#else
515
            } else {
516
                errOpenGL << "1D texture detected @" << idx << ", not supported by OpenGLES";
517
                return false;
518
            }
519
#endif
520
        }
521
522
        // 3. Keep the texture id & name for the later enabling.
523
524
        unsigned type = GL_TEXTURE_2D;
525
        m_lut3dTexIDs.push_back({texId, textureName, samplerName, type});
526
        currIndex++;
368
    }
527
    }
369
528
370
    // Step 3: Generate the shader text
529
    // Step 3: Generate the shader text
371
    QString shaderCacheID = QString::fromLatin1(m_processor->getGpuShaderTextCacheID(shaderDesc));
530
    QString shaderCacheID = QString::fromLatin1(shaderDesc->getCacheID());
372
    if (m_program.isEmpty() || shaderCacheID != m_shadercacheid) {
531
    if (m_program.isEmpty() || shaderCacheID != m_shadercacheid) {
373
        //dbgKrita << "Computing Shader " << m_shadercacheid;
532
        // dbgKrita << "Computing Shader " << m_shadercacheid;
374
533
375
        m_shadercacheid = shaderCacheID;
534
        m_shadercacheid = shaderCacheID;
376
535
377
        std::ostringstream os;
536
        m_program = QString::fromLatin1("%1\n").arg(shaderDesc->getShaderText());
378
        os << m_processor->getGpuShaderText(shaderDesc) << "\n";
379
380
        m_program = QString::fromLatin1(os.str().c_str());
381
        shouldRecompileShader = true;
537
        shouldRecompileShader = true;
382
    }
538
    }
383
539
540
    // Step 4: mirror and bind uniforms
541
    m_lut3dUniforms.clear();
542
543
    const unsigned maxUniforms = shaderDesc->getNumUniforms();
544
    for (unsigned idx = 0; idx < maxUniforms; ++idx) {
545
        OCIO::GpuShaderDesc::UniformData data;
546
        const char *name = shaderDesc->getUniform(idx, data);
547
        if (data.m_type == OCIO::UNIFORM_UNKNOWN) {
548
            errOpenGL << "Uniform" << idx << "has an unknown type";
549
            return false;
550
        }
551
        // Transfer uniform.
552
        m_lut3dUniforms.push_back({name, data});
553
    }
554
384
    m_shaderDirty = false;
555
    m_shaderDirty = false;
385
    return shouldRecompileShader;
556
    return shouldRecompileShader;
386
}
557
}
558
559
void OcioDisplayFilter::setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const
560
{
561
    for (unsigned int idx = 0; idx < m_lut3dTexIDs.size(); ++idx) {
562
        const auto &data = m_lut3dTexIDs[idx];
563
        f->glActiveTexture(GL_TEXTURE0 + 1 + idx);
564
        f->glBindTexture(data.m_type, data.m_uid);
565
        program->setUniformValue(program->uniformLocation(data.m_samplerName), GLint(1 + idx));
566
    }
567
568
    for (const KisTextureUniform &uniform : m_lut3dUniforms) {
569
        const int m_handle = program->uniformLocation(uniform.m_name);
570
571
        const OCIO::GpuShaderDesc::UniformData &m_data = uniform.m_data;
572
573
        // Update value.
574
        if (m_data.m_getDouble) {
575
            program->setUniformValue(m_handle, static_cast<const GLfloat>(m_data.m_getDouble()));
576
        } else if (m_data.m_getBool) {
577
            program->setUniformValue(m_handle, static_cast<const GLfloat>(m_data.m_getBool() ? 1.0f : 0.0f));
578
        } else if (m_data.m_getFloat3) {
579
            program->setUniformValue(m_handle,
580
                                     m_data.m_getFloat3()[0],
581
                                     m_data.m_getFloat3()[1],
582
                                     m_data.m_getFloat3()[2]);
583
        } else if (m_data.m_vectorFloat.m_getSize && m_data.m_vectorFloat.m_getVector) {
584
            program->setUniformValueArray(m_handle,
585
                                          m_data.m_vectorFloat.m_getVector(),
586
                                          m_data.m_vectorFloat.m_getSize(),
587
                                          1);
588
        } else if (m_data.m_vectorInt.m_getSize && m_data.m_vectorInt.m_getVector) {
589
            program->setUniformValueArray(m_handle, m_data.m_vectorInt.m_getVector(), m_data.m_vectorInt.m_getSize());
590
        } else {
591
            errOpenGL << "Uniform" << uniform.m_name << "is not linked to any value";
592
            continue;
593
        }
594
    }
595
}
(-)a/plugins/dockers/lut/ocio_display_filter.h (-42 / +61 lines)
Lines 1-38 Link Here
1
/*
1
/*
2
 *  Copyright (c) 2012 Boudewijn Rempt <boud@valdyas.org>
2
 *  SPDX-FileCopyrightText: 2012 Boudewijn Rempt <boud@valdyas.org>
3
 *  SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
3
 *
4
 *
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  SPDX-License-Identifier: GPL-2.0-or-later
5
 *  it under the terms of the GNU General Public License as published by
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
 */
6
 */
7
18
#ifndef OCIO_DISPLAY_FILTER_H
8
#ifndef OCIO_DISPLAY_FILTER_H
19
#define OCIO_DISPLAY_FILTER_H
9
#define OCIO_DISPLAY_FILTER_H
20
10
11
#include <vector>
12
13
#include <QOpenGLShaderProgram>
14
15
#include <OpenColorIO.h>
16
#include <OpenColorTransforms.h>
17
#include <OpenColorTypes.h>
18
21
#include <kis_display_filter.h>
19
#include <kis_display_filter.h>
22
#include <OpenColorIO/OpenColorIO.h>
20
#include <kis_exposure_gamma_correction_interface.h>
23
#include <OpenColorIO/OpenColorTransforms.h>
24
#include <QVector>
25
#include "kis_exposure_gamma_correction_interface.h"
26
21
27
namespace OCIO = OCIO_NAMESPACE;
22
namespace OCIO = OCIO_NAMESPACE;
28
23
29
enum OCIO_CHANNEL_SWIZZLE {
24
enum OCIO_CHANNEL_SWIZZLE { LUMINANCE, RGBA, R, G, B, A };
30
    LUMINANCE,
25
31
    RGBA,
26
struct KisTextureUniform {
32
    R,
27
public:
33
    G,
28
    KisTextureUniform(const QString &name, const OCIO::GpuShaderDesc::UniformData &data)
34
    B,
29
        : m_name(name)
35
    A
30
        , m_data(data)
31
    {
32
    }
33
34
    QString m_name;
35
    OCIO::GpuShaderDesc::UniformData m_data;
36
37
private:
38
    KisTextureUniform() = delete;
39
};
40
41
struct KisTextureEntry {
42
    unsigned m_uid = -1;
43
    QString m_textureName;
44
    QString m_samplerName;
45
    unsigned m_type = -1;
46
47
    KisTextureEntry(unsigned uid, const QString &textureName, const QString &samplerName, unsigned type)
48
        : m_uid(uid)
49
        , m_textureName(textureName)
50
        , m_samplerName(samplerName)
51
        , m_type(type)
52
    {
53
    }
36
};
54
};
37
55
38
class OcioDisplayFilter : public KisDisplayFilter
56
class OcioDisplayFilter : public KisDisplayFilter
Lines 42-62 public: Link Here
42
    explicit OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent = 0);
60
    explicit OcioDisplayFilter(KisExposureGammaCorrectionInterface *interface, QObject *parent = 0);
43
    ~OcioDisplayFilter();
61
    ~OcioDisplayFilter();
44
62
45
    void filter(quint8 *pixels, quint32 numPixels);
63
    void filter(quint8 *pixels, quint32 numPixels) override;
46
    void approximateInverseTransformation(quint8 *pixels, quint32 numPixels);
64
    void approximateInverseTransformation(quint8 *pixels, quint32 numPixels) override;
47
    void approximateForwardTransformation(quint8 *pixels, quint32 numPixels);
65
    void approximateForwardTransformation(quint8 *pixels, quint32 numPixels) override;
48
    bool useInternalColorManagement() const;
66
    bool useInternalColorManagement() const override;
49
    bool lockCurrentColorVisualRepresentation() const;
67
    bool lockCurrentColorVisualRepresentation() const override;
50
    void setLockCurrentColorVisualRepresentation(bool value);
68
    void setLockCurrentColorVisualRepresentation(bool value);
51
69
52
    bool updateShader();
70
    bool updateShader() override;
53
    template <class F>
71
72
    template<class F>
54
    bool updateShaderImpl(F *f);
73
    bool updateShaderImpl(F *f);
55
74
56
    KisExposureGammaCorrectionInterface *correctionInterface() const;
75
    void setupTextures(QOpenGLFunctions *f, QOpenGLShaderProgram *program) const override;
57
76
58
    virtual QString program() const;
77
    KisExposureGammaCorrectionInterface *correctionInterface() const override;
59
    GLuint lutTexture() const;
78
79
    QString program() const override;
60
80
61
    void updateProcessor();
81
    void updateProcessor();
62
82
Lines 67-80 public: Link Here
67
    const char *view;
87
    const char *view;
68
    const char *look;
88
    const char *look;
69
    OCIO_CHANNEL_SWIZZLE swizzle;
89
    OCIO_CHANNEL_SWIZZLE swizzle;
70
    float exposure;
90
    double exposure;
71
    float gamma;
91
    double gamma;
72
    float blackPoint;
92
    double blackPoint;
73
    float whitePoint;
93
    double whitePoint;
74
    bool forceInternalColorManagement;
94
    bool forceInternalColorManagement;
75
95
76
private:
96
private:
77
78
    OCIO::ConstProcessorRcPtr m_processor;
97
    OCIO::ConstProcessorRcPtr m_processor;
79
    OCIO::ConstProcessorRcPtr m_revereseApproximationProcessor;
98
    OCIO::ConstProcessorRcPtr m_revereseApproximationProcessor;
80
    OCIO::ConstProcessorRcPtr m_forwardApproximationProcessor;
99
    OCIO::ConstProcessorRcPtr m_forwardApproximationProcessor;
Lines 84-93 private: Link Here
84
    bool m_lockCurrentColorVisualRepresentation;
103
    bool m_lockCurrentColorVisualRepresentation;
85
104
86
    QString m_program;
105
    QString m_program;
87
    GLuint m_lut3dTexID;
106
    std::vector<KisTextureEntry> m_lut3dTexIDs;
88
    QVector<float> m_lut3d;
89
    QString m_lut3dcacheid;
107
    QString m_lut3dcacheid;
90
    QString m_shadercacheid;
108
    QString m_shadercacheid;
109
    std::vector<KisTextureUniform> m_lut3dUniforms;
91
110
92
    bool m_shaderDirty;
111
    bool m_shaderDirty;
93
};
112
};
(-)a/plugins/dockers/lut/tests/CMakeLists.txt (-1 / +1 lines)
Lines 11-15 krita_add_broken_unit_test(kis_ocio_display_filter_test.cpp Link Here
11
    ../ocio_display_filter.cpp  
11
    ../ocio_display_filter.cpp  
12
    ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp
12
    ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp
13
    TEST_NAME KisOcioDisplayFilterTest
13
    TEST_NAME KisOcioDisplayFilterTest
14
    LINK_LIBRARIES kritaui ${OCIO_LIBRARIES} KF5::I18n Qt5::Test
14
    LINK_LIBRARIES kritaui OpenColorIO::OpenColorIO KF5::I18n Qt5::Test
15
    NAME_PREFIX "plugins-dockers-lut-")
15
    NAME_PREFIX "plugins-dockers-lut-")
(-)a/plugins/dockers/lut/wdglut.ui (-2 / +9 lines)
Lines 7-13 Link Here
7
    <x>0</x>
7
    <x>0</x>
8
    <y>0</y>
8
    <y>0</y>
9
    <width>357</width>
9
    <width>357</width>
10
    <height>286</height>
10
    <height>328</height>
11
   </rect>
11
   </rect>
12
  </property>
12
  </property>
13
  <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
13
  <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
Lines 338-344 Link Here
338
       </layout>
338
       </layout>
339
      </item>
339
      </item>
340
      <item>
340
      <item>
341
       <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0">
341
       <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0">
342
        <property name="spacing">
342
        <property name="spacing">
343
         <number>2</number>
343
         <number>2</number>
344
        </property>
344
        </property>
Lines 348-353 Link Here
348
        <property name="rightMargin">
348
        <property name="rightMargin">
349
         <number>2</number>
349
         <number>2</number>
350
        </property>
350
        </property>
351
        <item>
352
         <widget class="QLabel" name="m_lblOcioVersion">
353
          <property name="text">
354
           <string>TextLabel</string>
355
          </property>
356
         </widget>
357
        </item>
351
        <item>
358
        <item>
352
         <spacer name="horizontalSpacer">
359
         <spacer name="horizontalSpacer">
353
          <property name="orientation">
360
          <property name="orientation">
(-)a/cmake/modules/FindOpenColorIO.cmake (+104 lines)
Line 0 Link Here
1
# Module to find OpenColorIO
2
#
3
# This module will first look into the directories hinted by the variables:
4
#   - OpenColorIO_ROOT
5
#
6
# This module defines the following variables:
7
#
8
# OPENCOLORIO_FOUND       - True if OpenColorIO was found.
9
# OPENCOLORIO_INCLUDES    - where to find OpenColorIO.h
10
# OPENCOLORIO_LIBRARIES   - list of libraries to link against when using OpenColorIO
11
# OPENCOLORIO_DEFINITIONS - Definitions needed when using OpenColorIO
12
#
13
# SPDX-FileCopyrightText: 2008 Contributors to the OpenImageIO project
14
# SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
15
# SPDX-License-Identifier: BSD-3-Clause
16
17
include (FindPackageHandleStandardArgs)
18
include (FindPackageMessage)
19
20
find_path (OPENCOLORIO_INCLUDE_DIR
21
    OpenColorIO.h
22
    HINTS
23
        ${OPENCOLORIO_INCLUDE_PATH}
24
        ENV OPENCOLORIO_INCLUDE_PATH
25
    PATHS
26
        /sw/include
27
        /opt/local/include
28
    PATH_SUFFIXES OpenColorIO OpenColorIO1
29
    DOC "The directory where OpenColorIO.h resides")
30
31
if (EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h")
32
    # Search twice, because this symbol changed between OCIO 1.x and 2.x
33
    file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP
34
         REGEX "^#define OCIO_VERSION_STR[ \t].*$")
35
    if (NOT TMP)
36
        file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorABI.h" TMP
37
             REGEX "^#define OCIO_VERSION[ \t].*$")
38
    endif ()
39
    string (REGEX MATCHALL "([0-9]+)\\.([0-9]+)\\.[0-9]+" OPENCOLORIO_VERSION ${TMP})
40
    set (OPENCOLORIO_VERSION_MAJOR ${CMAKE_MATCH_1})
41
    set (OPENCOLORIO_VERSION_MINOR ${CMAKE_MATCH_2})
42
endif ()
43
44
find_library (OPENCOLORIO_LIBRARY
45
    NAMES
46
        OpenColorIO
47
        OpenColorIO_${OPENCOLORIO_VERSION_MAJOR}_${OPENCOLORIO_VERSION_MINOR}
48
        OpenColorIO${OPENCOLORIO_VERSION_MAJOR}
49
    HINTS
50
        ${OPENCOLORIO_LIBRARY_PATH}
51
        ENV OPENCOLORIO_LIBRARY_PATH
52
    PATHS
53
        /usr/lib64
54
        /usr/local/lib64
55
        /sw/lib
56
        /opt/local/lib
57
    DOC "The OCIO library")
58
59
find_package_handle_standard_args (OpenColorIO
60
    REQUIRED_VARS   OPENCOLORIO_INCLUDE_DIR OPENCOLORIO_LIBRARY
61
    FOUND_VAR       OPENCOLORIO_FOUND
62
    VERSION_VAR     OPENCOLORIO_VERSION
63
    )
64
65
if (OpenColorIO_FOUND)
66
    set (OPENCOLORIO_INCLUDES ${OPENCOLORIO_INCLUDE_DIR})
67
    set (OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARY})
68
    set (OPENCOLORIO_DEFINITIONS "")
69
    if (NOT TARGET OpenColorIO::OpenColorIO)
70
        add_library(OpenColorIO::OpenColorIO UNKNOWN IMPORTED)
71
        set_target_properties(OpenColorIO::OpenColorIO PROPERTIES
72
            INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}")
73
74
        set_property(TARGET OpenColorIO::OpenColorIO APPEND PROPERTY
75
            IMPORTED_LOCATION "${OPENCOLORIO_LIBRARIES}")
76
        if (LINKSTATIC)
77
            target_compile_definitions(OpenColorIO::OpenColorIO
78
                INTERFACE "-DOpenColorIO_STATIC")
79
        endif()
80
    endif ()
81
    if (NOT TARGET OpenColorIO::OpenColorIOHeaders)
82
        add_library(OpenColorIO::OpenColorIOHeaders INTERFACE IMPORTED)
83
        set_target_properties(OpenColorIO::OpenColorIOHeaders PROPERTIES
84
            INTERFACE_INCLUDE_DIRECTORIES "${OPENCOLORIO_INCLUDES}")
85
    endif ()
86
endif ()
87
88
if (OpenColorIO_FOUND AND LINKSTATIC)
89
    # Is this necessary?
90
    set (OPENCOLORIO_DEFINITIONS "-DOpenColorIO_STATIC")
91
    find_library (TINYXML_LIBRARY NAMES tinyxml)
92
    if (TINYXML_LIBRARY)
93
        set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${TINYXML_LIBRARY}" CACHE STRING "" FORCE)
94
    endif ()
95
    find_library (YAML_LIBRARY NAMES yaml-cpp)
96
    if (YAML_LIBRARY)
97
        set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${YAML_LIBRARY}" CACHE STRING "" FORCE)
98
    endif ()
99
    find_library (LCMS2_LIBRARY NAMES lcms2)
100
    if (LCMS2_LIBRARY)
101
        set (OPENCOLORIO_LIBRARIES "${OPENCOLORIO_LIBRARIES};${LCMS2_LIBRARY}" CACHE STRING "" FORCE)
102
    endif ()
103
endif ()
104

Return to bug 821244