diff --git a/kcmkwin/kwincompositing/compositing.h b/kcmkwin/kwincompositing/compositing.h --- a/kcmkwin/kwincompositing/compositing.h +++ b/kcmkwin/kwincompositing/compositing.h @@ -41,7 +41,6 @@ Q_PROPERTY(int glScaleFilter READ glScaleFilter WRITE setGlScaleFilter NOTIFY glScaleFilterChanged) Q_PROPERTY(bool xrScaleFilter READ xrScaleFilter WRITE setXrScaleFilter NOTIFY xrScaleFilterChanged) Q_PROPERTY(int glSwapStrategy READ glSwapStrategy WRITE setGlSwapStrategy NOTIFY glSwapStrategyChanged) - Q_PROPERTY(bool glColorCorrection READ glColorCorrection WRITE setGlColorCorrection NOTIFY glColorCorrectionChanged) Q_PROPERTY(int compositingType READ compositingType WRITE setCompositingType NOTIFY compositingTypeChanged) Q_PROPERTY(bool compositingEnabled READ compositingEnabled WRITE setCompositingEnabled NOTIFY compositingEnabledChanged) Q_PROPERTY(KWin::Compositing::OpenGLPlatformInterfaceModel *openGLPlatformInterfaceModel READ openGLPlatformInterfaceModel CONSTANT) @@ -59,7 +58,6 @@ int glScaleFilter() const; bool xrScaleFilter() const; int glSwapStrategy() const; - bool glColorCorrection() const; int compositingType() const; bool compositingEnabled() const; int openGLPlatformInterface() const; @@ -73,7 +71,6 @@ void setGlScaleFilter(int index); void setXrScaleFilter(bool filter); void setGlSwapStrategy(int strategy); - void setGlColorCorrection(bool correction); void setCompositingType(int index); void setCompositingEnabled(bool enalbed); void setOpenGLPlatformInterface(int interface); @@ -92,7 +89,6 @@ void glScaleFilterChanged(int); void xrScaleFilterChanged(int); void glSwapStrategyChanged(int); - void glColorCorrectionChanged(bool); void compositingTypeChanged(int); void compositingEnabledChanged(bool); void openGLPlatformInterfaceChanged(int); @@ -104,7 +100,6 @@ int m_glScaleFilter; bool m_xrScaleFilter; int m_glSwapStrategy; - bool m_glColorCorrection; int m_compositingType; bool m_compositingEnabled; bool m_changed; diff --git a/kcmkwin/kwincompositing/compositing.cpp b/kcmkwin/kwincompositing/compositing.cpp --- a/kcmkwin/kwincompositing/compositing.cpp +++ b/kcmkwin/kwincompositing/compositing.cpp @@ -42,7 +42,6 @@ , m_glScaleFilter(0) , m_xrScaleFilter(false) , m_glSwapStrategy(0) - , m_glColorCorrection(false) , m_compositingType(0) , m_compositingEnabled(true) , m_changed(false) @@ -57,7 +56,6 @@ connect(this, &Compositing::glScaleFilterChanged, this, &Compositing::changed); connect(this, &Compositing::xrScaleFilterChanged, this, &Compositing::changed); connect(this, &Compositing::glSwapStrategyChanged, this, &Compositing::changed); - connect(this, &Compositing::glColorCorrectionChanged, this, &Compositing::changed); connect(this, &Compositing::compositingTypeChanged, this, &Compositing::changed); connect(this, &Compositing::compositingEnabledChanged, this, &Compositing::changed); connect(this, &Compositing::openGLPlatformInterfaceChanged, this, &Compositing::changed); @@ -94,7 +92,6 @@ return 0; }; setGlSwapStrategy(swapStrategy()); - setGlColorCorrection(kwinConfig.readEntry("GLColorCorrection", false)); auto type = [&kwinConfig]{ const QString backend = kwinConfig.readEntry("Backend", "OpenGL"); @@ -127,7 +124,6 @@ setGlScaleFilter(2); setXrScaleFilter(false); setGlSwapStrategy(1); - setGlColorCorrection(false); setCompositingType(CompositingType::OPENGL20_INDEX); const QModelIndex index = m_openGLPlatformInterfaceModel->indexForKey(QStringLiteral("glx")); setOpenGLPlatformInterface(index.isValid() ? index.row() : 0); @@ -192,11 +188,6 @@ return m_glSwapStrategy; } -bool Compositing::glColorCorrection() const -{ - return m_glColorCorrection; -} - int Compositing::compositingType() const { return m_compositingType; @@ -216,15 +207,6 @@ emit animationSpeedChanged(speed); } -void Compositing::setGlColorCorrection(bool correction) -{ - if (correction == m_glColorCorrection) { - return; - } - m_glColorCorrection = correction; - emit glColorCorrectionChanged(correction); -} - void Compositing::setGlScaleFilter(int index) { if (index == m_glScaleFilter) { @@ -309,7 +291,6 @@ } }; kwinConfig.writeEntry("GLPreferBufferSwap", swapStrategy()); - kwinConfig.writeEntry("GLColorCorrection", glColorCorrection()); QString backend; bool glCore = false; switch (compositingType()) { diff --git a/kcmkwin/kwincompositing/compositing.ui b/kcmkwin/kwincompositing/compositing.ui --- a/kcmkwin/kwincompositing/compositing.ui +++ b/kcmkwin/kwincompositing/compositing.ui @@ -7,7 +7,7 @@ 0 0 462 - 377 + 349 @@ -21,14 +21,14 @@ false - + OpenGL compositing (the default) has crashed KWin in the past. This was most likely due to a driver bug. If you think that you have meanwhile upgraded to a stable driver, you can reset this protection but be aware that this might result in an immediate crash! Alternatively, you might want to use the XRender backend instead. - + true @@ -38,10 +38,10 @@ false - + Scale method "Accurate" is not supported by all hardware and can cause performance regressions and rendering artifacts. - + true @@ -51,7 +51,7 @@ false - + true @@ -61,10 +61,10 @@ false - + Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized. - + true @@ -269,21 +269,7 @@ - - - - Experimental: - - - - - - Enable color correction - - - - Applications can set a hint to block compositing when the window is open. diff --git a/kcmkwin/kwincompositing/main.cpp b/kcmkwin/kwincompositing/main.cpp --- a/kcmkwin/kwincompositing/main.cpp +++ b/kcmkwin/kwincompositing/main.cpp @@ -167,11 +167,6 @@ } ); - // color correction - m_form.colorCorrection->setChecked(m_compositing->glColorCorrection()); - connect(m_compositing, &Compositing::glColorCorrectionChanged, m_form.colorCorrection, &QCheckBox::setChecked); - connect(m_form.colorCorrection, &QCheckBox::toggled, m_compositing, &Compositing::setGlColorCorrection); - // windows blocking compositing m_form.windowsBlockCompositing->setChecked(m_compositing->windowsBlockCompositing()); connect(m_compositing, &Compositing::windowsBlockCompositingChanged, m_form.windowsBlockCompositing, &QCheckBox::setChecked); @@ -195,7 +190,6 @@ m_form.glScaleFilterLabel->setVisible(currentType != CompositingType::XRENDER_INDEX); m_form.xrScaleFilter->setVisible(currentType == CompositingType::XRENDER_INDEX); m_form.xrScaleFilterLabel->setVisible(currentType == CompositingType::XRENDER_INDEX); - m_form.colorCorrection->setEnabled(currentType == CompositingType::OPENGL31_INDEX || currentType == CompositingType::OPENGL20_INDEX); }; showHideBasedOnType(); connect(m_form.type, currentIndexChangedSignal, diff --git a/kwin.kcfg b/kwin.kcfg --- a/kwin.kcfg +++ b/kwin.kcfg @@ -243,9 +243,6 @@ false - - false - false diff --git a/libkwineffects/CMakeLists.txt b/libkwineffects/CMakeLists.txt --- a/libkwineffects/CMakeLists.txt +++ b/libkwineffects/CMakeLists.txt @@ -82,15 +82,14 @@ kwingltexture.cpp kwinglutils_funcs.cpp kwinglplatform.cpp - kwinglcolorcorrection.cpp logging.cpp ) macro( KWIN4_ADD_GLUTILS_BACKEND name glinclude ) include_directories(${glinclude}) add_library(${name} SHARED ${kwin_GLUTILSLIB_SRCS}) generate_export_header(${name} BASE_NAME kwinglutils EXPORT_FILE_NAME kwinglutils_export.h) - target_link_libraries(${name} PUBLIC Qt5::DBus XCB::XCB KF5::CoreAddons KF5::WindowSystem) + target_link_libraries(${name} PUBLIC XCB::XCB KF5::CoreAddons KF5::WindowSystem) set_target_properties(${name} PROPERTIES VERSION ${KWINEFFECTS_VERSION_STRING} SOVERSION ${KWINEFFECTS_SOVERSION} diff --git a/libkwineffects/kwinglcolorcorrection.h b/libkwineffects/kwinglcolorcorrection.h deleted file mode 100644 --- a/libkwineffects/kwinglcolorcorrection.h +++ /dev/null @@ -1,106 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2012 Casian Andrei - -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, see . -*********************************************************************/ - -#ifndef KWIN_COLOR_CORRECTION_H -#define KWIN_COLOR_CORRECTION_H - -#include - -#include - -namespace KWin { - -class ColorCorrectionPrivate; - -/** - * Implements a color correction mechanism. The settings are obtained - * asynchronously via D-Bus from kolor-server, which is part of kolor-manager. - * - * If it fails to get the settings, nothing should happen (no correction), even - * if it is set to enabled. - * - * Supports per-output and per-region correction (window region). - * - * \warning This class is not designed to be used by effects, however - * it may happen to be useful their case somehow. - */ -class KWINGLUTILS_EXPORT ColorCorrection : public QObject -{ - Q_OBJECT - -public: - explicit ColorCorrection(QObject *parent = nullptr); - virtual ~ColorCorrection(); - - /** - * Prepares color correction for the output number \param screen. - * Sets up the appropriate color lookup texture for the output. - */ - void setupForOutput(int screen); - - /** - * Unsets color correction by using a dummy color lookup texture. This - * does not disable anything, the CC mechanisms remain in place. Instead, it - * indicates to draw normally. - */ - void reset(); - - /** - * Modifies \param sourceCode, making it suitable for performing - * color correction. This is done by inserting a 3d texture lookup operation - * just before the output fragment color is returned. - */ - static QByteArray prepareFragmentShader(const QByteArray &sourceCode); - - /** - * @return whether color correction is enabled - */ - bool isEnabled() const; - -public Q_SLOTS: - /** - * Enables or disables color correction. Compositing should be restarted - * for changes to take effect. - * - * @return true when successful - */ - bool setEnabled(bool enabled); - -Q_SIGNALS: - /** - * Emitted when some changes happened to the color correction settings, and - * a full repaint of the scene should be done to make the new settings visible. - */ - void changed(); - - /** - * Emitted when something failed because of an error (probably a GL error) - * The description of the error should be found in the logs. - */ - void errorOccured(); - -private: - ColorCorrectionPrivate * const d_ptr; - Q_DECLARE_PRIVATE(ColorCorrection) -}; - -} // KWin namespace - -#endif // KWIN_COLOR_CORRECTION_H diff --git a/libkwineffects/kwinglcolorcorrection.cpp b/libkwineffects/kwinglcolorcorrection.cpp deleted file mode 100644 --- a/libkwineffects/kwinglcolorcorrection.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2012 Casian Andrei - -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, see . -*********************************************************************/ - -#include "kwinglcolorcorrection.h" -#include "kwinglcolorcorrection_p.h" - -#include "kwinglplatform.h" -#include "kwinglutils.h" -#include "logging_p.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace KWin { - -/* - * Color lookup table - * - * The 3D lookup texture has 64 points in each dimension, using 16 bit integers. - * That means each active region will use 1.5MiB of texture memory. - */ -static const int LUT_GRID_POINTS = 64; -static const size_t CLUT_ELEMENT_SIZE = sizeof(quint16); -static const uint CLUT_ELEMENT_COUNT = LUT_GRID_POINTS * LUT_GRID_POINTS * LUT_GRID_POINTS * 3; -static const size_t CLUT_DATA_SIZE = CLUT_ELEMENT_COUNT * CLUT_ELEMENT_SIZE; - -inline static void buildDummyClut(Clut &c) -{ - c.resize(CLUT_ELEMENT_COUNT); - quint16 *p = c.data(); - - for (int ib = 0; ib < LUT_GRID_POINTS; ++ ib) { - quint16 b = (quint16) ((float) ib / (LUT_GRID_POINTS - 1) * 65535.0 + 0.5); - for (int ig = 0; ig < LUT_GRID_POINTS; ++ ig) { - quint16 g = (quint16) ((float) ig / (LUT_GRID_POINTS - 1) * 65535.0 + 0.5); - for (int ir = 0; ir < LUT_GRID_POINTS; ++ ir) { - quint16 r = (quint16) ((float) ir / (LUT_GRID_POINTS - 1) * 65535.0 + 0.5); - - *(p ++) = r; - *(p ++) = g; - *(p ++) = b; - } - } - } -} - - -/* - * Color Server Interface - */ - -ColorServerInterface::ColorServerInterface(const QString &service, - const QString &path, - const QDBusConnection &connection, - QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) - , m_versionInfoWatcher(0) - , m_outputClutsWatcher(0) - , m_regionClutsWatcher(0) - , m_versionInfoUpdated(false) - , m_outputClutsUpdated(false) - , m_regionClutsUpdated(false) - , m_versionInfo(0) - , m_signaledFail(false) -{ - qDBusRegisterMetaType< Clut >(); - qDBusRegisterMetaType< ClutList >(); - qDBusRegisterMetaType< RegionalClut >(); - qDBusRegisterMetaType< RegionalClutMap >(); - - connect(this, SIGNAL(outputClutsChanged()), this, SLOT(update())); - connect(this, SIGNAL(regionClutsChanged()), this, SLOT(update())); -} - -ColorServerInterface::~ColorServerInterface() -{ -} - -uint ColorServerInterface::versionInfo() const -{ - if (!m_versionInfoUpdated) - qCWarning(LIBKWINGLUTILS) << "Version info not updated"; - return m_versionInfo; -} - -const ClutList& ColorServerInterface::outputCluts() const -{ - return m_outputCluts; -} - -const RegionalClutMap& ColorServerInterface::regionCluts() const -{ - return m_regionCluts; -} - -void ColorServerInterface::update() -{ - m_versionInfoUpdated = false; - m_outputClutsUpdated = false; - m_regionClutsUpdated = false; - delete m_versionInfoWatcher; - delete m_outputClutsWatcher; - delete m_regionClutsWatcher; - m_versionInfoWatcher = new QDBusPendingCallWatcher(getVersionInfo(), this); - m_outputClutsWatcher = new QDBusPendingCallWatcher(getOutputCluts(), this); - m_regionClutsWatcher = new QDBusPendingCallWatcher(getRegionCluts(), this); - connect(m_versionInfoWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), - this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*))); - connect(m_outputClutsWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), - this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*))); - connect(m_regionClutsWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), - this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*))); - - m_signaledFail = false; -} - -QDBusPendingReply< uint > ColorServerInterface::getVersionInfo() -{ - return QDBusPendingReply< uint >(asyncCall(QStringLiteral("getVersionInfo"))); -} - -QDBusPendingReply< ClutList > ColorServerInterface::getOutputCluts() -{ - return QDBusPendingReply< ClutList >(asyncCall(QStringLiteral("getOutputCluts"))); -} - -QDBusPendingReply< RegionalClutMap > ColorServerInterface::getRegionCluts() -{ - return QDBusPendingReply< RegionalClutMap >(asyncCall(QStringLiteral("getRegionCluts"))); -} - -void ColorServerInterface::callFinishedSlot(QDBusPendingCallWatcher *watcher) -{ - if (watcher == m_versionInfoWatcher) { - qCDebug(LIBKWINGLUTILS) << "Version info call finished"; - QDBusPendingReply< uint > reply = *watcher; - if (reply.isError()) { - qCWarning(LIBKWINGLUTILS) << reply.error(); - if (!m_signaledFail) - emit updateFailed(); - m_signaledFail = true; - return; - } else { - m_versionInfo = reply.value(); - m_versionInfoUpdated = true; - } - } - - if (watcher == m_outputClutsWatcher) { - qCDebug(LIBKWINGLUTILS) << "Output cluts call finished"; - QDBusPendingReply< ClutList > reply = *watcher; - if (reply.isError()) { - qCWarning(LIBKWINGLUTILS) << reply.error(); - if (!m_signaledFail) - emit updateFailed(); - m_signaledFail = true; - return; - } else { - m_outputCluts = reply.value(); - m_outputClutsUpdated = true; - } - } - - if (watcher == m_regionClutsWatcher) { - qCDebug(LIBKWINGLUTILS) << "Region cluts call finished"; - QDBusPendingReply< RegionalClutMap > reply = *watcher; - if (reply.isError()) { - qCWarning(LIBKWINGLUTILS) << reply.error(); - if (!m_signaledFail) - emit updateFailed(); - m_signaledFail = true; - return; - } else { - m_regionCluts = reply.value(); - m_regionClutsUpdated = true; - } - } - - if (m_versionInfoUpdated && - m_outputClutsUpdated && - m_regionClutsUpdated) { - qCDebug(LIBKWINGLUTILS) << "Update succeeded"; - emit updateSucceeded(); - } -} - - -/* - * To be injected in the fragment shader sources - */ -static const char s_ccVars[] = - "uniform sampler3D u_ccLookupTexture;\n"; -static const char s_ccAlteration[] = - "gl_FragColor.rgb = texture3D(u_ccLookupTexture, gl_FragColor.rgb / gl_FragColor.a).rgb * gl_FragColor.a;\n"; -static const char s_ccAlteration_140[] = - "fragColor.rgb = texture(u_ccLookupTexture, fragColor.rgb / fragColor.a).rgb * fragColor.a;\n"; - - -/* - * Color Correction - */ - -ColorCorrection::ColorCorrection(QObject *parent) - : QObject(parent) - , d_ptr(new ColorCorrectionPrivate(this)) -{ - connect(this, SIGNAL(errorOccured()), this, SIGNAL(changed())); -} - -ColorCorrection::~ColorCorrection() -{ - setEnabled(false); -} - -ColorCorrectionPrivate::ColorCorrectionPrivate(ColorCorrection *parent) - : QObject(parent) - , m_enabled(false) - , m_hasError(false) - , m_duringEnablingPhase(false) - , m_haveTexture3D(!GLPlatform::instance()->isGLES() || hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_OES_texture_3D"))) - , m_ccTextureUnit(-1) - , m_dummyCCTexture(0) - , m_lastOutput(-1) - , q_ptr(parent) -{ - // We need a dummy color lookup table (sRGB profile to sRGB profile) - buildDummyClut(m_dummyClut); - - // Establish a D-Bus communication interface with KolorServer - m_csi = new ColorServerInterface( - QStringLiteral("org.kde.kded5"), - QStringLiteral("/modules/kolorserver"), - QDBusConnection::sessionBus(), - this); - - m_outputCluts = &m_csi->outputCluts(); - - connect(m_csi, SIGNAL(updateSucceeded()), this, SLOT(colorServerUpdateSucceededSlot())); - connect(m_csi, SIGNAL(updateFailed()), this, SLOT(colorServerUpdateFailedSlot())); -} - -ColorCorrectionPrivate::~ColorCorrectionPrivate() -{ - -} - -bool ColorCorrection::isEnabled() const -{ - Q_D(const ColorCorrection); - return d->m_enabled; -} - -bool ColorCorrection::setEnabled(bool enabled) -{ - Q_D(ColorCorrection); - - if (enabled == d->m_enabled) - return true; - - if (enabled && d->m_hasError) { - qCCritical(LIBKWINGLUTILS) << "cannot enable color correction because of a previous error"; - return false; - } - - const GLPlatform *gl = GLPlatform::instance(); - if (enabled && gl->isGLES() && !d->m_haveTexture3D) { - qCCritical(LIBKWINGLUTILS) << "color correction is not supported on OpenGL ES without OES_texture_3D"; - d->m_hasError = true; - return false; - } - - if (enabled) { - // Update all profiles and regions - d->m_csi->update(); - qCDebug(LIBKWINGLUTILS) << "color correction will be enabled after contacting KolorManager"; - d->m_duringEnablingPhase = true; - // d->m_enabled will be set to true in colorServerUpdateSucceededSlot() - } else { - d->deleteCCTextures(); - d->m_enabled = false; - GLShader::sColorCorrect = false; - qCDebug(LIBKWINGLUTILS) << "color correction has been disabled"; - - // Reload all shaders - ShaderManager::cleanup(); - ShaderManager::instance(); - } - - return true; -} - -void ColorCorrection::setupForOutput(int screen) -{ - Q_D(ColorCorrection); - - if (!d->m_enabled || d->m_hasError) - return; - - GLShader *shader = ShaderManager::instance()->getBoundShader(); - if (!shader) { - qCCritical(LIBKWINGLUTILS) << "no bound shader for color correction setup"; - d->m_hasError = true; - emit errorOccured(); - return; - } - - if (d->m_ccTextureUnit < 0) { - GLint maxUnits = 0; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits); - d->m_ccTextureUnit = maxUnits - 1; - } - - if (!shader->setUniform(GLShader::ColorCorrectionLookupTextureUnit, d->m_ccTextureUnit)) { - qCCritical(LIBKWINGLUTILS) << "unable to set uniform for the color correction lookup texture"; - d->m_hasError = true; - emit errorOccured(); - return; - } - - if (!d->setupCCTextures()) { - qCCritical(LIBKWINGLUTILS) << "unable to setup color correction textures"; - d->m_hasError = true; - emit errorOccured(); - return; - } - - GLint activeTexture; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - glActiveTexture(GL_TEXTURE0 + d->m_ccTextureUnit); - - if (d->m_outputCCTextures.isEmpty() || screen < 0 || screen >= d->m_outputCCTextures.count()) { - // Configure with a dummy texture in case something is wrong - Q_ASSERT(d->m_dummyCCTexture != 0); - glBindTexture(GL_TEXTURE_3D, d->m_dummyCCTexture); - } else { - // Everything looks ok, configure with the proper color correction texture - glBindTexture(GL_TEXTURE_3D, d->m_outputCCTextures[screen]); - } - - glActiveTexture(activeTexture); - - d->m_lastOutput = screen; -} - -void ColorCorrection::reset() -{ - setupForOutput(-1); -} - -QByteArray ColorCorrection::prepareFragmentShader(const QByteArray &sourceCode) -{ - bool sourceIsValid = true; - - /* - * Detect comments to ignore them later - */ - QList< QPair< int, int > > comments; - int beginIndex, endIndex = 0; - int i1, i2; - - enum {ctNone, ctBegin, ctEnd} commentType; - QByteArrayMatcher commentBegin1("/*"), commentBegin2("//"); - QByteArrayMatcher commentEnd1("*/"), commentEnd2("\n"); - - do { - // Determine the next comment begin index - i1 = commentBegin1.indexIn(sourceCode, endIndex); - i2 = commentBegin2.indexIn(sourceCode, endIndex); - if (i1 == -1 && i2 == -1) commentType = ctNone; - else if (i1 == -1) commentType = ctEnd; - else if (i2 == -1) commentType = ctBegin; - else if (i1 < i2) commentType = ctBegin; - else commentType = ctEnd; - if (commentType == ctNone) - break; - - // Determine the comment's end index - if (commentType == ctBegin) { - beginIndex = i1; - endIndex = commentEnd1.indexIn(sourceCode, beginIndex + 2); - } - if (commentType == ctEnd) { - beginIndex = i2; - endIndex = commentEnd2.indexIn(sourceCode, beginIndex + 2); - } - - if (endIndex != -1) { - if (commentType == ctBegin) - endIndex ++; // adjust for "*/" to be removed - if (commentType == ctEnd) - endIndex --; // adjust for "\n" to be kept - comments.append(QPair< int, int >(beginIndex, endIndex)); - } else { - if (commentType == ctBegin) - sourceIsValid = false; - if (commentType == ctEnd) - comments.append(QPair< int, int >(beginIndex, sourceCode.length())); - break; - } - } while (sourceIsValid); - if (!sourceIsValid) - return sourceCode; - - // Create a version of the source code with the comments stripped out - QByteArray cfSource(sourceCode); // comment-free source code - for (int i = comments.size() - 1; i >= 0; -- i) { - beginIndex = comments[i].first; - endIndex = comments[i].second; - cfSource.replace(beginIndex, endIndex - beginIndex + 1, " "); - } - - /* - * Browse through the code while counting braces - * Search for "void main() { ... }: - */ - QByteArrayMatcher braceOpen("{"); - QByteArrayMatcher braceClose("}"); - QByteArrayMatcher voidKeyword("void"); - int levelOfScope = 0; - enum {brNone, brOpen, brClose} braceType; - - int mainFuncBegin = -1; // where "void main" begins - int mainFuncEnd = -1; // at the closing brace of "void main" - bool insideMainFunc = false; - int i = 0; - - do { - // Determine where the next brace is - i1 = braceOpen.indexIn(cfSource, i); - i2 = braceClose.indexIn(cfSource, i); - if (i1 == -1 && i2 == -1) braceType = brNone; - else if (i1 == -1) braceType = brClose; - else if (i2 == -1) braceType = brOpen; - else if (i1 < i2) braceType = brOpen; - else braceType = brClose; - if (braceType == brNone) { - if (levelOfScope > 0) - sourceIsValid = false; - break; - } - - // Handle opening brance (see if is from void main()) - if (braceType == brOpen) { - if (levelOfScope == 0) { - // Need to search between i and i1 (the last '}' and the current '{' - QByteArray section = cfSource.mid(i, i1 - i); - int i_void = -1; - while ((i_void = section.indexOf("void", i_void + 1)) != -1) { - // Extract the subsection that begins with "void" - QByteArray subSection = section.mid(i_void).simplified(); - subSection.replace('(', " ( "); - subSection.replace(')', " ) "); - QList tokens = subSection.split(' '); - for (int i_token = tokens.size() - 1; i_token >= 0; -- i_token) - if (tokens[i_token].trimmed().isEmpty()) - tokens.removeAt(i_token); - if (tokens.size() == 4 && - tokens[0] == "void" && - tokens[1] == "main" && - tokens[2] == "(" && - tokens[3] == ")") { - if (mainFuncBegin != -1) { - sourceIsValid = false; - break; - } - mainFuncBegin = i + i_void; - insideMainFunc = true; - } - } - } - - levelOfScope ++; - i = i1 + 1; - } - - // Handle closing brace (see if it is from void main()) - if (braceType == brClose) { - levelOfScope --; - if (levelOfScope < 0) { - sourceIsValid = false; - break; - } - - if (levelOfScope == 0 && insideMainFunc) { - mainFuncEnd = i2; - insideMainFunc = false; - } - - i = i2 + 1; - } - } while (sourceIsValid); - sourceIsValid = sourceIsValid && mainFuncBegin != -1 && mainFuncEnd != -1; - if (!sourceIsValid) - return sourceCode; - - QByteArray mainFunc = cfSource.mid(mainFuncBegin, mainFuncEnd - mainFuncBegin + 1); - - /* - * Insert color correction variables at the beginning and - * the color correction code at the end of the main function. - * Need to handle return "jumps" inside the main function. - */ - if (GLPlatform::instance()->glslVersion() >= kVersionNumber(1, 40)) - mainFunc.insert(mainFunc.size() - 1, s_ccAlteration_140); - else - mainFunc.insert(mainFunc.size() - 1, s_ccAlteration); - mainFunc.insert(0, s_ccVars); - - // Search for return statements inside the main function - QByteArrayMatcher returnMatcher("return"); - i = -1; - while ((i = returnMatcher.indexIn(mainFunc, i)) != -1) { - i1 = mainFunc.indexOf(';', i); - mainFunc.insert(i1 + 1, '}'); - mainFunc.insert(i, '{'); - mainFunc.insert(i + 1, s_ccAlteration); - mainFuncEnd += strlen(s_ccAlteration) + 2; - - i = i1 + strlen(s_ccAlteration) + 2; - } - - // Replace the main function - cfSource.replace(mainFuncBegin, mainFuncEnd - mainFuncBegin + 1, mainFunc); - - return cfSource; -} - -bool ColorCorrectionPrivate::setupCCTextures() -{ - if (!m_enabled || m_hasError) { - qCWarning(LIBKWINGLUTILS) << "Color correction not enabled or an error occurred, refusing to set up textures"; - return false; - } - - // Dummy texture first - if (!m_dummyCCTexture) { - glGenTextures(1, &m_dummyCCTexture); - if (!setupCCTexture(m_dummyCCTexture, m_dummyClut)) { - qCCritical(LIBKWINGLUTILS) << "unable to setup dummy color correction texture"; - m_dummyCCTexture = 0; - return false; - } - } - - bool success = true; - - // Setup actual color correction textures - if (m_outputCCTextures.isEmpty() && !m_outputCluts->isEmpty()) { - qCDebug(LIBKWINGLUTILS) << "setting up output color correction textures"; - - const int outputCount = m_outputCluts->size(); - m_outputCCTextures.resize(outputCount); - glGenTextures(outputCount, m_outputCCTextures.data()); - - for (int i = 0; i < outputCount; ++i) - if (!setupCCTexture(m_outputCCTextures[i], m_outputCluts->at(i))) { - qCCritical(LIBKWINGLUTILS) << "unable to set up color correction texture for output" << i; - success = false; - } - } - - return success; -} - -void ColorCorrectionPrivate::deleteCCTextures() -{ - // Delete dummy texture - if (m_dummyCCTexture) { - glDeleteTextures(1, &m_dummyCCTexture); - m_dummyCCTexture = 0; - } - - // Delete actual color correction extures - if (!m_outputCCTextures.isEmpty()) { - glDeleteTextures(m_outputCCTextures.size(), m_outputCCTextures.data()); - m_outputCCTextures.clear(); - } -} - -bool ColorCorrectionPrivate::setupCCTexture(GLuint texture, const Clut& clut) -{ - if ((uint) clut.size() != CLUT_ELEMENT_COUNT) { - qCCritical(LIBKWINGLUTILS) << "cannot setup CC texture: invalid color lookup table"; - return false; - } - - // Clear any previous GL errors - checkGLError("setupCCTexture-clearErrors"); - - glBindTexture(GL_TEXTURE_3D, texture); - - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - if (!GLPlatform::instance()->isGLES()) { - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16, - LUT_GRID_POINTS, LUT_GRID_POINTS, LUT_GRID_POINTS, - 0, GL_RGB, GL_UNSIGNED_SHORT, clut.data()); - } else { - const int textureDataSize = clut.size(); - QVector textureData(textureDataSize); - quint8 *pTextureData = textureData.data(); - const quint16 *pClutData = clut.data(); - for (int i = 0; i < textureDataSize; ++i) - *(pTextureData++) = *(pClutData++) >> 8; - - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, - LUT_GRID_POINTS, LUT_GRID_POINTS, LUT_GRID_POINTS, - 0, GL_RGB, GL_UNSIGNED_BYTE, textureData.data()); - } - - return !checkGLError("setupCCTexture"); -} - -void ColorCorrectionPrivate::colorServerUpdateSucceededSlot() -{ - Q_Q(ColorCorrection); - - qCDebug(LIBKWINGLUTILS) << "Update of color profiles succeeded"; - - // Force the color correction textures to be recreated - deleteCCTextures(); - - // If this is reached after enabling color correction using ColorCorrection::setEnabled(true) - if (m_duringEnablingPhase) { - m_duringEnablingPhase = false; - m_enabled = true; - GLShader::sColorCorrect = true; - qCDebug(LIBKWINGLUTILS) << "Color correction has been enabled"; - - // Reload all shaders - ShaderManager::cleanup(); - } - - emit q->changed(); -} - -void ColorCorrectionPrivate::colorServerUpdateFailedSlot() -{ - Q_Q(ColorCorrection); - - m_duringEnablingPhase = false; - - qCCritical(LIBKWINGLUTILS) << "Update of color profiles failed"; - m_hasError = true; - emit q->errorOccured(); -} - -} // KWin namespace diff --git a/libkwineffects/kwinglcolorcorrection_p.h b/libkwineffects/kwinglcolorcorrection_p.h deleted file mode 100644 --- a/libkwineffects/kwinglcolorcorrection_p.h +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************** - KWin - the KDE window manager - This file is part of the KDE project. - -Copyright (C) 2012 Casian Andrei - -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, see . -*********************************************************************/ - -#ifndef KWIN_COLOR_CORRECTION_P_H_ -#define KWIN_COLOR_CORRECTION_P_H_ - -#include "kwinglcolorcorrection.h" -#include "kwinglutils_funcs.h" - -#include -#include -#include -#include -#include - -class QDBusPendingCallWatcher; - -/* - * Clut - * All this should be the same as in the color server code, in kolor-manager - */ -typedef QVector Clut; -typedef QList ClutList; -typedef struct { QRect r; Clut c; } RegionalClut; -typedef QMultiMap RegionalClutMap; - -Q_DECLARE_METATYPE(Clut) -Q_DECLARE_METATYPE(ClutList) -Q_DECLARE_METATYPE(RegionalClut) -Q_DECLARE_METATYPE(RegionalClutMap) - -// Marshall the RegionalClut data into a D-Bus argument -inline QDBusArgument &operator<<(QDBusArgument &argument, const RegionalClut &rc) -{ - argument.beginStructure(); - argument << rc.r << rc.c; - argument.endStructure(); - return argument; -} - -// Retrieve the RegionalClut data from the D-Bus argument -inline const QDBusArgument &operator>>(const QDBusArgument &argument, RegionalClut &rc) -{ - argument.beginStructure(); - argument >> rc.r >> rc.c; - argument.endStructure(); - return argument; -} - - -namespace KWin { - -class ColorServerInterface; - - -/* - * Color Correction Private Data - */ -class ColorCorrectionPrivate : public QObject -{ - Q_OBJECT - -public: - explicit ColorCorrectionPrivate(ColorCorrection* parent); - virtual ~ColorCorrectionPrivate(); - - bool setupCCTextures(); - void deleteCCTextures(); - static bool setupCCTexture(GLuint texture, const Clut &clut); - -public Q_SLOTS: - void colorServerUpdateSucceededSlot(); - void colorServerUpdateFailedSlot(); - -public: - bool m_enabled; - bool m_hasError; - bool m_duringEnablingPhase; - bool m_haveTexture3D; - int m_ccTextureUnit; - - ColorServerInterface *m_csi; - const ClutList *m_outputCluts; - QVector m_outputCCTextures; - Clut m_dummyClut; - GLuint m_dummyCCTexture; - - int m_lastOutput; - -private: - ColorCorrection *q_ptr; - Q_DECLARE_PUBLIC(ColorCorrection) -}; - - -/* - * Color Server DBus interface - */ -class ColorServerInterface : public QDBusAbstractInterface -{ - Q_OBJECT - -public: - static inline const char *staticInterfaceName() - { return "org.kde.KolorServer"; } - -public: - ColorServerInterface(const QString &service, - const QString &path, - const QDBusConnection &connection, - QObject *parent = nullptr); - virtual ~ColorServerInterface(); - - uint versionInfo() const; - const ClutList& outputCluts() const; - const RegionalClutMap& regionCluts() const; - -public Q_SLOTS: - void update(); - -Q_SIGNALS: - void updateSucceeded(); - void updateFailed(); - void outputClutsChanged(); - void regionClutsChanged(); - -private: - QDBusPendingReply< uint > getVersionInfo(); - QDBusPendingReply< ClutList > getOutputCluts(); - QDBusPendingReply< RegionalClutMap > getRegionCluts(); - -private Q_SLOTS: - void callFinishedSlot(QDBusPendingCallWatcher *watcher); - -private: - QDBusPendingCallWatcher *m_versionInfoWatcher; - QDBusPendingCallWatcher *m_outputClutsWatcher; - QDBusPendingCallWatcher *m_regionClutsWatcher; - bool m_versionInfoUpdated; - bool m_outputClutsUpdated; - bool m_regionClutsUpdated; - uint m_versionInfo; - ClutList m_outputCluts; - RegionalClutMap m_regionCluts; - - bool m_signaledFail; -}; - -} // KWin namespace - -#endif // KWIN_COLOR_CORRECTION_P_H_ diff --git a/libkwineffects/kwinglutils.h b/libkwineffects/kwinglutils.h --- a/libkwineffects/kwinglutils.h +++ b/libkwineffects/kwinglutils.h @@ -139,7 +139,6 @@ enum IntUniform { AlphaToOne, ///< @deprecated no longer used - ColorCorrectionLookupTextureUnit, IntUniformCount }; @@ -178,10 +177,6 @@ int mIntLocation[IntUniformCount]; int mColorLocation[ColorUniformCount]; - static bool sColorCorrect; - - friend class ColorCorrection; - friend class ColorCorrectionPrivate; friend class ShaderManager; }; diff --git a/libkwineffects/kwinglutils.cpp b/libkwineffects/kwinglutils.cpp --- a/libkwineffects/kwinglutils.cpp +++ b/libkwineffects/kwinglutils.cpp @@ -24,7 +24,6 @@ // need to call GLTexturePrivate::initStatic() #include "kwingltexture_p.h" -#include "kwinglcolorcorrection.h" #include "kwineffects.h" #include "kwinglplatform.h" #include "logging_p.h" @@ -142,8 +141,6 @@ // GLShader //**************************************** -bool GLShader::sColorCorrect = false; - GLShader::GLShader(unsigned int flags) : mValid(false) , mLocationsResolved(false) @@ -230,10 +227,6 @@ ba.replace("#version 140", "#version 300 es\n\nprecision highp float;\n"); } - // Inject color correction code for fragment shaders, if possible - if (shaderType == GL_FRAGMENT_SHADER && sColorCorrect) - ba = ColorCorrection::prepareFragmentShader(ba); - return ba; } @@ -346,8 +339,6 @@ mFloatLocation[Saturation] = uniformLocation("saturation"); - mIntLocation[ColorCorrectionLookupTextureUnit] = uniformLocation("u_ccLookupTexture"); - mColorLocation[Color] = uniformLocation("geometryColor"); mLocationsResolved = true; diff --git a/options.h b/options.h --- a/options.h +++ b/options.h @@ -175,7 +175,6 @@ * -1 = auto **/ Q_PROPERTY(int glSmoothScale READ glSmoothScale WRITE setGlSmoothScale NOTIFY glSmoothScaleChanged) - Q_PROPERTY(bool colorCorrected READ isColorCorrected WRITE setColorCorrected NOTIFY colorCorrectedChanged) Q_PROPERTY(bool xrenderSmoothScale READ isXrenderSmoothScale WRITE setXrenderSmoothScale NOTIFY xrenderSmoothScaleChanged) Q_PROPERTY(qint64 maxFpsInterval READ maxFpsInterval WRITE setMaxFpsInterval NOTIFY maxFpsIntervalChanged) Q_PROPERTY(uint refreshRate READ refreshRate WRITE setRefreshRate NOTIFY refreshRateChanged) @@ -558,9 +557,6 @@ int glSmoothScale() const { return m_glSmoothScale; } - bool isColorCorrected() const { - return m_colorCorrected; - } // XRender bool isXrenderSmoothScale() const { return m_xrenderSmoothScale; @@ -743,9 +739,6 @@ static int defaultGlSmoothScale() { return 2; } - static bool defaultColorCorrected() { - return false; - } static bool defaultXrenderSmoothScale() { return false; } @@ -845,7 +838,6 @@ void compositingInitializedChanged(); void hiddenPreviewsChanged(); void glSmoothScaleChanged(); - void colorCorrectedChanged(); void xrenderSmoothScaleChanged(); void maxFpsIntervalChanged(); void refreshRateChanged(); @@ -859,9 +851,6 @@ void configChanged(); -public Q_SLOTS: - void setColorCorrected(bool colorCorrected = false); - private: void setElectricBorders(int borders); void syncFromKcfgc(); @@ -894,7 +883,6 @@ bool m_compositingInitialized; HiddenPreviews m_hiddenPreviews; int m_glSmoothScale; - bool m_colorCorrected; bool m_xrenderSmoothScale; qint64 m_maxFpsInterval; // Settings that should be auto-detected diff --git a/options.cpp b/options.cpp --- a/options.cpp +++ b/options.cpp @@ -115,7 +115,6 @@ , m_compositingInitialized(Options::defaultCompositingInitialized()) , m_hiddenPreviews(Options::defaultHiddenPreviews()) , m_glSmoothScale(Options::defaultGlSmoothScale()) - , m_colorCorrected(Options::defaultColorCorrected()) , m_xrenderSmoothScale(Options::defaultXrenderSmoothScale()) , m_maxFpsInterval(Options::defaultMaxFpsInterval()) , m_refreshRate(Options::defaultRefreshRate()) @@ -643,15 +642,6 @@ emit glSmoothScaleChanged(); } -void Options::setColorCorrected(bool colorCorrected) -{ - if (m_colorCorrected == colorCorrected) { - return; - } - m_colorCorrected = colorCorrected; - emit colorCorrectedChanged(); -} - void Options::setXrenderSmoothScale(bool xrenderSmoothScale) { if (m_xrenderSmoothScale == xrenderSmoothScale) { @@ -991,8 +981,6 @@ c = 0; setGlPreferBufferSwap(c); - setColorCorrected(config.readEntry("GLColorCorrection", Options::defaultColorCorrected())); - m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false); HiddenPreviews previews = Options::defaultHiddenPreviews(); diff --git a/scene_opengl.h b/scene_opengl.h --- a/scene_opengl.h +++ b/scene_opengl.h @@ -32,7 +32,6 @@ namespace KWin { -class ColorCorrection; class LanczosFilter; class OpenGLBackend; class SyncManager; @@ -128,7 +127,6 @@ static bool supported(OpenGLBackend *backend); - ColorCorrection *colorCorrection(); QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; } QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; } @@ -141,16 +139,14 @@ virtual void updateProjectionMatrix() override; private Q_SLOTS: - void slotColorCorrectedChanged(bool recreateShaders = true); void resetLanczosFilter(); private: void performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data); QMatrix4x4 createProjectionMatrix() const; private: LanczosFilter *m_lanczosFilter; - QScopedPointer m_colorCorrection; QMatrix4x4 m_projectionMatrix; QMatrix4x4 m_screenProjectionMatrix; GLuint vao; diff --git a/scene_opengl.cpp b/scene_opengl.cpp --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -31,7 +31,6 @@ #include "platform.h" #include "wayland_server.h" -#include #include #include "utils.h" @@ -992,7 +991,6 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject *parent) : SceneOpenGL(backend, parent) , m_lanczosFilter(NULL) - , m_colorCorrection() { if (!init_ok) { // base ctor already failed @@ -1006,10 +1004,6 @@ return; } - // Initialize color correction before the shaders - slotColorCorrectedChanged(false); - connect(options, SIGNAL(colorCorrectedChanged()), this, SLOT(slotColorCorrectedChanged()), Qt::QueuedConnection); - const QSize &s = screens()->size(); GLRenderTarget::setVirtualScreenSize(s); GLRenderTarget::setVirtualScreenGeometry(screens()->geometry()); @@ -1120,20 +1114,7 @@ if (waylandServer() && waylandServer()->isScreenLocked() && !w->window()->isLockScreen() && !w->window()->isInputMethod()) { return; } - if (!m_colorCorrection.isNull() && m_colorCorrection->isEnabled()) { - // Split the painting for separate screens - const int numScreens = screens()->count(); - for (int screen = 0; screen < numScreens; ++ screen) { - QRegion regionForScreen(region); - if (numScreens > 1) - regionForScreen = region.intersected(screens()->geometry(screen)); - - data.setScreen(screen); - performPaintWindow(w, mask, regionForScreen, data); - } - } else { - performPaintWindow(w, mask, region, data); - } + performPaintWindow(w, mask, region, data); } void SceneOpenGL2::performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data) @@ -1156,33 +1137,6 @@ m_lanczosFilter = NULL; } -ColorCorrection *SceneOpenGL2::colorCorrection() -{ - return m_colorCorrection.data(); -} - -void SceneOpenGL2::slotColorCorrectedChanged(bool recreateShaders) -{ - qCDebug(KWIN_CORE) << "Color correction:" << options->isColorCorrected(); - if (options->isColorCorrected() && m_colorCorrection.isNull()) { - m_colorCorrection.reset(new ColorCorrection(this)); - if (!m_colorCorrection->setEnabled(true)) { - m_colorCorrection.reset(); - return; - } - connect(m_colorCorrection.data(), SIGNAL(changed()), Compositor::self(), SLOT(addRepaintFull())); - connect(m_colorCorrection.data(), SIGNAL(errorOccured()), options, SLOT(setColorCorrected()), Qt::QueuedConnection); - if (recreateShaders) { - // Reload all shaders - ShaderManager::cleanup(); - ShaderManager::instance(); - } - } else { - m_colorCorrection.reset(); - } - Compositor::self()->addRepaintFull(); -} - //**************************************** // SceneOpenGL::Texture //**************************************** @@ -1521,8 +1475,6 @@ if (!beginRenderWindow(mask, region, data)) return; - SceneOpenGL2 *scene = static_cast(m_scene); - QMatrix4x4 windowMatrix = transformation(mask, data); const QMatrix4x4 modelViewProjection = modelViewProjectionMatrix(mask, data); const QMatrix4x4 mvpMatrix = modelViewProjection * windowMatrix; @@ -1541,10 +1493,6 @@ } shader->setUniform(GLShader::ModelViewProjectionMatrix, mvpMatrix); - if (ColorCorrection *cc = scene->colorCorrection()) { - cc->setupForOutput(data.screen()); - } - shader->setUniform(GLShader::Saturation, data.saturation()); const GLenum filter = (mask & (Effect::PAINT_WINDOW_TRANSFORMED | Effect::PAINT_SCREEN_TRANSFORMED))