reintroduce prepaintscreen

* work also without blur enabled
* try to pass only the 3 color parameters
This commit is contained in:
Marco Martin 2014-01-06 21:43:03 +01:00
parent dabafc4988
commit 210f7d3eff
4 changed files with 126 additions and 16 deletions

View file

@ -22,7 +22,6 @@
#include "contrast.h" #include "contrast.h"
#include "contrastshader.h" #include "contrastshader.h"
// KConfigSkeleton // KConfigSkeleton
#include "contrastconfig.h"
#include <X11/Xatom.h> #include <X11/Xatom.h>
@ -75,6 +74,9 @@ void ContrastEffect::reconfigure(ReconfigureFlags flags)
{ {
Q_UNUSED(flags) Q_UNUSED(flags)
if (shader)
shader->init();
if (!shader || !shader->isValid()) if (!shader || !shader->isValid())
XDeleteProperty(display(), rootWindow(), net_wm_contrast_region); XDeleteProperty(display(), rootWindow(), net_wm_contrast_region);
} }
@ -85,21 +87,22 @@ void ContrastEffect::updateContrastRegion(EffectWindow *w) const
float colorTransform[16]; float colorTransform[16];
const QByteArray value = w->readProperty(net_wm_contrast_region, XA_CARDINAL, 32); const QByteArray value = w->readProperty(net_wm_contrast_region, XA_CARDINAL, 32);
if (value.size() > 0 && !((value.size() - (16 * sizeof(float))) % ((4 * sizeof(long))))) { if (value.size() > 0 && !((value.size() - (3 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) {
const long *cardinals = reinterpret_cast<const long*>(value.constData()); const uint32_t *cardinals = reinterpret_cast<const uint32_t*>(value.constData());
qWarning()<<"GGG"<<cardinals;
unsigned int i = 0; unsigned int i = 0;
for (; i < ((value.size() - (16 * sizeof(long)))) / sizeof(long);) { for (; i < ((value.size() - (3 * sizeof(uint32_t)))) / sizeof(uint32_t);) {
int x = cardinals[i++]; int x = cardinals[i++];
int y = cardinals[i++]; int y = cardinals[i++];
int w = cardinals[i++]; int w = cardinals[i++];
int h = cardinals[i++]; int h = cardinals[i++];
region += QRect(x, y, w, h); region += QRect(x, y, w, h);
} }
for (unsigned int j = 0; j < 16; ++j) { qreal contrast = ((qreal)cardinals[i++]) / 100;
colorTransform[j] = (float)cardinals[i + j] / 100; qreal intensity = ((qreal)cardinals[i++]) / 100;
} qreal saturation = ((qreal)cardinals[i++]) / 100;
QMatrix4x4 colorMatrix(colorTransform);
shader->setColorMatrix(colorMatrix); shader->setColorMatrix(colorMatrix(contrast, intensity, saturation));
} }
if (region.isEmpty() && !value.isNull()) { if (region.isEmpty() && !value.isNull()) {
@ -116,6 +119,52 @@ void ContrastEffect::slotWindowAdded(EffectWindow *w)
updateContrastRegion(w); updateContrastRegion(w);
} }
void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom)
{
if (w && atom == net_wm_contrast_region) {
updateContrastRegion(w);
}
}
QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal saturation)
{
QMatrix4x4 satMatrix; //saturation
QMatrix4x4 intMatrix; //intensity
QMatrix4x4 contMatrix; //contrast
//Saturation matrix
if (!qFuzzyCompare(saturation, 1.0)) {
const qreal rval = (1.0 - saturation) * .2126;
const qreal gval = (1.0 - saturation) * .7152;
const qreal bval = (1.0 - saturation) * .0722;
satMatrix = QMatrix4x4(rval + saturation, rval, rval, 0.0,
gval, gval + saturation, gval, 0.0,
bval, bval, bval + saturation, 0.0,
0, 0, 0, 1.0);
}
//IntensityMatrix
if (!qFuzzyCompare(intensity, 1.0)) {
intMatrix.scale(intensity, intensity, intensity);
}
//Contrast Matrix
if (!qFuzzyCompare(contrast, 1.0)) {
const float transl = (1.0 - contrast) / 2.0;
contMatrix = QMatrix4x4(contrast, 0, 0, 0.0,
0, contrast, 0, 0.0,
0, 0, contrast, 0.0,
transl, transl, transl, 1.0);
}
QMatrix4x4 colorMatrix = contMatrix * satMatrix * intMatrix;
//colorMatrix = colorMatrix.transposed();
return colorMatrix;
}
bool ContrastEffect::enabledByDefault() bool ContrastEffect::enabledByDefault()
{ {
GLPlatform *gl = GLPlatform::instance(); GLPlatform *gl = GLPlatform::instance();
@ -209,6 +258,63 @@ void ContrastEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &region)
vbo->setAttribLayout(layout, 2, sizeof(QVector2D)); vbo->setAttribLayout(layout, 2, sizeof(QVector2D));
} }
void ContrastEffect::prePaintScreen(ScreenPrePaintData &data, int time)
{
m_paintedArea = QRegion();
m_currentContrast = QRegion();
effects->prePaintScreen(data, time);
}
void ContrastEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
{
// this effect relies on prePaintWindow being called in the bottom to top order
effects->prePaintWindow(w, data, time);
if (!w->isPaintingEnabled()) {
return;
}
if (!shader || !shader->isValid()) {
return;
}
const QRegion oldPaint = data.paint;
// we don't have to blur a region we don't see
m_currentContrast -= data.clip;
// if we have to paint a non-opaque part of this window that intersects with the
// currently blurred region (which is not cached) we have to redraw the whole region
if ((data.paint-data.clip).intersects(m_currentContrast)) {
data.paint |= m_currentContrast;
}
// in case this window has regions to be blurred
const QRect screen(0, 0, displayWidth(), displayHeight());
const QRegion contrastArea = contrastRegion(w).translated(w->pos()) & screen;
// we are not caching the window
// if this window or an window underneath the modified area is painted again we have to
// do everything
if (m_paintedArea.intersects(contrastArea) || data.paint.intersects(contrastArea)) {
data.paint |= contrastArea;
// we have to check again whether we do not damage a blurred area
// of a window we do not cache
if (contrastArea.intersects(m_currentContrast)) {
data.paint |= m_currentContrast;
}
}
m_currentContrast |= contrastArea;
// m_paintedArea keep track of all repainted areas
m_paintedArea -= data.clip;
m_paintedArea |= data.paint;
}
bool ContrastEffect::shouldContrast(const EffectWindow *w, int mask, const WindowPaintData &data) const bool ContrastEffect::shouldContrast(const EffectWindow *w, int mask, const WindowPaintData &data) const
{ {
if (!shader || !shader->isValid()) if (!shader || !shader->isValid())

View file

@ -1,6 +1,5 @@
/* /*
* Copyright © 2010 Fredrik Höglund <fredrik@kde.org> * Copyright © 2010 Fredrik Höglund <fredrik@kde.org>
* Copyright 2014 Marco Martin <mart@kde.org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -43,7 +42,10 @@ public:
static bool supported(); static bool supported();
static bool enabledByDefault(); static bool enabledByDefault();
static QMatrix4x4 colorMatrix(qreal contrast, qreal intensity, qreal saturation);
void reconfigure(ReconfigureFlags flags); void reconfigure(ReconfigureFlags flags);
void prePaintScreen(ScreenPrePaintData &data, int time);
void prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time);
void drawWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data); void drawWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data);
void paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity); void paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity);
@ -51,6 +53,7 @@ public:
public Q_SLOTS: public Q_SLOTS:
void slotWindowAdded(KWin::EffectWindow *w); void slotWindowAdded(KWin::EffectWindow *w);
void slotPropertyNotify(KWin::EffectWindow *w, long atom);
void slotScreenGeometryChanged(); void slotScreenGeometryChanged();
private: private:
@ -64,6 +67,8 @@ private:
private: private:
ContrastShader *shader; ContrastShader *shader;
long net_wm_contrast_region; long net_wm_contrast_region;
QRegion m_paintedArea; // actually painted area which is greater than m_damagedArea
QRegion m_currentContrast; // keeps track of the currently contrasted area of non-caching windows(from bottom to top)
}; };
inline inline

View file

@ -47,10 +47,7 @@ ContrastShader::~ContrastShader()
ContrastShader *ContrastShader::create() ContrastShader *ContrastShader::create()
{ {
if (ContrastShader::supported()) { if (ContrastShader::supported()) {
ContrastShader *s = new ContrastShader(); return new ContrastShader();
s->reset();
s->init();
return s;
} }
return NULL; return NULL;
@ -137,6 +134,7 @@ void ContrastShader::unbind()
void ContrastShader::init() void ContrastShader::init()
{ {
reset();
#ifdef KWIN_HAVE_OPENGLES #ifdef KWIN_HAVE_OPENGLES

View file

@ -34,6 +34,8 @@ public:
ContrastShader(); ContrastShader();
virtual ~ContrastShader(); virtual ~ContrastShader();
void init();
static ContrastShader *create(); static ContrastShader *create();
bool isValid() const { bool isValid() const {
@ -54,8 +56,7 @@ protected:
void setIsValid(bool value) { void setIsValid(bool value) {
mValid = value; mValid = value;
} }
virtual void init(); void reset();
virtual void reset();
private: private:
bool mValid; bool mValid;