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
This commit is contained in:
Martin Gräßlin 2016-10-14 15:49:57 +02:00
parent 4e9a1eeb50
commit 359224a5dc
6 changed files with 32 additions and 8 deletions

View file

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwineffects.h>
#include <QMatrix4x4>
#include <QtGui/QVector2D>
#include <QVector3D>
@ -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);

View file

@ -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
//****************************************

View file

@ -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<Private> d;

View file

@ -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) {

View file

@ -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);

View file

@ -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();