diff --git a/autotests/test_screen_paint_data.cpp b/autotests/test_screen_paint_data.cpp --- a/autotests/test_screen_paint_data.cpp +++ b/autotests/test_screen_paint_data.cpp @@ -20,6 +20,7 @@ #include +#include #include #include @@ -57,11 +58,12 @@ 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 @@ 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::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 @@ 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.h b/libkwineffects/kwineffects.h --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -2547,7 +2547,7 @@ { public: ScreenPaintData(); - ScreenPaintData(const QMatrix4x4 &projectionMatrix); + ScreenPaintData(const QMatrix4x4 &projectionMatrix, const QRect &outputGeometry = QRect()); ScreenPaintData(const ScreenPaintData &other); virtual ~ScreenPaintData(); /** @@ -2599,6 +2599,16 @@ * @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/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -435,19 +435,21 @@ { public: QMatrix4x4 projectionMatrix; + QRect outputGeometry; }; ScreenPaintData::ScreenPaintData() : PaintData() , d(new Private()) { } -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 @@ 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 @@ setRotationAxis(rhs.rotationAxis()); setRotationAngle(rhs.rotationAngle()); d->projectionMatrix = rhs.d->projectionMatrix; + d->outputGeometry = rhs.d->outputGeometry; return *this; } @@ -530,6 +534,11 @@ return d->projectionMatrix; } +QRect ScreenPaintData::outputGeometry() const +{ + return d->outputGeometry; +} + //**************************************** // Effect //**************************************** diff --git a/scene.h b/scene.h --- a/scene.h +++ b/scene.h @@ -173,7 +173,7 @@ 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.cpp b/scene.cpp --- a/scene.cpp +++ b/scene.cpp @@ -107,7 +107,7 @@ // 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 @@ paintBackground(region); } - ScreenPaintData data(projection); + ScreenPaintData data(projection, outputGeometry); effects->paintScreen(*mask, region, data); foreach (Window *w, stacking_order) { diff --git a/scene_opengl.cpp b/scene_opengl.cpp --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -710,7 +710,7 @@ 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();