kwineffects: Strip ScreenPaintData of transforms

ScreenPaintData provides a way to transform the painted screen, e.g.
scale or translate. From API point of view, it's great. It allows
fullscreen effects to transform the workspace in various ways.

On the other hand, such effects end up fighting the default scene
painting algorithm. For example, just have a look at the slide effect!
With fullscreen effects, it's better to leave to them the decision how
the screen should be painted. For example, such approach is taken in
some wayland compositors, e.g. wayfire, and our qtquick effects already
operate in similar fashion.

Given that, strip the ScreenPaintData of all available transforms. The
main motivation behind this change is to improve encapsulation of item
painting code and simplify model-view-projection code in kwin. It will
also make the job of extracting item code for sharing purposes easier.
This commit is contained in:
Vlad Zahorodnii 2022-06-18 21:15:21 +03:00
parent 53d25c7228
commit fa78de6219
12 changed files with 27 additions and 480 deletions

View file

@ -5,15 +5,6 @@ add_subdirectory(integration)
add_subdirectory(libinput)
add_subdirectory(tabbox)
########################################################
# Test ScreenPaintData
########################################################
set(testScreenPaintData_SRCS test_screen_paint_data.cpp)
add_executable(testScreenPaintData ${testScreenPaintData_SRCS})
target_link_libraries(testScreenPaintData kwineffects Qt::Test Qt::Widgets KF5::WindowSystem)
add_test(NAME kwin-testScreenPaintData COMMAND testScreenPaintData)
ecm_mark_as_test(testScreenPaintData)
########################################################
# Test WindowPaintData
########################################################

View file

@ -1,273 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <kwineffects.h>
#include <QMatrix4x4>
#include <QVector2D>
#include <QVector3D>
#include <QtTest>
using namespace KWin;
class TestScreenPaintData : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testCtor();
void testCopyCtor();
void testAssignmentOperator();
void testSetScale();
void testOperatorMultiplyAssign();
void testSetTranslate();
void testOperatorPlus();
void testSetAngle();
void testSetRotationOrigin();
void testSetRotationAxis();
};
void TestScreenPaintData::testCtor()
{
ScreenPaintData data;
QCOMPARE(data.xScale(), 1.0);
QCOMPARE(data.yScale(), 1.0);
QCOMPARE(data.zScale(), 1.0);
QCOMPARE(data.xTranslation(), 0.0);
QCOMPARE(data.yTranslation(), 0.0);
QCOMPARE(data.zTranslation(), 0.0);
QCOMPARE(data.translation(), QVector3D());
QCOMPARE(data.rotationAngle(), 0.0);
QCOMPARE(data.rotationOrigin(), QVector3D());
QCOMPARE(data.rotationAxis(), QVector3D(0.0, 0.0, 1.0));
QCOMPARE(data.screen(), nullptr);
}
void TestScreenPaintData::testCopyCtor()
{
ScreenPaintData data;
ScreenPaintData data2(data);
// no value had been changed
QCOMPARE(data2.xScale(), 1.0);
QCOMPARE(data2.yScale(), 1.0);
QCOMPARE(data2.zScale(), 1.0);
QCOMPARE(data2.xTranslation(), 0.0);
QCOMPARE(data2.yTranslation(), 0.0);
QCOMPARE(data2.zTranslation(), 0.0);
QCOMPARE(data2.translation(), QVector3D());
QCOMPARE(data2.rotationAngle(), 0.0);
QCOMPARE(data2.rotationOrigin(), QVector3D());
QCOMPARE(data2.rotationAxis(), QVector3D(0.0, 0.0, 1.0));
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));
ScreenPaintData data3(data2);
QCOMPARE(data3.xScale(), 0.5);
QCOMPARE(data3.yScale(), 2.0);
QCOMPARE(data3.zScale(), 3.0);
QCOMPARE(data3.xTranslation(), 0.5);
QCOMPARE(data3.yTranslation(), 2.0);
QCOMPARE(data3.zTranslation(), 3.0);
QCOMPARE(data3.translation(), QVector3D(0.5, 2.0, 3.0));
QCOMPARE(data3.rotationAngle(), 45.0);
QCOMPARE(data3.rotationOrigin(), QVector3D(1.0, 2.0, 3.0));
QCOMPARE(data3.rotationAxis(), QVector3D(1.0, 1.0, 0.0));
}
void TestScreenPaintData::testAssignmentOperator()
{
ScreenPaintData data;
ScreenPaintData data2;
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));
data = data2;
// data and data2 should be the same
QCOMPARE(data.xScale(), 0.5);
QCOMPARE(data.yScale(), 2.0);
QCOMPARE(data.zScale(), 3.0);
QCOMPARE(data.xTranslation(), 0.5);
QCOMPARE(data.yTranslation(), 2.0);
QCOMPARE(data.zTranslation(), 3.0);
QCOMPARE(data.translation(), QVector3D(0.5, 2.0, 3.0));
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));
// data 2
QCOMPARE(data2.xScale(), 0.5);
QCOMPARE(data2.yScale(), 2.0);
QCOMPARE(data2.zScale(), 3.0);
QCOMPARE(data2.xTranslation(), 0.5);
QCOMPARE(data2.yTranslation(), 2.0);
QCOMPARE(data2.zTranslation(), 3.0);
QCOMPARE(data2.translation(), QVector3D(0.5, 2.0, 3.0));
QCOMPARE(data2.rotationAngle(), 45.0);
QCOMPARE(data2.rotationOrigin(), QVector3D(1.0, 2.0, 3.0));
QCOMPARE(data2.rotationAxis(), QVector3D(1.0, 1.0, 0.0));
}
void TestScreenPaintData::testSetScale()
{
ScreenPaintData data;
// without anything set, it's 1.0 on all axis
QCOMPARE(data.xScale(), 1.0);
QCOMPARE(data.yScale(), 1.0);
QCOMPARE(data.zScale(), 1.0);
// changing xScale should not affect y and z
data.setXScale(2.0);
QCOMPARE(data.xScale(), 2.0);
QCOMPARE(data.yScale(), 1.0);
QCOMPARE(data.zScale(), 1.0);
// changing yScale should not affect x and z
data.setYScale(3.0);
QCOMPARE(data.xScale(), 2.0);
QCOMPARE(data.yScale(), 3.0);
QCOMPARE(data.zScale(), 1.0);
// changing zScale should not affect x and y
data.setZScale(4.0);
QCOMPARE(data.xScale(), 2.0);
QCOMPARE(data.yScale(), 3.0);
QCOMPARE(data.zScale(), 4.0);
// setting a vector2d should affect x and y components
data.setScale(QVector2D(0.5, 2.0));
QCOMPARE(data.xScale(), 0.5);
QCOMPARE(data.yScale(), 2.0);
QCOMPARE(data.zScale(), 4.0);
// setting a vector3d should affect all components
data.setScale(QVector3D(1.5, 2.5, 3.5));
QCOMPARE(data.xScale(), 1.5);
QCOMPARE(data.yScale(), 2.5);
QCOMPARE(data.zScale(), 3.5);
}
void TestScreenPaintData::testOperatorMultiplyAssign()
{
ScreenPaintData data;
// without anything set, it's 1.0 on all axis
QCOMPARE(data.xScale(), 1.0);
QCOMPARE(data.yScale(), 1.0);
QCOMPARE(data.zScale(), 1.0);
// multiplying by a factor should set all components
data *= 2.0;
QCOMPARE(data.xScale(), 2.0);
QCOMPARE(data.yScale(), 2.0);
QCOMPARE(data.zScale(), 2.0);
// multiplying by a vector2D should set x and y components
data *= QVector2D(2.0, 3.0);
QCOMPARE(data.xScale(), 4.0);
QCOMPARE(data.yScale(), 6.0);
QCOMPARE(data.zScale(), 2.0);
// multiplying by a vector3d should set all components
data *= QVector3D(0.5, 1.5, 2.0);
QCOMPARE(data.xScale(), 2.0);
QCOMPARE(data.yScale(), 9.0);
QCOMPARE(data.zScale(), 4.0);
}
void TestScreenPaintData::testSetTranslate()
{
ScreenPaintData data;
QCOMPARE(data.xTranslation(), 0.0);
QCOMPARE(data.yTranslation(), 0.0);
QCOMPARE(data.zTranslation(), 0.0);
QCOMPARE(data.translation(), QVector3D());
// set x translate, should not affect y and z
data.setXTranslation(1.0);
QCOMPARE(data.xTranslation(), 1.0);
QCOMPARE(data.yTranslation(), 0.0);
QCOMPARE(data.zTranslation(), 0.0);
QCOMPARE(data.translation(), QVector3D(1.0, 0.0, 0.0));
// set y translate, should not affect x and z
data.setYTranslation(2.0);
QCOMPARE(data.xTranslation(), 1.0);
QCOMPARE(data.yTranslation(), 2.0);
QCOMPARE(data.zTranslation(), 0.0);
QCOMPARE(data.translation(), QVector3D(1.0, 2.0, 0.0));
// set z translate, should not affect x and y
data.setZTranslation(3.0);
QCOMPARE(data.xTranslation(), 1.0);
QCOMPARE(data.yTranslation(), 2.0);
QCOMPARE(data.zTranslation(), 3.0);
QCOMPARE(data.translation(), QVector3D(1.0, 2.0, 3.0));
// translate in x
data.translate(0.5);
QCOMPARE(data.translation(), QVector3D(1.5, 2.0, 3.0));
// translate in x and y
data.translate(0.5, 0.75);
QCOMPARE(data.translation(), QVector3D(2.0, 2.75, 3.0));
// translate in x, y and z
data.translate(1.0, 2.0, 3.0);
QCOMPARE(data.translation(), QVector3D(3.0, 4.75, 6.0));
// translate using vector
data.translate(QVector3D(2.0, 1.0, 0.5));
QCOMPARE(data.translation(), QVector3D(5.0, 5.75, 6.5));
}
void TestScreenPaintData::testOperatorPlus()
{
ScreenPaintData data;
QCOMPARE(data.xTranslation(), 0.0);
QCOMPARE(data.yTranslation(), 0.0);
QCOMPARE(data.zTranslation(), 0.0);
QCOMPARE(data.translation(), QVector3D());
// test with point
data += QPoint(1, 2);
QCOMPARE(data.translation(), QVector3D(1.0, 2.0, 0.0));
// test with pointf
data += QPointF(0.5, 0.75);
QCOMPARE(data.translation(), QVector3D(1.5, 2.75, 0.0));
// test with QVector2D
data += QVector2D(0.25, 1.5);
QCOMPARE(data.translation(), QVector3D(1.75, 4.25, 0.0));
// test with QVector3D
data += QVector3D(1.0, 2.0, 3.5);
QCOMPARE(data.translation(), QVector3D(2.75, 6.25, 3.5));
}
void TestScreenPaintData::testSetAngle()
{
ScreenPaintData data;
QCOMPARE(data.rotationAngle(), 0.0);
data.setRotationAngle(20.0);
QCOMPARE(data.rotationAngle(), 20.0);
}
void TestScreenPaintData::testSetRotationOrigin()
{
ScreenPaintData data;
QCOMPARE(data.rotationOrigin(), QVector3D());
data.setRotationOrigin(QVector3D(1.0, 2.0, 3.0));
QCOMPARE(data.rotationOrigin(), QVector3D(1.0, 2.0, 3.0));
}
void TestScreenPaintData::testSetRotationAxis()
{
ScreenPaintData data;
QCOMPARE(data.rotationAxis(), QVector3D(0.0, 0.0, 1.0));
data.setRotationAxis(Qt::XAxis);
QCOMPARE(data.rotationAxis(), QVector3D(1.0, 0.0, 0.0));
data.setRotationAxis(Qt::YAxis);
QCOMPARE(data.rotationAxis(), QVector3D(0.0, 1.0, 0.0));
data.setRotationAxis(Qt::ZAxis);
QCOMPARE(data.rotationAxis(), QVector3D(0.0, 0.0, 1.0));
data.setRotationAxis(QVector3D(1.0, 1.0, 0.0));
QCOMPARE(data.rotationAxis(), QVector3D(1.0, 1.0, 0.0));
}
QTEST_MAIN(TestScreenPaintData)
#include "test_screen_paint_data.moc"

View file

@ -112,8 +112,8 @@ void TrackMouseEffect::paintScreen(int mask, const QRegion &region, ScreenPaintD
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
QMatrix4x4 matrix(data.projectionMatrix());
const QPointF p = m_lastRect[0].topLeft() + QPoint(m_lastRect[0].width() / 2.0, m_lastRect[0].height() / 2.0);
const float x = p.x() * data.xScale() + data.xTranslation();
const float y = p.y() * data.yScale() + data.yTranslation();
const float x = p.x();
const float y = p.y();
for (int i = 0; i < 2; ++i) {
matrix.translate(x, y, 0.0);
matrix.rotate(i ? -2 * m_angle : m_angle, 0, 0, 1.0);

View file

@ -312,22 +312,23 @@ void ZoomEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &d
effects->paintScreen(mask, region, data);
GLFramebuffer::popFramebuffer();
data *= QVector2D(zoom, zoom);
const QSize screenSize = effects->virtualScreenSize();
// mouse-tracking allows navigation of the zoom-area using the mouse.
qreal xTranslation = 0;
qreal yTranslation = 0;
switch (mouseTracking) {
case MouseTrackingProportional:
data.setXTranslation(-int(cursorPoint.x() * (zoom - 1.0)));
data.setYTranslation(-int(cursorPoint.y() * (zoom - 1.0)));
xTranslation = -int(cursorPoint.x() * (zoom - 1.0));
yTranslation = -int(cursorPoint.y() * (zoom - 1.0));
prevPoint = cursorPoint;
break;
case MouseTrackingCentred:
prevPoint = cursorPoint;
// fall through
case MouseTrackingDisabled:
data.setXTranslation(qMin(0, qMax(int(screenSize.width() - screenSize.width() * zoom), int(screenSize.width() / 2 - prevPoint.x() * zoom))));
data.setYTranslation(qMin(0, qMax(int(screenSize.height() - screenSize.height() * zoom), int(screenSize.height() / 2 - prevPoint.y() * zoom))));
xTranslation = qMin(0, qMax(int(screenSize.width() - screenSize.width() * zoom), int(screenSize.width() / 2 - prevPoint.x() * zoom)));
yTranslation = qMin(0, qMax(int(screenSize.height() - screenSize.height() * zoom), int(screenSize.height() / 2 - prevPoint.y() * zoom)));
break;
case MouseTrackingPush: {
// touching an edge of the screen moves the zoom-area in that direction.
@ -351,8 +352,8 @@ void ZoomEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &d
if (yMove) {
prevPoint.setY(qMax(0, qMin(screenSize.height(), prevPoint.y() + yMove)));
}
data.setXTranslation(-int(prevPoint.x() * (zoom - 1.0)));
data.setYTranslation(-int(prevPoint.y() * (zoom - 1.0)));
xTranslation = -int(prevPoint.x() * (zoom - 1.0));
yTranslation = -int(prevPoint.y() * (zoom - 1.0));
break;
}
}
@ -367,8 +368,8 @@ void ZoomEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &d
acceptFocus = msecs > focusDelay;
}
if (acceptFocus) {
data.setXTranslation(-int(focusPoint.x() * (zoom - 1.0)));
data.setYTranslation(-int(focusPoint.y() * (zoom - 1.0)));
xTranslation = -int(focusPoint.x() * (zoom - 1.0));
yTranslation = -int(focusPoint.y() * (zoom - 1.0));
prevPoint = focusPoint;
}
}
@ -378,8 +379,8 @@ void ZoomEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &d
glClear(GL_COLOR_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.translate(data.translation());
matrix.scale(data.scale());
matrix.translate(xTranslation, yTranslation);
matrix.scale(zoom, zoom);
auto shader = ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
shader->setUniform(GLShader::ModelViewProjectionMatrix, data.projectionMatrix() * matrix);
@ -404,7 +405,7 @@ void ZoomEffect::paintScreen(int mask, const QRegion &region, ScreenPaintData &d
}
const QPoint p = effects->cursorPos() - cursor.hotSpot();
QRect rect(p * zoom + QPoint(data.xTranslation(), data.yTranslation()), cursorSize);
QRect rect(p * zoom + QPoint(xTranslation, yTranslation), cursorSize);
cursorTexture->bind();
glEnable(GL_BLEND);

View file

@ -404,14 +404,12 @@ public:
};
ScreenPaintData::ScreenPaintData()
: PaintData()
, d(new Private())
: d(new Private())
{
}
ScreenPaintData::ScreenPaintData(const QMatrix4x4 &projectionMatrix, EffectScreen *screen)
: PaintData()
, d(new Private())
: d(new Private())
{
d->projectionMatrix = projectionMatrix;
d->screen = screen;
@ -420,80 +418,19 @@ ScreenPaintData::ScreenPaintData(const QMatrix4x4 &projectionMatrix, EffectScree
ScreenPaintData::~ScreenPaintData() = default;
ScreenPaintData::ScreenPaintData(const ScreenPaintData &other)
: PaintData()
, d(new Private())
: d(new Private())
{
translate(other.translation());
setXScale(other.xScale());
setYScale(other.yScale());
setZScale(other.zScale());
setRotationOrigin(other.rotationOrigin());
setRotationAxis(other.rotationAxis());
setRotationAngle(other.rotationAngle());
d->projectionMatrix = other.d->projectionMatrix;
d->screen = other.d->screen;
}
ScreenPaintData &ScreenPaintData::operator=(const ScreenPaintData &rhs)
{
setXScale(rhs.xScale());
setYScale(rhs.yScale());
setZScale(rhs.zScale());
setXTranslation(rhs.xTranslation());
setYTranslation(rhs.yTranslation());
setZTranslation(rhs.zTranslation());
setRotationOrigin(rhs.rotationOrigin());
setRotationAxis(rhs.rotationAxis());
setRotationAngle(rhs.rotationAngle());
d->projectionMatrix = rhs.d->projectionMatrix;
d->screen = rhs.d->screen;
return *this;
}
ScreenPaintData &ScreenPaintData::operator*=(qreal scale)
{
setXScale(this->xScale() * scale);
setYScale(this->yScale() * scale);
setZScale(this->zScale() * scale);
return *this;
}
ScreenPaintData &ScreenPaintData::operator*=(const QVector2D &scale)
{
setXScale(this->xScale() * scale.x());
setYScale(this->yScale() * scale.y());
return *this;
}
ScreenPaintData &ScreenPaintData::operator*=(const QVector3D &scale)
{
setXScale(this->xScale() * scale.x());
setYScale(this->yScale() * scale.y());
setZScale(this->zScale() * scale.z());
return *this;
}
ScreenPaintData &ScreenPaintData::operator+=(const QPointF &translation)
{
return this->operator+=(QVector3D(translation));
}
ScreenPaintData &ScreenPaintData::operator+=(const QPoint &translation)
{
return this->operator+=(QVector3D(translation));
}
ScreenPaintData &ScreenPaintData::operator+=(const QVector2D &translation)
{
return this->operator+=(QVector3D(translation));
}
ScreenPaintData &ScreenPaintData::operator+=(const QVector3D &translation)
{
translate(translation);
return *this;
}
QMatrix4x4 ScreenPaintData::projectionMatrix() const
{
return d->projectionMatrix;

View file

@ -3292,54 +3292,14 @@ private:
WindowPaintDataPrivate *const d;
};
class KWINEFFECTS_EXPORT ScreenPaintData : public PaintData
class KWINEFFECTS_EXPORT ScreenPaintData
{
public:
ScreenPaintData();
ScreenPaintData(const QMatrix4x4 &projectionMatrix, EffectScreen *screen = nullptr);
ScreenPaintData(const ScreenPaintData &other);
~ScreenPaintData() override;
/**
* Scales the screen by @p scale factor.
* Multiplies all three components by the given factor.
* @since 4.10
*/
ScreenPaintData &operator*=(qreal scale);
/**
* Scales the screen by @p scale factor.
* Performs a component wise multiplication on x and y components.
* @since 4.10
*/
ScreenPaintData &operator*=(const QVector2D &scale);
/**
* Scales the screen by @p scale factor.
* Performs a component wise multiplication.
* @since 4.10
*/
ScreenPaintData &operator*=(const QVector3D &scale);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* @since 4.10
*/
ScreenPaintData &operator+=(const QPointF &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData &operator+=(const QPoint &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData &operator+=(const QVector2D &translation);
/**
* Translates the screen by the given @p translation and returns a reference to the ScreenPaintData.
* Overloaded method for convenience.
* @since 4.10
*/
ScreenPaintData &operator+=(const QVector3D &translation);
~ScreenPaintData();
ScreenPaintData &operator=(const ScreenPaintData &rhs);
/**

View file

@ -580,7 +580,7 @@ void Scene::paintWindow(WindowItem *item, int mask, const QRegion &region)
return;
}
WindowPaintData data(screenProjectionMatrix());
WindowPaintData data(renderTargetProjectionMatrix());
effects->paintWindow(item->window()->effectWindow(), mask, region, data);
}
@ -610,11 +610,6 @@ bool Scene::supportsNativeFence() const
return false;
}
QMatrix4x4 Scene::screenProjectionMatrix() const
{
return QMatrix4x4();
}
QPainter *Scene::scenePainter() const
{
return nullptr;

View file

@ -132,8 +132,6 @@ public:
virtual void doneOpenGLContextCurrent();
virtual bool supportsNativeFence() const;
virtual QMatrix4x4 screenProjectionMatrix() const;
virtual DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0;
/**
@ -193,10 +191,10 @@ protected:
// shared implementation of painting the screen in the generic
// (unoptimized) way
void preparePaintGenericScreen();
virtual void paintGenericScreen(int mask, const ScreenPaintData &data);
void paintGenericScreen(int mask, const ScreenPaintData &data);
// shared implementation of painting the screen in an optimized way
void preparePaintSimpleScreen();
virtual void paintSimpleScreen(int mask, const QRegion &region);
void paintSimpleScreen(int mask, const QRegion &region);
// paint the background (not the desktop background - the whole background)
virtual void paintBackground(const QRegion &region) = 0;
// called after all effects had their paintWindow() called

View file

@ -99,32 +99,6 @@ void SceneOpenGL::paint(RenderTarget *renderTarget, const QRegion &region)
GLVertexBuffer::streamingBuffer()->endOfFrame();
}
QMatrix4x4 SceneOpenGL::transformation(int mask, const ScreenPaintData &data) const
{
QMatrix4x4 matrix;
if (!(mask & PAINT_SCREEN_TRANSFORMED)) {
return matrix;
}
matrix.translate(data.translation());
const QVector3D scale = data.scale();
matrix.scale(scale.x(), scale.y(), scale.z());
if (data.rotationAngle() == 0.0) {
return matrix;
}
// Apply the rotation
// cannot use data.rotation->applyTo(&matrix) as QGraphicsRotation uses projectedRotate to map back to 2D
matrix.translate(data.rotationOrigin());
const QVector3D axis = data.rotationAxis();
matrix.rotate(data.rotationAngle(), axis.x(), axis.y(), axis.z());
matrix.translate(-data.rotationOrigin());
return matrix;
}
void SceneOpenGL::paintBackground(const QRegion &region)
{
if (region == infiniteRegion()) {
@ -257,22 +231,6 @@ bool SceneOpenGL::supported(OpenGLBackend *backend)
return true;
}
void SceneOpenGL::paintSimpleScreen(int mask, const QRegion &region)
{
m_screenProjectionMatrix = renderTargetProjectionMatrix();
Scene::paintSimpleScreen(mask, region);
}
void SceneOpenGL::paintGenericScreen(int mask, const ScreenPaintData &data)
{
const QMatrix4x4 screenMatrix = transformation(mask, data);
m_screenProjectionMatrix = renderTargetProjectionMatrix() * screenMatrix;
Scene::paintGenericScreen(mask, data);
}
void SceneOpenGL::doPaintBackground(const QVector<float> &vertices)
{
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
@ -446,17 +404,17 @@ void SceneOpenGL::createRenderNode(Item *item, RenderContext *context)
QMatrix4x4 SceneOpenGL::modelViewProjectionMatrix(const WindowPaintData &data) const
{
const QMatrix4x4 pMatrix = data.projectionMatrix();
// An effect may want to override the default projection matrix in some cases,
// such as when it is rendering a window on a render target that doesn't have
// the same dimensions as the default framebuffer.
//
// Note that the screen transformation is not applied here.
const QMatrix4x4 pMatrix = data.projectionMatrix();
if (!pMatrix.isIdentity()) {
return pMatrix;
} else {
return renderTargetProjectionMatrix();
}
return m_screenProjectionMatrix;
}
static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)

View file

@ -72,22 +72,13 @@ public:
QVector<QByteArray> openGLPlatformInterfaceExtensions() const override;
std::shared_ptr<GLTexture> textureForOutput(Output *output) const override;
QMatrix4x4 screenProjectionMatrix() const override
{
return m_screenProjectionMatrix;
}
static SceneOpenGL *createScene(OpenGLBackend *backend, QObject *parent);
static bool supported(OpenGLBackend *backend);
protected:
void paintBackground(const QRegion &region) override;
QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
void paintOffscreenQuickView(OffscreenQuickView *w) override;
void paintSimpleScreen(int mask, const QRegion &region) override;
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
private:
void doPaintBackground(const QVector<float> &vertices);
QMatrix4x4 modelViewProjectionMatrix(const WindowPaintData &data) const;
@ -97,7 +88,6 @@ private:
bool init_ok = true;
OpenGLBackend *m_backend;
QMatrix4x4 m_screenProjectionMatrix;
GLuint vao = 0;
bool m_blendingEnabled = false;
};

View file

@ -58,15 +58,6 @@ bool SceneQPainter::initFailed() const
return false;
}
void SceneQPainter::paintGenericScreen(int mask, const ScreenPaintData &data)
{
m_painter->save();
m_painter->translate(data.xTranslation(), data.yTranslation());
m_painter->scale(data.xScale(), data.yScale());
Scene::paintGenericScreen(mask, data);
m_painter->restore();
}
void SceneQPainter::paint(RenderTarget *target, const QRegion &region)
{
QImage *buffer = std::get<QImage *>(target->nativeHandle());

View file

@ -25,7 +25,6 @@ class KWIN_EXPORT SceneQPainter : public Scene
public:
~SceneQPainter() override;
void paint(RenderTarget *renderTarget, const QRegion &region) override;
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
bool initFailed() const override;
Shadow *createShadow(Window *window) override;
DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override;