Pass projection matrix to ScreenPaintData

With this change a new ctor overload is added to ScreenPaintData
which allows passing a projection matrix through the effects. This
allows effects to put up custom shaders with a shared projection matrix
and without having to calculate it themselves.

The projection matrix is a read-only information for the effects. There
is no way to change or overwrite it.
This commit is contained in:
Martin Gräßlin 2015-11-26 16:12:12 +01:00
parent 5657405d32
commit f284ef814c
5 changed files with 43 additions and 5 deletions

View file

@ -418,13 +418,30 @@ WindowPaintData &WindowPaintData::operator+=(const QVector3D &translation)
return *this; return *this;
} }
class ScreenPaintData::Private
{
public:
QMatrix4x4 projectionMatrix;
};
ScreenPaintData::ScreenPaintData() ScreenPaintData::ScreenPaintData()
: PaintData() : PaintData()
, d(new Private())
{ {
} }
ScreenPaintData::ScreenPaintData(const QMatrix4x4 &projectionMatrix)
: PaintData()
, d(new Private())
{
d->projectionMatrix = projectionMatrix;
}
ScreenPaintData::~ScreenPaintData() = default;
ScreenPaintData::ScreenPaintData(const ScreenPaintData &other) ScreenPaintData::ScreenPaintData(const ScreenPaintData &other)
: PaintData() : PaintData()
, d(new Private())
{ {
translate(other.translation()); translate(other.translation());
setXScale(other.xScale()); setXScale(other.xScale());
@ -433,6 +450,7 @@ ScreenPaintData::ScreenPaintData(const ScreenPaintData &other)
setRotationOrigin(other.rotationOrigin()); setRotationOrigin(other.rotationOrigin());
setRotationAxis(other.rotationAxis()); setRotationAxis(other.rotationAxis());
setRotationAngle(other.rotationAngle()); setRotationAngle(other.rotationAngle());
d->projectionMatrix = other.d->projectionMatrix;
} }
ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs) ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs)
@ -446,6 +464,7 @@ ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs)
setRotationOrigin(rhs.rotationOrigin()); setRotationOrigin(rhs.rotationOrigin());
setRotationAxis(rhs.rotationAxis()); setRotationAxis(rhs.rotationAxis());
setRotationAngle(rhs.rotationAngle()); setRotationAngle(rhs.rotationAngle());
d->projectionMatrix = rhs.d->projectionMatrix;
return *this; return *this;
} }
@ -493,6 +512,11 @@ ScreenPaintData &ScreenPaintData::operator+=(const QVector3D &translation)
return *this; return *this;
} }
QMatrix4x4 ScreenPaintData::projectionMatrix() const
{
return d->projectionMatrix;
}
//**************************************** //****************************************
// Effect // Effect
//**************************************** //****************************************

View file

@ -40,6 +40,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QList> #include <QList>
#include <QHash> #include <QHash>
#include <QStack> #include <QStack>
#include <QScopedPointer>
#include <KPluginFactory> #include <KPluginFactory>
@ -2419,7 +2420,9 @@ class KWINEFFECTS_EXPORT ScreenPaintData : public PaintData
{ {
public: public:
ScreenPaintData(); ScreenPaintData();
ScreenPaintData(const QMatrix4x4 &projectionMatrix);
ScreenPaintData(const ScreenPaintData &other); ScreenPaintData(const ScreenPaintData &other);
virtual ~ScreenPaintData();
/** /**
* Scales the screen by @p scale factor. * Scales the screen by @p scale factor.
* Multiplies all three components by the given factor. * Multiplies all three components by the given factor.
@ -2462,6 +2465,16 @@ public:
**/ **/
ScreenPaintData& operator+=(const QVector3D &translation); ScreenPaintData& operator+=(const QVector3D &translation);
ScreenPaintData& operator=(const ScreenPaintData &rhs); ScreenPaintData& operator=(const ScreenPaintData &rhs);
/**
* The projection matrix used by the scene for the current rendering pass.
* On non-OpenGL compositors it's set to Identity matrix.
* @since 5.6
**/
QMatrix4x4 projectionMatrix() const;
private:
class Private;
QScopedPointer<Private> d;
}; };
class KWINEFFECTS_EXPORT ScreenPrePaintData class KWINEFFECTS_EXPORT ScreenPrePaintData

View file

@ -106,7 +106,7 @@ Scene::~Scene()
// returns mask and possibly modified region // returns mask and possibly modified region
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint, void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
QRegion *updateRegion, QRegion *validRegion) QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection)
{ {
const QSize &screenSize = screens()->size(); const QSize &screenSize = screens()->size();
const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height());
@ -146,7 +146,7 @@ void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint
paintBackground(region); paintBackground(region);
} }
ScreenPaintData data; ScreenPaintData data(projection);
effects->paintScreen(*mask, region, data); effects->paintScreen(*mask, region, data);
foreach (Window *w, stacking_order) { foreach (Window *w, stacking_order) {

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "kwineffects.h" #include "kwineffects.h"
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMatrix4x4>
class QOpenGLFramebufferObject; class QOpenGLFramebufferObject;
@ -158,7 +159,7 @@ protected:
void clearStackingOrder(); void clearStackingOrder();
// shared implementation, starts painting the screen // shared implementation, starts painting the screen
void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint, void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint,
QRegion *updateRegion, QRegion *validRegion); QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection = QMatrix4x4());
friend class EffectsHandlerImpl; friend class EffectsHandlerImpl;
// called after all effects had their paintScreen() called // called after all effects had their paintScreen() called
void finalPaintScreen(int mask, QRegion region, ScreenPaintData& data); void finalPaintScreen(int mask, QRegion region, ScreenPaintData& data);

View file

@ -728,7 +728,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
int mask = 0; int mask = 0;
updateProjectionMatrix(); updateProjectionMatrix();
paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid); // call generic implementation paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid, projectionMatrix()); // call generic implementation
GLVertexBuffer::streamingBuffer()->endOfFrame(); GLVertexBuffer::streamingBuffer()->endOfFrame();
@ -748,7 +748,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
int mask = 0; int mask = 0;
updateProjectionMatrix(); updateProjectionMatrix();
paintScreen(&mask, damage, repaint, &updateRegion, &validRegion); // call generic implementation paintScreen(&mask, damage, repaint, &updateRegion, &validRegion, projectionMatrix()); // call generic implementation
if (!GLPlatform::instance()->isGLES()) { if (!GLPlatform::instance()->isGLES()) {
const QSize &screenSize = screens()->size(); const QSize &screenSize = screens()->size();