Merge branch 'color2'
Conflicts: kwin/libkwineffects/kwinglplatform.cpp
This commit is contained in:
commit
479be668d7
19 changed files with 1129 additions and 52 deletions
|
@ -130,6 +130,7 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
|
|||
|
||||
connect(ui.glVSync, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
connect(ui.glShaders, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
connect(ui.glColorCorrection, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
connect(m_showDetailedErrors, SIGNAL(triggered(bool)), SLOT(showDetailedEffectLoadingInformation()));
|
||||
connect(ui.ghns, SIGNAL(clicked(bool)), SLOT(slotGHNS()));
|
||||
|
||||
|
@ -384,6 +385,7 @@ void KWinCompositingConfig::loadAdvancedTab()
|
|||
|
||||
ui.glVSync->setChecked(config.readEntry("GLVSync", true));
|
||||
ui.glShaders->setChecked(!config.readEntry<bool>("GLLegacy", false));
|
||||
ui.glColorCorrection->setChecked(config.readEntry("GLColorCorrection", false));
|
||||
|
||||
toogleSmoothScaleUi(ui.compositingType->currentIndex());
|
||||
}
|
||||
|
@ -517,7 +519,7 @@ bool KWinCompositingConfig::saveAdvancedTab()
|
|||
|
||||
config.writeEntry("GLVSync", ui.glVSync->isChecked());
|
||||
config.writeEntry("GLLegacy", !ui.glShaders->isChecked());
|
||||
|
||||
config.writeEntry("GLColorCorrection", ui.glColorCorrection->isChecked());
|
||||
|
||||
return advancedChanged;
|
||||
}
|
||||
|
@ -755,6 +757,7 @@ void KWinCompositingConfig::defaults()
|
|||
ui.glScaleFilter->setCurrentIndex(2);
|
||||
ui.glVSync->setChecked(true);
|
||||
ui.glShaders->setChecked(true);
|
||||
ui.glColorCorrection->setChecked(false);
|
||||
}
|
||||
|
||||
QString KWinCompositingConfig::quickHelp() const
|
||||
|
|
|
@ -806,6 +806,17 @@ p, li { white-space: pre-wrap; }
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="glShaders">
|
||||
<property name="toolTip">
|
||||
<string>If enabled all rendering will be performed with Shaders written in the OpenGL Shading Language.
|
||||
On legacy hardware disabling Shaders can improve the performance.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use OpenGL 2 Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="glVSync">
|
||||
<property name="text">
|
||||
|
@ -816,14 +827,16 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="glShaders">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="glColorCorrection">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>If enabled all rendering will be performed with Shaders written in the OpenGL Shading Language.
|
||||
On legacy hardware disabling Shaders can improve the performance.</string>
|
||||
<string><p>Activates color correction if possible, using the Kolor-Manager. Requires OpenGL 2 Shaders to be enabled and Kolor-Manager to be installed. May fail silently.</p><p><strong>Experimental</strong>.</p></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use OpenGL 2 Shaders</string>
|
||||
<string>Enable color correction (experimental)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -921,12 +934,28 @@ On legacy hardware disabling Shaders can improve the performance.</string>
|
|||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>161</x>
|
||||
<y>64</y>
|
||||
<x>312</x>
|
||||
<y>119</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>194</x>
|
||||
<y>119</y>
|
||||
<x>345</x>
|
||||
<y>146</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>glShaders</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>glColorCorrection</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>204</x>
|
||||
<y>315</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>204</x>
|
||||
<y>358</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
|
|
@ -29,6 +29,7 @@ set(kwin_GLUTILSLIB_SRCS
|
|||
kwingltexture.cpp
|
||||
kwinglutils_funcs.cpp
|
||||
kwinglplatform.cpp
|
||||
kwinglcolorcorrection.cpp
|
||||
)
|
||||
|
||||
macro( KWIN4_ADD_GLUTILS_BACKEND name glinclude )
|
||||
|
|
|
@ -211,6 +211,7 @@ public:
|
|||
qreal decorationOpacity;
|
||||
qreal saturation;
|
||||
qreal brightness;
|
||||
int screen;
|
||||
};
|
||||
|
||||
WindowPaintData::WindowPaintData(EffectWindow* w)
|
||||
|
@ -223,6 +224,7 @@ WindowPaintData::WindowPaintData(EffectWindow* w)
|
|||
setDecorationOpacity(1.0);
|
||||
setSaturation(1.0);
|
||||
setBrightness(1.0);
|
||||
setScreen(0);
|
||||
}
|
||||
|
||||
WindowPaintData::WindowPaintData(const WindowPaintData &other)
|
||||
|
@ -242,6 +244,7 @@ WindowPaintData::WindowPaintData(const WindowPaintData &other)
|
|||
setDecorationOpacity(other.decorationOpacity());
|
||||
setSaturation(other.saturation());
|
||||
setBrightness(other.brightness());
|
||||
setScreen(other.screen());
|
||||
}
|
||||
|
||||
WindowPaintData::~WindowPaintData()
|
||||
|
@ -269,6 +272,11 @@ qreal WindowPaintData::brightness() const
|
|||
return d->brightness;
|
||||
}
|
||||
|
||||
int WindowPaintData::screen() const
|
||||
{
|
||||
return d->screen;
|
||||
}
|
||||
|
||||
void WindowPaintData::setDecorationOpacity(qreal opacity)
|
||||
{
|
||||
d->decorationOpacity = opacity;
|
||||
|
@ -289,6 +297,11 @@ void WindowPaintData::setBrightness(qreal brightness)
|
|||
d->brightness = brightness;
|
||||
}
|
||||
|
||||
void WindowPaintData::setScreen(int screen) const
|
||||
{
|
||||
d->screen = screen;
|
||||
}
|
||||
|
||||
qreal WindowPaintData::multiplyDecorationOpacity(qreal factor)
|
||||
{
|
||||
d->decorationOpacity *= factor;
|
||||
|
|
|
@ -1943,6 +1943,18 @@ public:
|
|||
* @since 4.10
|
||||
**/
|
||||
qreal multiplyBrightness(qreal factor);
|
||||
/**
|
||||
* The screen number for which the painting should be done.
|
||||
* This affects color correction (different screens may need different
|
||||
* color correction lookup tables because they have different ICC profiles).
|
||||
* @return screen for which painting should be done
|
||||
*/
|
||||
int screen() const;
|
||||
/**
|
||||
* @param screen New screen number
|
||||
* A value less than 0 will indicate that a default profile should be done.
|
||||
*/
|
||||
void setScreen(int screen) const;
|
||||
WindowQuadList quads;
|
||||
/**
|
||||
* Shader to be used for rendering, if any.
|
||||
|
|
629
libkwineffects/kwinglcolorcorrection.cpp
Normal file
629
libkwineffects/kwinglcolorcorrection.cpp
Normal file
|
@ -0,0 +1,629 @@
|
|||
/********************************************************************
|
||||
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 <KDebug>
|
||||
|
||||
#include <QByteArrayMatcher>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QPair>
|
||||
#include <QVector3D>
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
#define CC_TEXTURE_INTERNAL_FORMAT GL_RGB
|
||||
|
||||
/*
|
||||
* A bit of ugliness to allow building with OpenGL ES < 3, without
|
||||
* ifdef's everywhere in the code. These should not actually be used anywhere.
|
||||
*/
|
||||
#ifndef GL_TEXTURE_3D
|
||||
#define GL_TEXTURE_3D 0x806F // From OES_texture_3D extension
|
||||
#define GL_TEXTURE_WRAP_R 0x8072 // From OES_texture_3D extension
|
||||
void glTexImage3D(GLenum, int, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *)
|
||||
{
|
||||
Q_ASSERT(false); // Execution must not reach here
|
||||
}
|
||||
#endif // defined(GL_TEXTURE_3D)
|
||||
|
||||
#else // KWIN_HAVE_OPENGLES
|
||||
#define CC_TEXTURE_INTERNAL_FORMAT GL_RGB16
|
||||
#endif // KWIN_HAVE_OPENGLES
|
||||
|
||||
|
||||
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)
|
||||
kWarning(1212) << "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("getVersionInfo"));
|
||||
}
|
||||
|
||||
QDBusPendingReply< ClutList > ColorServerInterface::getOutputCluts()
|
||||
{
|
||||
return QDBusPendingReply< ClutList >(asyncCall("getOutputCluts"));
|
||||
}
|
||||
|
||||
QDBusPendingReply< RegionalClutMap > ColorServerInterface::getRegionCluts()
|
||||
{
|
||||
return QDBusPendingReply< RegionalClutMap >(asyncCall("getRegionCluts"));
|
||||
}
|
||||
|
||||
void ColorServerInterface::callFinishedSlot(QDBusPendingCallWatcher *watcher)
|
||||
{
|
||||
if (watcher == m_versionInfoWatcher) {
|
||||
kDebug(1212) << "Version info call finished";
|
||||
QDBusPendingReply< uint > reply = *watcher;
|
||||
if (reply.isError()) {
|
||||
kWarning(1212) << reply.error();
|
||||
if (!m_signaledFail)
|
||||
emit updateFailed();
|
||||
m_signaledFail = true;
|
||||
return;
|
||||
} else {
|
||||
m_versionInfo = reply.value();
|
||||
m_versionInfoUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (watcher == m_outputClutsWatcher) {
|
||||
kDebug(1212) << "Output cluts call finished";
|
||||
QDBusPendingReply< ClutList > reply = *watcher;
|
||||
if (reply.isError()) {
|
||||
kWarning(1212) << reply.error();
|
||||
if (!m_signaledFail)
|
||||
emit updateFailed();
|
||||
m_signaledFail = true;
|
||||
return;
|
||||
} else {
|
||||
m_outputCluts = reply.value();
|
||||
m_outputClutsUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (watcher == m_regionClutsWatcher) {
|
||||
kDebug(1212) << "Region cluts call finished";
|
||||
QDBusPendingReply< RegionalClutMap > reply = *watcher;
|
||||
if (reply.isError()) {
|
||||
kWarning(1212) << 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) {
|
||||
kDebug(1212) << "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 / min(gl_FragColor.a, 1.0)).rgb;\n";
|
||||
|
||||
|
||||
/*
|
||||
* Color Correction
|
||||
*/
|
||||
|
||||
ColorCorrection::ColorCorrection(QObject *parent)
|
||||
: QObject(parent)
|
||||
, d_ptr(new ColorCorrectionPrivate(this))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ColorCorrection::~ColorCorrection()
|
||||
{
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
ColorCorrectionPrivate::ColorCorrectionPrivate(ColorCorrection *parent)
|
||||
: QObject(parent)
|
||||
, m_enabled(false)
|
||||
, m_hasError(false)
|
||||
, 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(
|
||||
"org.kde.kded",
|
||||
"/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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ColorCorrection::setEnabled(bool enabled)
|
||||
{
|
||||
Q_D(ColorCorrection);
|
||||
|
||||
if (enabled == d->m_enabled)
|
||||
return;
|
||||
|
||||
if (enabled && d->m_hasError) {
|
||||
kError(1212) << "cannot enable color correction";
|
||||
return;
|
||||
}
|
||||
|
||||
const GLPlatform *gl = GLPlatform::instance();
|
||||
if (enabled && gl->isGLES() && (gl->glVersion() >> 32) < 3) {
|
||||
kError(1212) << "color correction is not supported with OpenGL ES < 3.0";
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
// Update all profiles and regions
|
||||
d->m_csi->update();
|
||||
} else {
|
||||
d->deleteCCTextures();
|
||||
}
|
||||
|
||||
d->m_enabled = enabled;
|
||||
GLShader::sColorCorrect = enabled;
|
||||
kDebug(1212) << enabled;
|
||||
}
|
||||
|
||||
void ColorCorrection::setupForOutput(int screen)
|
||||
{
|
||||
Q_D(ColorCorrection);
|
||||
|
||||
GLShader *shader = ShaderManager::instance()->getBoundShader();
|
||||
if (!shader) {
|
||||
kError(1212) << "no bound shader for color correction setup";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shader->setUniform("u_ccLookupTexture", d->m_ccTextureUnit)) {
|
||||
// This means the color correction shaders are probably not loaded
|
||||
if (!d->m_enabled)
|
||||
return;
|
||||
kError(1212) << "unable to set uniform for the color correction lookup texture";
|
||||
}
|
||||
|
||||
d->setupCCTextures();
|
||||
|
||||
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 correctiont texture
|
||||
glBindTexture(GL_TEXTURE_3D, d->m_outputCCTextures[screen]);
|
||||
}
|
||||
|
||||
glActiveTexture(activeTexture);
|
||||
|
||||
checkGLError("setupForOutput");
|
||||
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
void ColorCorrectionPrivate::setupCCTextures()
|
||||
{
|
||||
if (m_ccTextureUnit < 0) {
|
||||
GLint maxUnits = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits);
|
||||
m_ccTextureUnit = maxUnits - 1;
|
||||
}
|
||||
|
||||
// Dummy texture first
|
||||
if (!m_dummyCCTexture) {
|
||||
glGenTextures(1, &m_dummyCCTexture);
|
||||
setupCCTexture(m_dummyCCTexture, m_dummyClut);
|
||||
}
|
||||
|
||||
// Setup actual color correction textures
|
||||
if (m_outputCCTextures.isEmpty() && !m_outputCluts->isEmpty()) {
|
||||
kDebug(1212) << "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)
|
||||
setupCCTexture(m_outputCCTextures[i], m_outputCluts->at(i));
|
||||
}
|
||||
|
||||
// TODO Handle errors (what if a texture isn't generated?)
|
||||
checkGLError("setupCCTextures");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
checkGLError("deleteCCTextures");
|
||||
}
|
||||
|
||||
void ColorCorrectionPrivate::setupCCTexture(GLuint texture, const Clut& clut)
|
||||
{
|
||||
if ((uint) clut.size() != CLUT_ELEMENT_COUNT) {
|
||||
kError(1212) << "cannot setup CC texture: invalid color lookup table";
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug(1212) << texture;
|
||||
|
||||
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);
|
||||
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, CC_TEXTURE_INTERNAL_FORMAT,
|
||||
LUT_GRID_POINTS, LUT_GRID_POINTS, LUT_GRID_POINTS,
|
||||
0, GL_RGB, GL_UNSIGNED_SHORT, clut.data());
|
||||
|
||||
|
||||
checkGLError("setupCCTexture");
|
||||
}
|
||||
|
||||
void ColorCorrectionPrivate::colorServerUpdateSucceededSlot()
|
||||
{
|
||||
Q_Q(ColorCorrection);
|
||||
|
||||
kDebug(1212) << "Update of color profiles succeeded";
|
||||
|
||||
// Force the color correction textures to be recreated
|
||||
deleteCCTextures();
|
||||
|
||||
emit q->changed();
|
||||
}
|
||||
|
||||
void ColorCorrectionPrivate::colorServerUpdateFailedSlot()
|
||||
{
|
||||
Q_Q(ColorCorrection);
|
||||
|
||||
kError(1212) << "Update of color profiles failed";
|
||||
|
||||
q->setEnabled(false);
|
||||
}
|
||||
|
||||
} // KWin namespace
|
95
libkwineffects/kwinglcolorcorrection.h
Normal file
95
libkwineffects/kwinglcolorcorrection.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/********************************************************************
|
||||
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_funcs.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QRect>
|
||||
|
||||
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 KWIN_EXPORT ColorCorrection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ColorCorrection(QObject *parent = 0);
|
||||
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);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Enables or disables color correction. Compositing should be restarted
|
||||
* for changes to take effect.
|
||||
*/
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
ColorCorrectionPrivate * const d_ptr;
|
||||
Q_DECLARE_PRIVATE(ColorCorrection)
|
||||
};
|
||||
|
||||
} // KWin namespace
|
||||
|
||||
#endif // KWIN_COLOR_CORRECTION_H
|
165
libkwineffects/kwinglcolorcorrection_p.h
Normal file
165
libkwineffects/kwinglcolorcorrection_p.h
Normal file
|
@ -0,0 +1,165 @@
|
|||
/********************************************************************
|
||||
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 <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();
|
||||
|
||||
void setupCCTextures();
|
||||
void deleteCCTextures();
|
||||
static void setupCCTexture(GLuint texture, const Clut &clut);
|
||||
|
||||
public slots:
|
||||
void colorServerUpdateSucceededSlot();
|
||||
void colorServerUpdateFailedSlot();
|
||||
|
||||
public:
|
||||
bool m_enabled;
|
||||
bool m_hasError;
|
||||
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 = 0);
|
||||
virtual ~ColorServerInterface();
|
||||
|
||||
uint versionInfo() const;
|
||||
const ClutList& outputCluts() const;
|
||||
const RegionalClutMap& regionCluts() const;
|
||||
|
||||
public slots:
|
||||
void update();
|
||||
|
||||
signals:
|
||||
void updateSucceeded();
|
||||
void updateFailed();
|
||||
void outputClutsChanged();
|
||||
void regionClutsChanged();
|
||||
|
||||
private:
|
||||
QDBusPendingReply< uint > getVersionInfo();
|
||||
QDBusPendingReply< ClutList > getOutputCluts();
|
||||
QDBusPendingReply< RegionalClutMap > getRegionCluts();
|
||||
|
||||
private 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_
|
|
@ -1031,5 +1031,14 @@ CompositingType GLPlatform::recommendedCompositor() const
|
|||
return m_recommendedCompositor;
|
||||
}
|
||||
|
||||
bool GLPlatform::isGLES() const
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace KWin
|
||||
|
||||
|
|
|
@ -295,6 +295,10 @@ public:
|
|||
* @since 4.9
|
||||
**/
|
||||
bool isLooseBinding() const;
|
||||
/**
|
||||
* @returns Whether OpenGL ES is used
|
||||
*/
|
||||
bool isGLES() const;
|
||||
|
||||
/**
|
||||
* @returns The CompositingType recommended by the driver.
|
||||
|
|
|
@ -24,6 +24,7 @@ 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 "kwinglobals.h"
|
||||
#include "kwineffects.h"
|
||||
#include "kwinglplatform.h"
|
||||
|
@ -258,6 +259,8 @@ void popMatrix()
|
|||
// GLShader
|
||||
//****************************************
|
||||
|
||||
bool GLShader::sColorCorrect = false;
|
||||
|
||||
GLShader::GLShader()
|
||||
: mProgram(0)
|
||||
, mValid(false)
|
||||
|
@ -299,10 +302,8 @@ bool GLShader::loadFromFiles(const QString &vertexFile, const QString &fragmentF
|
|||
return load(vertexSource, fragmentSource);
|
||||
}
|
||||
|
||||
bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &source) const
|
||||
const QByteArray GLShader::prepareSource(GLenum shaderType, const QByteArray &source) const
|
||||
{
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
|
||||
// Prepare the source code
|
||||
QByteArray ba;
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
|
@ -313,7 +314,19 @@ bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &sour
|
|||
}
|
||||
ba.append(source);
|
||||
|
||||
const char* src = ba.constData();
|
||||
// Inject color correction code for fragment shaders, if possible
|
||||
if (shaderType == GL_FRAGMENT_SHADER && sColorCorrect)
|
||||
ba = ColorCorrection::prepareFragmentShader(ba);
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &source) const
|
||||
{
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
|
||||
QByteArray preparedSource = prepareSource(shaderType, source);
|
||||
const char* src = preparedSource.constData();
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
|
||||
// Compile the shader
|
||||
|
|
|
@ -204,6 +204,7 @@ protected:
|
|||
GLShader();
|
||||
bool loadFromFiles(const QString& vertexfile, const QString& fragmentfile);
|
||||
bool load(const QByteArray &vertexSource, const QByteArray &fragmentSource);
|
||||
const QByteArray prepareSource(GLenum shaderType, const QByteArray &sourceCode) const;
|
||||
bool compile(GLuint program, GLenum shaderType, const QByteArray &sourceCode) const;
|
||||
void bind();
|
||||
void unbind();
|
||||
|
@ -219,6 +220,9 @@ private:
|
|||
int mFloatLocation[FloatUniformCount];
|
||||
int mIntLocation[IntUniformCount];
|
||||
|
||||
static bool sColorCorrect;
|
||||
|
||||
friend class ColorCorrection;
|
||||
friend class ShaderManager;
|
||||
};
|
||||
|
||||
|
|
12
options.cpp
12
options.cpp
|
@ -148,6 +148,7 @@ Options::Options(QObject *parent)
|
|||
, m_unredirectFullscreen(Options::defaultUnredirectFullscreen())
|
||||
, m_glSmoothScale(Options::defaultGlSmoothScale())
|
||||
, m_glVSync(Options::defaultGlVSync())
|
||||
, m_colorCorrected(Options::defaultColorCorrected())
|
||||
, m_xrenderSmoothScale(Options::defaultXrenderSmoothScale())
|
||||
, m_maxFpsInterval(Options::defaultMaxFpsInterval())
|
||||
, m_refreshRate(Options::defaultRefreshRate())
|
||||
|
@ -709,6 +710,15 @@ void Options::setGlVSync(bool glVSync)
|
|||
emit glVSyncChanged();
|
||||
}
|
||||
|
||||
void Options::setColorCorrected(bool colorCorrected)
|
||||
{
|
||||
if (m_colorCorrected == colorCorrected) {
|
||||
return;
|
||||
}
|
||||
m_colorCorrected = colorCorrected;
|
||||
emit colorCorrectedChanged();
|
||||
}
|
||||
|
||||
void Options::setXrenderSmoothScale(bool xrenderSmoothScale)
|
||||
{
|
||||
if (m_xrenderSmoothScale == xrenderSmoothScale) {
|
||||
|
@ -1009,6 +1019,8 @@ void Options::reloadCompositingSettings(bool force)
|
|||
}
|
||||
setGlLegacy(config.readEntry("GLLegacy", Options::defaultGlLegacy()));
|
||||
|
||||
setColorCorrected(config.readEntry("GLColorCorrection", Options::defaultColorCorrected()));
|
||||
|
||||
m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false);
|
||||
|
||||
HiddenPreviews previews = Options::defaultHiddenPreviews();
|
||||
|
|
10
options.h
10
options.h
|
@ -183,6 +183,7 @@ class Options : public QObject, public KDecorationOptions
|
|||
**/
|
||||
Q_PROPERTY(int glSmoothScale READ glSmoothScale WRITE setGlSmoothScale NOTIFY glSmoothScaleChanged)
|
||||
Q_PROPERTY(bool glVSync READ isGlVSync WRITE setGlVSync NOTIFY glVSyncChanged)
|
||||
Q_PROPERTY(bool colorCorrected READ isColorCorrected WRITE setColorCorrected NOTIFY colorCorrectedChanged)
|
||||
Q_PROPERTY(bool xrenderSmoothScale READ isXrenderSmoothScale WRITE setXrenderSmoothScale NOTIFY xrenderSmoothScaleChanged)
|
||||
Q_PROPERTY(uint maxFpsInterval READ maxFpsInterval WRITE setMaxFpsInterval NOTIFY maxFpsIntervalChanged)
|
||||
Q_PROPERTY(uint refreshRate READ refreshRate WRITE setRefreshRate NOTIFY refreshRateChanged)
|
||||
|
@ -552,6 +553,9 @@ public:
|
|||
bool isGlVSync() const {
|
||||
return m_glVSync;
|
||||
}
|
||||
bool isColorCorrected() const {
|
||||
return m_colorCorrected;
|
||||
}
|
||||
// XRender
|
||||
bool isXrenderSmoothScale() const {
|
||||
return m_xrenderSmoothScale;
|
||||
|
@ -635,6 +639,7 @@ public:
|
|||
void setUnredirectFullscreen(bool unredirectFullscreen);
|
||||
void setGlSmoothScale(int glSmoothScale);
|
||||
void setGlVSync(bool glVSync);
|
||||
void setColorCorrected(bool colorCorrected);
|
||||
void setXrenderSmoothScale(bool xrenderSmoothScale);
|
||||
void setMaxFpsInterval(uint maxFpsInterval);
|
||||
void setRefreshRate(uint refreshRate);
|
||||
|
@ -841,6 +846,9 @@ public:
|
|||
static bool defaultGlVSync() {
|
||||
return true;
|
||||
}
|
||||
static bool defaultColorCorrected() {
|
||||
return false;
|
||||
}
|
||||
static bool defaultXrenderSmoothScale() {
|
||||
return false;
|
||||
}
|
||||
|
@ -942,6 +950,7 @@ Q_SIGNALS:
|
|||
void unredirectFullscreenChanged();
|
||||
void glSmoothScaleChanged();
|
||||
void glVSyncChanged();
|
||||
void colorCorrectedChanged();
|
||||
void xrenderSmoothScaleChanged();
|
||||
void maxFpsIntervalChanged();
|
||||
void refreshRateChanged();
|
||||
|
@ -985,6 +994,7 @@ private:
|
|||
bool m_unredirectFullscreen;
|
||||
int m_glSmoothScale;
|
||||
bool m_glVSync;
|
||||
bool m_colorCorrected;
|
||||
bool m_xrenderSmoothScale;
|
||||
uint m_maxFpsInterval;
|
||||
// Settings that should be auto-detected
|
||||
|
|
|
@ -10,7 +10,7 @@ varying vec2 varyingTexCoords;
|
|||
void main() {
|
||||
vec4 tex = texture2D(sampler, varyingTexCoords);
|
||||
|
||||
tex.a += float(u_forceAlpha);
|
||||
tex.a = min(tex.a + float(u_forceAlpha), 1.0);
|
||||
|
||||
if (saturation != 1.0) {
|
||||
tex.rgb = mix(vec3(dot( vec3( 0.30, 0.59, 0.11 ), tex.rgb )), tex.rgb, saturation);
|
||||
|
|
13
scene.cpp
13
scene.cpp
|
@ -75,12 +75,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "client.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "lanczosfilter.h"
|
||||
#include "overlaywindow.h"
|
||||
#include "shadow.h"
|
||||
|
||||
|
@ -440,16 +438,7 @@ void Scene::finalPaintWindow(EffectWindowImpl* w, int mask, QRegion region, Wind
|
|||
// will be eventually called from drawWindow()
|
||||
void Scene::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
|
||||
{
|
||||
if (mask & PAINT_WINDOW_LANCZOS) {
|
||||
if (lanczos_filter.isNull()) {
|
||||
lanczos_filter = new LanczosFilter(this);
|
||||
// recreate the lanczos filter when the screen gets resized
|
||||
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), lanczos_filter.data(), SLOT(deleteLater()));
|
||||
connect(QApplication::desktop(), SIGNAL(resized(int)), lanczos_filter.data(), SLOT(deleteLater()));
|
||||
}
|
||||
lanczos_filter.data()->performPaint(w, mask, region, data);
|
||||
} else
|
||||
w->sceneWindow()->performPaint(mask, region, data);
|
||||
w->sceneWindow()->performPaint(mask, region, data);
|
||||
}
|
||||
|
||||
bool Scene::waitSyncAvailable() const
|
||||
|
|
4
scene.h
4
scene.h
|
@ -32,7 +32,6 @@ class Workspace;
|
|||
class Deleted;
|
||||
class EffectFrameImpl;
|
||||
class EffectWindowImpl;
|
||||
class LanczosFilter;
|
||||
class OverlayWindow;
|
||||
class Shadow;
|
||||
|
||||
|
@ -125,7 +124,7 @@ protected:
|
|||
// shared implementation, starts painting the window
|
||||
virtual void paintWindow(Window* w, int mask, QRegion region, WindowQuadList quads);
|
||||
// called after all effects had their drawWindow() called
|
||||
void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data);
|
||||
virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data);
|
||||
// compute time since the last repaint
|
||||
void updateTimeDiff();
|
||||
// saved data for 2nd pass of optimized screen painting
|
||||
|
@ -154,7 +153,6 @@ protected:
|
|||
int time_diff;
|
||||
QElapsedTimer last_time;
|
||||
Workspace* wspace;
|
||||
QWeakPointer<LanczosFilter> lanczos_filter;
|
||||
};
|
||||
|
||||
// The base class for windows representations in composite backends
|
||||
|
|
101
scene_opengl.cpp
101
scene_opengl.cpp
|
@ -76,6 +76,7 @@ Sources and other compositing managers:
|
|||
|
||||
#include <kxerrorhandler.h>
|
||||
|
||||
#include <kwinglcolorcorrection.h>
|
||||
#include <kwinglplatform.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -83,6 +84,7 @@ Sources and other compositing managers:
|
|||
#include "composite.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "lanczosfilter.h"
|
||||
#include "overlaywindow.h"
|
||||
#include "paintredirector.h"
|
||||
|
||||
|
@ -95,6 +97,7 @@ Sources and other compositing managers:
|
|||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#include <qpainter.h>
|
||||
#include <QDesktopWidget>
|
||||
#include <QVector2D>
|
||||
#include <QVector4D>
|
||||
#include <QMatrix4x4>
|
||||
|
@ -467,7 +470,14 @@ bool SceneOpenGL2::supported(OpenGLBackend *backend)
|
|||
|
||||
SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend)
|
||||
: SceneOpenGL(Workspace::self(), backend)
|
||||
, m_colorCorrection(new ColorCorrection(this))
|
||||
{
|
||||
// Initialize color correction before the shaders
|
||||
kDebug(1212) << "Color correction:" << options->isColorCorrected();
|
||||
m_colorCorrection->setEnabled(options->isColorCorrected());
|
||||
connect(m_colorCorrection, SIGNAL(changed()), Compositor::self(), SLOT(addRepaintFull()));
|
||||
connect(options, SIGNAL(colorCorrectedChanged()), this, SLOT(slotColorCorrectedChanged()));
|
||||
|
||||
if (!ShaderManager::instance()->isValid()) {
|
||||
kDebug(1212) << "No Scene Shaders available";
|
||||
return;
|
||||
|
@ -515,6 +525,52 @@ SceneOpenGL::Window *SceneOpenGL2::createWindow(Toplevel *t)
|
|||
return new SceneOpenGL2Window(t);
|
||||
}
|
||||
|
||||
void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
|
||||
{
|
||||
if (options->isColorCorrected()) {
|
||||
// Split the painting for separate screens
|
||||
int numScreens = Workspace::self()->numScreens();
|
||||
for (int screen = 0; screen < numScreens; ++ screen) {
|
||||
QRegion regionForScreen(region);
|
||||
if (numScreens > 1)
|
||||
regionForScreen = region.intersected(Workspace::self()->screenGeometry(screen));
|
||||
|
||||
data.setScreen(screen);
|
||||
performPaintWindow(w, mask, regionForScreen, data);
|
||||
}
|
||||
} else {
|
||||
performPaintWindow(w, mask, region, data);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL2::performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
|
||||
{
|
||||
if (mask & PAINT_WINDOW_LANCZOS) {
|
||||
if (m_lanczosFilter.isNull()) {
|
||||
m_lanczosFilter = new LanczosFilter(this);
|
||||
// recreate the lanczos filter when the screen gets resized
|
||||
connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), m_lanczosFilter.data(), SLOT(deleteLater()));
|
||||
connect(QApplication::desktop(), SIGNAL(resized(int)), m_lanczosFilter.data(), SLOT(deleteLater()));
|
||||
}
|
||||
m_lanczosFilter.data()->performPaint(w, mask, region, data);
|
||||
} else
|
||||
w->sceneWindow()->performPaint(mask, region, data);
|
||||
}
|
||||
|
||||
ColorCorrection *SceneOpenGL2::colorCorrection()
|
||||
{
|
||||
return m_colorCorrection;
|
||||
}
|
||||
|
||||
void SceneOpenGL2::slotColorCorrectedChanged()
|
||||
{
|
||||
m_colorCorrection->setEnabled(options->isColorCorrected());
|
||||
|
||||
// Reload all shaders
|
||||
ShaderManager::cleanup();
|
||||
ShaderManager::instance();
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneOpenGL1
|
||||
//****************************************
|
||||
|
@ -711,12 +767,12 @@ SceneOpenGL::TexturePrivate::~TexturePrivate()
|
|||
|
||||
SceneOpenGL::Window::Window(Toplevel* c)
|
||||
: Scene::Window(c)
|
||||
, m_scene(NULL)
|
||||
, texture(NULL)
|
||||
, topTexture(NULL)
|
||||
, leftTexture(NULL)
|
||||
, rightTexture(NULL)
|
||||
, bottomTexture(NULL)
|
||||
, m_scene(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -895,9 +951,9 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
|
|||
WindowQuadList contentQuads = data.quads.select(WindowQuadContents);
|
||||
if (!contentQuads.empty()) {
|
||||
texture->bind();
|
||||
prepareStates(Content, data.opacity(), data.brightness(), data.saturation());
|
||||
prepareStates(Content, data.opacity(), data.brightness(), data.saturation(), data.screen());
|
||||
renderQuads(mask, region, contentQuads, texture, false, hardwareClipping);
|
||||
restoreStates(Content, data.opacity(), data.brightness(), data.saturation());
|
||||
restoreStates(Content, data.opacity(), data.brightness(), data.saturation(), data.screen());
|
||||
texture->unbind();
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (m_scene && m_scene->debug) {
|
||||
|
@ -1025,10 +1081,10 @@ void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType
|
|||
decorationTexture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
decorationTexture->bind();
|
||||
|
||||
prepareStates(decorationType, data.opacity() * data.decorationOpacity(), data.brightness(), data.saturation());
|
||||
prepareStates(decorationType, data.opacity() * data.decorationOpacity(), data.brightness(), data.saturation(), data.screen());
|
||||
makeDecorationArrays(quads, rect, decorationTexture);
|
||||
GLVertexBuffer::streamingBuffer()->render(region, GL_TRIANGLES, hardwareClipping);
|
||||
restoreStates(decorationType, data.opacity() * data.decorationOpacity(), data.brightness(), data.saturation());
|
||||
restoreStates(decorationType, data.opacity() * data.decorationOpacity(), data.brightness(), data.saturation(), data.screen());
|
||||
decorationTexture->unbind();
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (m_scene && m_scene->debug) {
|
||||
|
@ -1062,9 +1118,9 @@ void SceneOpenGL::Window::paintShadow(const QRegion ®ion, const WindowPaintDa
|
|||
texture->setFilter(GL_NEAREST);
|
||||
texture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
texture->bind();
|
||||
prepareStates(Shadow, data.opacity(), data.brightness(), data.saturation());
|
||||
prepareStates(Shadow, data.opacity(), data.brightness(), data.saturation(), data.screen());
|
||||
renderQuads(0, region, quads, texture, true, hardwareClipping);
|
||||
restoreStates(Shadow, data.opacity(), data.brightness(), data.saturation());
|
||||
restoreStates(Shadow, data.opacity(), data.brightness(), data.saturation(), data.screen());
|
||||
texture->unbind();
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (m_scene && m_scene->debug) {
|
||||
|
@ -1212,6 +1268,8 @@ void SceneOpenGL2Window::beginRenderWindow(int mask, const WindowPaintData &data
|
|||
}
|
||||
|
||||
shader->setUniform(GLShader::WindowTransformation, transformation(mask, data));
|
||||
|
||||
static_cast<SceneOpenGL2*>(m_scene)->colorCorrection()->setupForOutput(data.screen());
|
||||
}
|
||||
|
||||
void SceneOpenGL2Window::endRenderWindow(const WindowPaintData &data)
|
||||
|
@ -1221,7 +1279,7 @@ void SceneOpenGL2Window::endRenderWindow(const WindowPaintData &data)
|
|||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL2Window::prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation)
|
||||
void SceneOpenGL2Window::prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen)
|
||||
{
|
||||
// setup blending of transparent windows
|
||||
bool opaque = isOpaque() && opacity == 1.0;
|
||||
|
@ -1230,11 +1288,15 @@ void SceneOpenGL2Window::prepareStates(TextureType type, qreal opacity, qreal br
|
|||
opaque = false;
|
||||
if (!opaque) {
|
||||
glEnable(GL_BLEND);
|
||||
if (alpha) {
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
if (options->isColorCorrected()) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
glBlendColor((float)opacity, (float)opacity, (float)opacity, (float)opacity);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_CONSTANT_ALPHA);
|
||||
if (alpha) {
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
glBlendColor((float)opacity, (float)opacity, (float)opacity, (float)opacity);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_CONSTANT_ALPHA);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1245,12 +1307,15 @@ void SceneOpenGL2Window::prepareStates(TextureType type, qreal opacity, qreal br
|
|||
shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
|
||||
shader->setUniform(GLShader::Saturation, saturation);
|
||||
shader->setUniform(GLShader::AlphaToOne, opaque ? 1 : 0);
|
||||
|
||||
static_cast<SceneOpenGL2*>(m_scene)->colorCorrection()->setupForOutput(screen);
|
||||
}
|
||||
|
||||
void SceneOpenGL2Window::restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation)
|
||||
void SceneOpenGL2Window::restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen)
|
||||
{
|
||||
Q_UNUSED(brightness);
|
||||
Q_UNUSED(saturation);
|
||||
Q_UNUSED(screen);
|
||||
bool opaque = isOpaque() && opacity == 1.0;
|
||||
if (type != Content)
|
||||
opaque = false;
|
||||
|
@ -1258,6 +1323,8 @@ void SceneOpenGL2Window::restoreStates(TextureType type, qreal opacity, qreal br
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
ShaderManager::instance()->getBoundShader()->setUniform(GLShader::AlphaToOne, 0);
|
||||
|
||||
static_cast<SceneOpenGL2*>(m_scene)->colorCorrection()->setupForOutput(-1);
|
||||
}
|
||||
|
||||
//***************************************
|
||||
|
@ -1284,8 +1351,10 @@ void SceneOpenGL1Window::endRenderWindow(const WindowPaintData &data)
|
|||
popMatrix();
|
||||
}
|
||||
|
||||
void SceneOpenGL1Window::prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation)
|
||||
void SceneOpenGL1Window::prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen)
|
||||
{
|
||||
Q_UNUSED(screen)
|
||||
|
||||
GLTexture *tex = textureForType(type);
|
||||
bool alpha = false;
|
||||
bool opaque = true;
|
||||
|
@ -1415,8 +1484,10 @@ void SceneOpenGL1Window::prepareStates(TextureType type, qreal opacity, qreal br
|
|||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL1Window::restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation)
|
||||
void SceneOpenGL1Window::restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen)
|
||||
{
|
||||
Q_UNUSED(screen)
|
||||
|
||||
GLTexture *tex = textureForType(type);
|
||||
if (opacity != 1.0 || saturation != 1.0 || brightness != 1.0f) {
|
||||
if (saturation != 1.0 && tex->saturationSupported()) {
|
||||
|
|
|
@ -30,6 +30,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
namespace KWin
|
||||
{
|
||||
class ColorCorrection;
|
||||
class LanczosFilter;
|
||||
class OpenGLBackend;
|
||||
|
||||
class SceneOpenGL
|
||||
|
@ -84,6 +86,7 @@ private:
|
|||
|
||||
class SceneOpenGL2 : public SceneOpenGL
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SceneOpenGL2(OpenGLBackend *backend);
|
||||
virtual ~SceneOpenGL2();
|
||||
|
@ -93,10 +96,23 @@ public:
|
|||
|
||||
static bool supported(OpenGLBackend *backend);
|
||||
|
||||
ColorCorrection *colorCorrection();
|
||||
|
||||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void doPaintBackground(const QVector< float >& vertices);
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data);
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotColorCorrectedChanged();
|
||||
|
||||
private:
|
||||
void performPaintWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data);
|
||||
|
||||
private:
|
||||
QWeakPointer<LanczosFilter> m_lanczosFilter;
|
||||
ColorCorrection *m_colorCorrection;
|
||||
};
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_1
|
||||
|
@ -226,8 +242,9 @@ protected:
|
|||
* @param opacity The opacity value to use for this rendering
|
||||
* @param brightness The brightness value to use for this rendering
|
||||
* @param saturation The saturation value to use for this rendering
|
||||
* @param screen The index of the screen to use for this rendering
|
||||
**/
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation) = 0;
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen) = 0;
|
||||
/**
|
||||
* @brief Restores the OpenGL rendering state after the texture with @p type has been rendered.
|
||||
*
|
||||
|
@ -235,8 +252,9 @@ protected:
|
|||
* @param opacity The opacity value used for the rendering
|
||||
* @param brightness The brightness value used for this rendering
|
||||
* @param saturation The saturation value used for this rendering
|
||||
* @param screen The index of the screen to use for this rendering
|
||||
**/
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation) = 0;
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen) = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the texture for the given @p type.
|
||||
|
@ -246,6 +264,9 @@ protected:
|
|||
**/
|
||||
GLTexture *textureForType(TextureType type);
|
||||
|
||||
protected:
|
||||
SceneOpenGL *m_scene;
|
||||
|
||||
private:
|
||||
template<class T>
|
||||
void paintDecorations(const WindowPaintData &data, const QRegion ®ion, bool hardwareClipping);
|
||||
|
@ -254,7 +275,6 @@ private:
|
|||
Texture *leftTexture;
|
||||
Texture *rightTexture;
|
||||
Texture *bottomTexture;
|
||||
SceneOpenGL *m_scene;
|
||||
};
|
||||
|
||||
class SceneOpenGL2Window : public SceneOpenGL::Window
|
||||
|
@ -266,8 +286,8 @@ public:
|
|||
protected:
|
||||
virtual void beginRenderWindow(int mask, const WindowPaintData &data);
|
||||
virtual void endRenderWindow(const WindowPaintData &data);
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation);
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation);
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen);
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen);
|
||||
};
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGL_1
|
||||
|
@ -280,8 +300,8 @@ public:
|
|||
protected:
|
||||
virtual void beginRenderWindow(int mask, const WindowPaintData &data);
|
||||
virtual void endRenderWindow(const WindowPaintData &data);
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation);
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation);
|
||||
virtual void prepareStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen);
|
||||
virtual void restoreStates(TextureType type, qreal opacity, qreal brightness, qreal saturation, int screen);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue