Drop OpenGL based color correction from KWin

Summary:
The feature has always been considered experimental. Unfortunately it is
completely unmaintained and hasn't seen any commits in years. It
requires kolor-manager to function, but that has not seen a release
based on frameworks yet. This makes it difficult to maintain. In fact I
have never been able from the introduction till now to setup a color
corrected system. One needs kolor-manager and oyranos and especially the
latter is hardly available on any linux distribution (e.g. not on the
Debian/Ubuntu systems).

Due to being unmaintained color correction in KWin did not keep up with
recent changes. Neither did it see any updates during the xlib->xcb
port, nor during the Wayland port. Especially the Wayland port with the
rendering changes make it unlikely to function correctly. E.g. Wayland
introduced a proper per-screen rendering, while color correction did a
"fake" per screen rendering. How that is going to work in combination is
something nobody ever tried. Now after the introduction of proper
per-screen rendering the solution would be to port color correction to
the new api, but that never happened.

Color correction also modified the shaders, but a newer shader API got
introduced some time ago. Whether the color correction shader support
that or not, is unknown to me. Also which shader language versions are
supported. I know it was based on 3d texture support, which back on
introduction was partially lacking in OpenGL ES. Nowadays that changed,
but color correction didn't update.

Last but not least it is completely X11 based and there is no work on
how to make it work with Wayland.

Given all the problems, especially the fact that it is unmaintained and
cannot be setup on my system, means to me that the only solution is to
remove it.

I'm open to having it reintroduced in future, but only if the
availability on Linux distributions gets addressed before. As long as
major linux distributions do not ship this feature, it should not be in
KWin. Given that I must say that it was a mistake to add it in the first
place and I need to point out that I was against the merge back then.

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D3402
icc-effect-5.14.5
Martin Gräßlin 2016-11-17 15:03:54 +01:00
parent 2619ddf02e
commit 17e0bad922
15 changed files with 10 additions and 1100 deletions

View File

@ -42,7 +42,6 @@ Compositing::Compositing(QObject *parent)
, 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 @@ Compositing::Compositing(QObject *parent)
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 @@ void Compositing::reset()
return 0;
};
setGlSwapStrategy(swapStrategy());
setGlColorCorrection(kwinConfig.readEntry("GLColorCorrection", false));
auto type = [&kwinConfig]{
const QString backend = kwinConfig.readEntry("Backend", "OpenGL");
@ -127,7 +124,6 @@ void Compositing::defaults()
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 @@ int Compositing::glSwapStrategy() const
return m_glSwapStrategy;
}
bool Compositing::glColorCorrection() const
{
return m_glColorCorrection;
}
int Compositing::compositingType() const
{
return m_compositingType;
@ -216,15 +207,6 @@ void Compositing::setAnimationSpeed(int speed)
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 @@ void Compositing::save()
}
};
kwinConfig.writeEntry("GLPreferBufferSwap", swapStrategy());
kwinConfig.writeEntry("GLColorCorrection", glColorCorrection());
QString backend;
bool glCore = false;
switch (compositingType()) {

View File

@ -41,7 +41,6 @@ class Compositing : public QObject
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 @@ public:
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 @@ public:
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 @@ Q_SIGNALS:
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 @@ private:
int m_glScaleFilter;
bool m_xrScaleFilter;
int m_glSwapStrategy;
bool m_glColorCorrection;
int m_compositingType;
bool m_compositingEnabled;
bool m_changed;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>462</width>
<height>377</height>
<height>349</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@ -21,14 +21,14 @@
<property name="visible">
<bool>false</bool>
</property>
<property name="text" stdset="0">
<property name="text">
<string>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.</string>
</property>
<property name="wordWrap" stdset="0">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
@ -38,10 +38,10 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="text" stdset="0">
<property name="text">
<string>Scale method &quot;Accurate&quot; is not supported by all hardware and can cause performance regressions and rendering artifacts.</string>
</property>
<property name="wordWrap" stdset="0">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
@ -51,7 +51,7 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="wordWrap" stdset="0">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
@ -61,10 +61,10 @@ Alternatively, you might want to use the XRender backend instead.</string>
<property name="visible">
<bool>false</bool>
</property>
<property name="text" stdset="0">
<property name="text">
<string>Keeping the window thumbnail always interferes with the minimized state of windows. This can result in windows not suspending their work when minimized.</string>
</property>
<property name="wordWrap" stdset="0">
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
@ -269,21 +269,7 @@ Alternatively, you might want to use the XRender backend instead.</string>
</item>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Experimental:</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="colorCorrection">
<property name="text">
<string>Enable color correction</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="windowsBlockCompositing">
<property name="toolTip">
<string>Applications can set a hint to block compositing when the window is open.

View File

@ -167,11 +167,6 @@ void KWinCompositingSettings::init()
}
);
// 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 @@ void KWinCompositingSettings::init()
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,

View File

@ -243,9 +243,6 @@
<entry name="GLLegacy" type="Bool">
<default>false</default>
</entry>
<entry name="GLColorCorrection" type="Bool">
<default>false</default>
</entry>
<entry name="XRenderSmoothScale" type="Bool">
<default>false</default>
</entry>

View File

@ -82,7 +82,6 @@ set(kwin_GLUTILSLIB_SRCS
kwingltexture.cpp
kwinglutils_funcs.cpp
kwinglplatform.cpp
kwinglcolorcorrection.cpp
logging.cpp
)
@ -90,7 +89,7 @@ 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}

View File

@ -1,674 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2012 Casian Andrei <skeletk13@gmail.com>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "kwinglcolorcorrection.h"
#include "kwinglcolorcorrection_p.h"
#include "kwinglplatform.h"
#include "kwinglutils.h"
#include "logging_p.h"
#include <QByteArrayMatcher>
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusPendingCall>
#include <QDBusPendingCallWatcher>
#include <QPair>
#include <QVector3D>
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<QByteArray> 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<quint8> 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

View File

@ -1,106 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2012 Casian Andrei <skeletk13@gmail.com>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_COLOR_CORRECTION_H
#define KWIN_COLOR_CORRECTION_H
#include <kwinglutils_export.h>
#include <QObject>
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

View File

@ -1,168 +0,0 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2012 Casian Andrei <skeletk13@gmail.com>
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 <http://www.gnu.org/licenses/>.
*********************************************************************/
#ifndef KWIN_COLOR_CORRECTION_P_H_
#define KWIN_COLOR_CORRECTION_P_H_
#include "kwinglcolorcorrection.h"
#include "kwinglutils_funcs.h"
#include <QDBusAbstractInterface>
#include <QDBusMetaType>
#include <QDBusPendingReply>
#include <QRect>
#include <QVector>
class QDBusPendingCallWatcher;
/*
* Clut
* All this should be the same as in the color server code, in kolor-manager
*/
typedef QVector<quint16> Clut;
typedef QList<Clut> ClutList;
typedef struct { QRect r; Clut c; } RegionalClut;
typedef QMultiMap<uint, RegionalClut> 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<GLuint> 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_

View File

@ -24,7 +24,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// 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 @@ bool checkGLError(const char* txt)
// GLShader
//****************************************
bool GLShader::sColorCorrect = false;
GLShader::GLShader(unsigned int flags)
: mValid(false)
, mLocationsResolved(false)
@ -230,10 +227,6 @@ const QByteArray GLShader::prepareSource(GLenum shaderType, const QByteArray &so
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 @@ void GLShader::resolveLocations()
mFloatLocation[Saturation] = uniformLocation("saturation");
mIntLocation[ColorCorrectionLookupTextureUnit] = uniformLocation("u_ccLookupTexture");
mColorLocation[Color] = uniformLocation("geometryColor");
mLocationsResolved = true;

View File

@ -139,7 +139,6 @@ public:
enum IntUniform {
AlphaToOne, ///< @deprecated no longer used
ColorCorrectionLookupTextureUnit,
IntUniformCount
};
@ -178,10 +177,6 @@ private:
int mIntLocation[IntUniformCount];
int mColorLocation[ColorUniformCount];
static bool sColorCorrect;
friend class ColorCorrection;
friend class ColorCorrectionPrivate;
friend class ShaderManager;
};

View File

@ -115,7 +115,6 @@ Options::Options(QObject *parent)
, 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 @@ void Options::setGlSmoothScale(int glSmoothScale)
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 @@ void Options::reloadCompositingSettings(bool force)
c = 0;
setGlPreferBufferSwap(c);
setColorCorrected(config.readEntry("GLColorCorrection", Options::defaultColorCorrected()));
m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false);
HiddenPreviews previews = Options::defaultHiddenPreviews();

View File

@ -175,7 +175,6 @@ class KWIN_EXPORT Options : public QObject
* -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 @@ public:
int glSmoothScale() const {
return m_glSmoothScale;
}
bool isColorCorrected() const {
return m_colorCorrected;
}
// XRender
bool isXrenderSmoothScale() const {
return m_xrenderSmoothScale;
@ -743,9 +739,6 @@ public:
static int defaultGlSmoothScale() {
return 2;
}
static bool defaultColorCorrected() {
return false;
}
static bool defaultXrenderSmoothScale() {
return false;
}
@ -845,7 +838,6 @@ Q_SIGNALS:
void compositingInitializedChanged();
void hiddenPreviewsChanged();
void glSmoothScaleChanged();
void colorCorrectedChanged();
void xrenderSmoothScaleChanged();
void maxFpsIntervalChanged();
void refreshRateChanged();
@ -859,9 +851,6 @@ Q_SIGNALS:
void configChanged();
public Q_SLOTS:
void setColorCorrected(bool colorCorrected = false);
private:
void setElectricBorders(int borders);
void syncFromKcfgc();
@ -894,7 +883,6 @@ private:
bool m_compositingInitialized;
HiddenPreviews m_hiddenPreviews;
int m_glSmoothScale;
bool m_colorCorrected;
bool m_xrenderSmoothScale;
qint64 m_maxFpsInterval;
// Settings that should be auto-detected

View File

@ -31,7 +31,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "platform.h"
#include "wayland_server.h"
#include <kwinglcolorcorrection.h>
#include <kwinglplatform.h>
#include "utils.h"
@ -992,7 +991,6 @@ bool SceneOpenGL2::supported(OpenGLBackend *backend)
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 @@ SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend, QObject *parent)
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 @@ void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region
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 @@ void SceneOpenGL2::resetLanczosFilter()
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 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData
if (!beginRenderWindow(mask, region, data))
return;
SceneOpenGL2 *scene = static_cast<SceneOpenGL2 *>(m_scene);
QMatrix4x4 windowMatrix = transformation(mask, data);
const QMatrix4x4 modelViewProjection = modelViewProjectionMatrix(mask, data);
const QMatrix4x4 mvpMatrix = modelViewProjection * windowMatrix;
@ -1541,10 +1493,6 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData
}
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))

View File

@ -32,7 +32,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace KWin
{
class ColorCorrection;
class LanczosFilter;
class OpenGLBackend;
class SyncManager;
@ -128,7 +127,6 @@ public:
static bool supported(OpenGLBackend *backend);
ColorCorrection *colorCorrection();
QMatrix4x4 projectionMatrix() const override { return m_projectionMatrix; }
QMatrix4x4 screenProjectionMatrix() const override { return m_screenProjectionMatrix; }
@ -141,7 +139,6 @@ protected:
virtual void updateProjectionMatrix() override;
private Q_SLOTS:
void slotColorCorrectedChanged(bool recreateShaders = true);
void resetLanczosFilter();
private:
@ -150,7 +147,6 @@ private:
private:
LanczosFilter *m_lanczosFilter;
QScopedPointer<ColorCorrection> m_colorCorrection;
QMatrix4x4 m_projectionMatrix;
QMatrix4x4 m_screenProjectionMatrix;
GLuint vao;