From 359224a5dcf9ef22f2c5f059f920f3f5f799012b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 14 Oct 2016 15:49:57 +0200 Subject: [PATCH] Pass the current output geometry to ScreenPaintData Summary: On Wayland per output rendering is performed and paintScreen is invoked for every output. Some effects need the information which output is currently being rendered as otherwise e.g. FBO access could fail. This change adds the current output geometry to ScreenPaintData. On X11 (all outputs one geometry) this information is not set and a null rect is returned. That way the effects can also easily check which rendering mode is used. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D3058 --- autotests/test_screen_paint_data.cpp | 9 +++++++-- libkwineffects/kwineffects.cpp | 11 ++++++++++- libkwineffects/kwineffects.h | 12 +++++++++++- scene.cpp | 4 ++-- scene.h | 2 +- scene_opengl.cpp | 2 +- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/autotests/test_screen_paint_data.cpp b/autotests/test_screen_paint_data.cpp index 6f02c93631..01655575b1 100644 --- a/autotests/test_screen_paint_data.cpp +++ b/autotests/test_screen_paint_data.cpp @@ -20,6 +20,7 @@ along with this program. If not, see . #include +#include #include #include @@ -57,11 +58,12 @@ void TestScreenPaintData::testCtor() QCOMPARE(data.rotationAngle(), 0.0); QCOMPARE(data.rotationOrigin(), QVector3D()); QCOMPARE(data.rotationAxis(), QVector3D(0.0, 0.0, 1.0)); + QCOMPARE(data.outputGeometry(), QRect()); } void TestScreenPaintData::testCopyCtor() { - ScreenPaintData data; + ScreenPaintData data(QMatrix4x4(), QRect(10, 20, 30, 40)); ScreenPaintData data2(data); // no value had been changed QCOMPARE(data2.xScale(), 1.0); @@ -74,6 +76,7 @@ void TestScreenPaintData::testCopyCtor() QCOMPARE(data2.rotationAngle(), 0.0); QCOMPARE(data2.rotationOrigin(), QVector3D()); QCOMPARE(data2.rotationAxis(), QVector3D(0.0, 0.0, 1.0)); + QCOMPARE(data2.outputGeometry(), QRect(10, 20, 30, 40)); data2.setScale(QVector3D(0.5, 2.0, 3.0)); data2.translate(0.5, 2.0, 3.0); @@ -97,13 +100,14 @@ void TestScreenPaintData::testCopyCtor() void TestScreenPaintData::testAssignmentOperator() { ScreenPaintData data; - ScreenPaintData data2; + ScreenPaintData data2(QMatrix4x4(), QRect(10, 20, 30, 40)); data2.setScale(QVector3D(0.5, 2.0, 3.0)); data2.translate(0.5, 2.0, 3.0); data2.setRotationAngle(45.0); data2.setRotationOrigin(QVector3D(1.0, 2.0, 3.0)); data2.setRotationAxis(QVector3D(1.0, 1.0, 0.0)); + QCOMPARE(data2.outputGeometry(), QRect(10, 20, 30, 40)); data = data2; // data and data2 should be the same @@ -117,6 +121,7 @@ void TestScreenPaintData::testAssignmentOperator() QCOMPARE(data.rotationAngle(), 45.0); QCOMPARE(data.rotationOrigin(), QVector3D(1.0, 2.0, 3.0)); QCOMPARE(data.rotationAxis(), QVector3D(1.0, 1.0, 0.0)); + QCOMPARE(data.outputGeometry(), QRect(10, 20, 30, 40)); // data 2 QCOMPARE(data2.xScale(), 0.5); QCOMPARE(data2.yScale(), 2.0); diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp index 899108065a..afa9804094 100644 --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -435,6 +435,7 @@ class ScreenPaintData::Private { public: QMatrix4x4 projectionMatrix; + QRect outputGeometry; }; ScreenPaintData::ScreenPaintData() @@ -443,11 +444,12 @@ ScreenPaintData::ScreenPaintData() { } -ScreenPaintData::ScreenPaintData(const QMatrix4x4 &projectionMatrix) +ScreenPaintData::ScreenPaintData(const QMatrix4x4 &projectionMatrix, const QRect &outputGeometry) : PaintData() , d(new Private()) { d->projectionMatrix = projectionMatrix; + d->outputGeometry = outputGeometry; } ScreenPaintData::~ScreenPaintData() = default; @@ -464,6 +466,7 @@ ScreenPaintData::ScreenPaintData(const ScreenPaintData &other) setRotationAxis(other.rotationAxis()); setRotationAngle(other.rotationAngle()); d->projectionMatrix = other.d->projectionMatrix; + d->outputGeometry = other.d->outputGeometry; } ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs) @@ -478,6 +481,7 @@ ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs) setRotationAxis(rhs.rotationAxis()); setRotationAngle(rhs.rotationAngle()); d->projectionMatrix = rhs.d->projectionMatrix; + d->outputGeometry = rhs.d->outputGeometry; return *this; } @@ -530,6 +534,11 @@ QMatrix4x4 ScreenPaintData::projectionMatrix() const return d->projectionMatrix; } +QRect ScreenPaintData::outputGeometry() const +{ + return d->outputGeometry; +} + //**************************************** // Effect //**************************************** diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index f0782b3432..869e552d92 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -2547,7 +2547,7 @@ class KWINEFFECTS_EXPORT ScreenPaintData : public PaintData { public: ScreenPaintData(); - ScreenPaintData(const QMatrix4x4 &projectionMatrix); + ScreenPaintData(const QMatrix4x4 &projectionMatrix, const QRect &outputGeometry = QRect()); ScreenPaintData(const ScreenPaintData &other); virtual ~ScreenPaintData(); /** @@ -2599,6 +2599,16 @@ public: * @since 5.6 **/ QMatrix4x4 projectionMatrix() const; + + /** + * The geometry of the currently rendered output. + * Only set for per-output rendering (e.g. Wayland). + * + * This geometry can be used as a hint about the native window the OpenGL context + * is bound. OpenGL calls need to be translated to this geometry. + * @since 5.9 + **/ + QRect outputGeometry() const; private: class Private; QScopedPointer d; diff --git a/scene.cpp b/scene.cpp index 277ce31649..c236efe1ec 100644 --- a/scene.cpp +++ b/scene.cpp @@ -107,7 +107,7 @@ Scene::~Scene() // returns mask and possibly modified region void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint, - QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection) + QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection, const QRect &outputGeometry) { const QSize &screenSize = screens()->size(); const QRegion displayRegion(0, 0, screenSize.width(), screenSize.height()); @@ -147,7 +147,7 @@ void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint paintBackground(region); } - ScreenPaintData data(projection); + ScreenPaintData data(projection, outputGeometry); effects->paintScreen(*mask, region, data); foreach (Window *w, stacking_order) { diff --git a/scene.h b/scene.h index a1a1b684c3..799161601c 100644 --- a/scene.h +++ b/scene.h @@ -173,7 +173,7 @@ protected: void clearStackingOrder(); // shared implementation, starts painting the screen void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint, - QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection = QMatrix4x4()); + QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection = QMatrix4x4(), const QRect &outputGeometry = QRect()); friend class EffectsHandlerImpl; // called after all effects had their paintScreen() called void finalPaintScreen(int mask, QRegion region, ScreenPaintData& data); diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 56cebc06cc..845bd442ab 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -710,7 +710,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) int mask = 0; updateProjectionMatrix(); - paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid, projectionMatrix()); // call generic implementation + paintScreen(&mask, damage.intersected(geo), repaint, &update, &valid, projectionMatrix(), geo); // call generic implementation GLVertexBuffer::streamingBuffer()->endOfFrame();