core: Make flip transform first

The wayland spec says we must flip first. FWIW it also matches how
kms processes reflect-x and reflect-y.
This commit is contained in:
Vlad Zahorodnii 2023-12-20 23:23:34 +02:00
parent 1905f7586e
commit 47017d19de
3 changed files with 78 additions and 58 deletions

View file

@ -103,9 +103,9 @@ void TestOutputTransform::mapRectF_data()
QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QRectF(10, 20, 30, 40) << QRectF(60, 140, 30, 40);
QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QRectF(10, 20, 30, 40) << QRectF(140, 10, 40, 30);
QTest::addRow("flip-0") << OutputTransform::Flipped << QRectF(10, 20, 30, 40) << QRectF(60, 20, 30, 40);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRectF(10, 20, 30, 40) << QRectF(140, 60, 40, 30);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRectF(10, 20, 30, 40) << QRectF(20, 10, 40, 30);
QTest::addRow("flip-180") << OutputTransform::Flipped180 << QRectF(10, 20, 30, 40) << QRectF(10, 140, 30, 40);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRectF(10, 20, 30, 40) << QRectF(20, 10, 40, 30);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRectF(10, 20, 30, 40) << QRectF(140, 60, 40, 30);
}
void TestOutputTransform::mapRectF()
@ -128,9 +128,9 @@ void TestOutputTransform::mapRect_data()
QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QRect(10, 20, 30, 40) << QRect(60, 140, 30, 40);
QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QRect(10, 20, 30, 40) << QRect(140, 10, 40, 30);
QTest::addRow("flip-0") << OutputTransform::Flipped << QRect(10, 20, 30, 40) << QRect(60, 20, 30, 40);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRect(10, 20, 30, 40) << QRect(140, 60, 40, 30);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRect(10, 20, 30, 40) << QRect(20, 10, 40, 30);
QTest::addRow("flip-180") << OutputTransform::Flipped180 << QRect(10, 20, 30, 40) << QRect(10, 140, 30, 40);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRect(10, 20, 30, 40) << QRect(20, 10, 40, 30);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRect(10, 20, 30, 40) << QRect(140, 60, 40, 30);
}
void TestOutputTransform::mapRect()
@ -153,9 +153,9 @@ void TestOutputTransform::mapPointF_data()
QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QPointF(10, 20) << QPointF(90, 180);
QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QPointF(10, 20) << QPointF(180, 10);
QTest::addRow("flip-0") << OutputTransform::Flipped << QPointF(10, 20) << QPointF(90, 20);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPointF(10, 20) << QPointF(180, 90);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPointF(10, 20) << QPointF(20, 10);
QTest::addRow("flip-180") << OutputTransform::Flipped180 << QPointF(10, 20) << QPointF(10, 180);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPointF(10, 20) << QPointF(20, 10);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPointF(10, 20) << QPointF(180, 90);
}
void TestOutputTransform::mapPointF()
@ -181,9 +181,9 @@ void TestOutputTransform::mapPoint_data()
QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QPoint(10, 20) << QPoint(90, 180);
QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QPoint(10, 20) << QPoint(180, 10);
QTest::addRow("flip-0") << OutputTransform::Flipped << QPoint(10, 20) << QPoint(90, 20);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPoint(10, 20) << QPoint(180, 90);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QPoint(10, 20) << QPoint(20, 10);
QTest::addRow("flip-180") << OutputTransform::Flipped180 << QPoint(10, 20) << QPoint(10, 180);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPoint(10, 20) << QPoint(20, 10);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QPoint(10, 20) << QPoint(180, 90);
}
void TestOutputTransform::mapPoint()
@ -240,10 +240,10 @@ void TestOutputTransform::combine_data()
QTest::addRow("rotate-90 | rotate-90") << OutputTransform::Rotated90 << OutputTransform::Rotated90 << OutputTransform::Rotated180;
QTest::addRow("rotate-180 | rotate-90") << OutputTransform::Rotated180 << OutputTransform::Rotated90 << OutputTransform::Rotated270;
QTest::addRow("rotate-270 | rotate-90") << OutputTransform::Rotated270 << OutputTransform::Rotated90 << OutputTransform::Normal;
QTest::addRow("flip-0 | rotate-90") << OutputTransform::Flipped << OutputTransform::Rotated90 << OutputTransform::Flipped270;
QTest::addRow("flip-90 | rotate-90") << OutputTransform::Flipped90 << OutputTransform::Rotated90 << OutputTransform::Flipped;
QTest::addRow("flip-180 | rotate-90") << OutputTransform::Flipped180 << OutputTransform::Rotated90 << OutputTransform::Flipped90;
QTest::addRow("flip-270 | rotate-90") << OutputTransform::Flipped270 << OutputTransform::Rotated90 << OutputTransform::Flipped180;
QTest::addRow("flip-0 | rotate-90") << OutputTransform::Flipped << OutputTransform::Rotated90 << OutputTransform::Flipped90;
QTest::addRow("flip-90 | rotate-90") << OutputTransform::Flipped90 << OutputTransform::Rotated90 << OutputTransform::Flipped180;
QTest::addRow("flip-180 | rotate-90") << OutputTransform::Flipped180 << OutputTransform::Rotated90 << OutputTransform::Flipped270;
QTest::addRow("flip-270 | rotate-90") << OutputTransform::Flipped270 << OutputTransform::Rotated90 << OutputTransform::Flipped;
QTest::addRow("rotate-0 | rotate-180") << OutputTransform::Normal << OutputTransform::Rotated180 << OutputTransform::Rotated180;
QTest::addRow("rotate-90 | rotate-180") << OutputTransform::Rotated90 << OutputTransform::Rotated180 << OutputTransform::Rotated270;
@ -258,45 +258,45 @@ void TestOutputTransform::combine_data()
QTest::addRow("rotate-90 | rotate-270") << OutputTransform::Rotated90 << OutputTransform::Rotated270 << OutputTransform::Normal;
QTest::addRow("rotate-180 | rotate-270") << OutputTransform::Rotated180 << OutputTransform::Rotated270 << OutputTransform::Rotated90;
QTest::addRow("rotate-270 | rotate-270") << OutputTransform::Rotated270 << OutputTransform::Rotated270 << OutputTransform::Rotated180;
QTest::addRow("flip-0 | rotate-270") << OutputTransform::Flipped << OutputTransform::Rotated270 << OutputTransform::Flipped90;
QTest::addRow("flip-90 | rotate-270") << OutputTransform::Flipped90 << OutputTransform::Rotated270 << OutputTransform::Flipped180;
QTest::addRow("flip-180 | rotate-270") << OutputTransform::Flipped180 << OutputTransform::Rotated270 << OutputTransform::Flipped270;
QTest::addRow("flip-270 | rotate-270") << OutputTransform::Flipped270 << OutputTransform::Rotated270 << OutputTransform::Flipped;
QTest::addRow("flip-0 | rotate-270") << OutputTransform::Flipped << OutputTransform::Rotated270 << OutputTransform::Flipped270;
QTest::addRow("flip-90 | rotate-270") << OutputTransform::Flipped90 << OutputTransform::Rotated270 << OutputTransform::Flipped;
QTest::addRow("flip-180 | rotate-270") << OutputTransform::Flipped180 << OutputTransform::Rotated270 << OutputTransform::Flipped90;
QTest::addRow("flip-270 | rotate-270") << OutputTransform::Flipped270 << OutputTransform::Rotated270 << OutputTransform::Flipped180;
QTest::addRow("rotate-0 | flip-0") << OutputTransform::Normal << OutputTransform::Flipped << OutputTransform::Flipped;
QTest::addRow("rotate-90 | flip-0") << OutputTransform::Rotated90 << OutputTransform::Flipped << OutputTransform::Flipped90;
QTest::addRow("rotate-90 | flip-0") << OutputTransform::Rotated90 << OutputTransform::Flipped << OutputTransform::Flipped270;
QTest::addRow("rotate-180 | flip-0") << OutputTransform::Rotated180 << OutputTransform::Flipped << OutputTransform::Flipped180;
QTest::addRow("rotate-270 | flip-0") << OutputTransform::Rotated270 << OutputTransform::Flipped << OutputTransform::Flipped270;
QTest::addRow("rotate-270 | flip-0") << OutputTransform::Rotated270 << OutputTransform::Flipped << OutputTransform::Flipped90;
QTest::addRow("flip-0 | flip-0") << OutputTransform::Flipped << OutputTransform::Flipped << OutputTransform::Normal;
QTest::addRow("flip-90 | flip-0") << OutputTransform::Flipped90 << OutputTransform::Flipped << OutputTransform::Rotated90;
QTest::addRow("flip-90 | flip-0") << OutputTransform::Flipped90 << OutputTransform::Flipped << OutputTransform::Rotated270;
QTest::addRow("flip-180 | flip-0") << OutputTransform::Flipped180 << OutputTransform::Flipped << OutputTransform::Rotated180;
QTest::addRow("flip-270 | flip-0") << OutputTransform::Flipped270 << OutputTransform::Flipped << OutputTransform::Rotated270;
QTest::addRow("flip-270 | flip-0") << OutputTransform::Flipped270 << OutputTransform::Flipped << OutputTransform::Rotated90;
QTest::addRow("rotate-0 | flip-90") << OutputTransform::Normal << OutputTransform::Flipped90 << OutputTransform::Flipped90;
QTest::addRow("rotate-90 | flip-90") << OutputTransform::Rotated90 << OutputTransform::Flipped90 << OutputTransform::Flipped180;
QTest::addRow("rotate-90 | flip-90") << OutputTransform::Rotated90 << OutputTransform::Flipped90 << OutputTransform::Flipped;
QTest::addRow("rotate-180 | flip-90") << OutputTransform::Rotated180 << OutputTransform::Flipped90 << OutputTransform::Flipped270;
QTest::addRow("rotate-270 | flip-90") << OutputTransform::Rotated270 << OutputTransform::Flipped90 << OutputTransform::Flipped;
QTest::addRow("flip-0 | flip-90") << OutputTransform::Flipped << OutputTransform::Flipped90 << OutputTransform::Rotated270;
QTest::addRow("rotate-270 | flip-90") << OutputTransform::Rotated270 << OutputTransform::Flipped90 << OutputTransform::Flipped180;
QTest::addRow("flip-0 | flip-90") << OutputTransform::Flipped << OutputTransform::Flipped90 << OutputTransform::Rotated90;
QTest::addRow("flip-90 | flip-90") << OutputTransform::Flipped90 << OutputTransform::Flipped90 << OutputTransform::Normal;
QTest::addRow("flip-180 | flip-90") << OutputTransform::Flipped180 << OutputTransform::Flipped90 << OutputTransform::Rotated90;
QTest::addRow("flip-180 | flip-90") << OutputTransform::Flipped180 << OutputTransform::Flipped90 << OutputTransform::Rotated270;
QTest::addRow("flip-270 | flip-90") << OutputTransform::Flipped270 << OutputTransform::Flipped90 << OutputTransform::Rotated180;
QTest::addRow("rotate-0 | flip-180") << OutputTransform::Normal << OutputTransform::Flipped180 << OutputTransform::Flipped180;
QTest::addRow("rotate-90 | flip-180") << OutputTransform::Rotated90 << OutputTransform::Flipped180 << OutputTransform::Flipped270;
QTest::addRow("rotate-90 | flip-180") << OutputTransform::Rotated90 << OutputTransform::Flipped180 << OutputTransform::Flipped90;
QTest::addRow("rotate-180 | flip-180") << OutputTransform::Rotated180 << OutputTransform::Flipped180 << OutputTransform::Flipped;
QTest::addRow("rotate-270 | flip-180") << OutputTransform::Rotated270 << OutputTransform::Flipped180 << OutputTransform::Flipped90;
QTest::addRow("rotate-270 | flip-180") << OutputTransform::Rotated270 << OutputTransform::Flipped180 << OutputTransform::Flipped270;
QTest::addRow("flip-0 | flip-180") << OutputTransform::Flipped << OutputTransform::Flipped180 << OutputTransform::Rotated180;
QTest::addRow("flip-90 | flip-180") << OutputTransform::Flipped90 << OutputTransform::Flipped180 << OutputTransform::Rotated270;
QTest::addRow("flip-90 | flip-180") << OutputTransform::Flipped90 << OutputTransform::Flipped180 << OutputTransform::Rotated90;
QTest::addRow("flip-180 | flip-180") << OutputTransform::Flipped180 << OutputTransform::Flipped180 << OutputTransform::Normal;
QTest::addRow("flip-270 | flip-180") << OutputTransform::Flipped270 << OutputTransform::Flipped180 << OutputTransform::Rotated90;
QTest::addRow("flip-270 | flip-180") << OutputTransform::Flipped270 << OutputTransform::Flipped180 << OutputTransform::Rotated270;
QTest::addRow("rotate-0 | flip-270") << OutputTransform::Normal << OutputTransform::Flipped270 << OutputTransform::Flipped270;
QTest::addRow("rotate-90 | flip-270") << OutputTransform::Rotated90 << OutputTransform::Flipped270 << OutputTransform::Flipped;
QTest::addRow("rotate-90 | flip-270") << OutputTransform::Rotated90 << OutputTransform::Flipped270 << OutputTransform::Flipped180;
QTest::addRow("rotate-180 | flip-270") << OutputTransform::Rotated180 << OutputTransform::Flipped270 << OutputTransform::Flipped90;
QTest::addRow("rotate-270 | flip-270") << OutputTransform::Rotated270 << OutputTransform::Flipped270 << OutputTransform::Flipped180;
QTest::addRow("flip-0 | flip-270") << OutputTransform::Flipped << OutputTransform::Flipped270 << OutputTransform::Rotated90;
QTest::addRow("rotate-270 | flip-270") << OutputTransform::Rotated270 << OutputTransform::Flipped270 << OutputTransform::Flipped;
QTest::addRow("flip-0 | flip-270") << OutputTransform::Flipped << OutputTransform::Flipped270 << OutputTransform::Rotated270;
QTest::addRow("flip-90 | flip-270") << OutputTransform::Flipped90 << OutputTransform::Flipped270 << OutputTransform::Rotated180;
QTest::addRow("flip-180 | flip-270") << OutputTransform::Flipped180 << OutputTransform::Flipped270 << OutputTransform::Rotated270;
QTest::addRow("flip-180 | flip-270") << OutputTransform::Flipped180 << OutputTransform::Flipped270 << OutputTransform::Rotated90;
QTest::addRow("flip-270 | flip-270") << OutputTransform::Flipped270 << OutputTransform::Flipped270 << OutputTransform::Normal;
}
@ -327,9 +327,9 @@ void TestOutputTransform::matrix_data()
QTest::addRow("rotate-180") << OutputTransform::Rotated180 << QRectF(10, 20, 30, 40) << QRectF(60, 140, 30, 40);
QTest::addRow("rotate-270") << OutputTransform::Rotated270 << QRectF(10, 20, 30, 40) << QRectF(140, 10, 40, 30);
QTest::addRow("flip-0") << OutputTransform::Flipped << QRectF(10, 20, 30, 40) << QRectF(60, 20, 30, 40);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRectF(10, 20, 30, 40) << QRectF(140, 60, 40, 30);
QTest::addRow("flip-90") << OutputTransform::Flipped90 << QRectF(10, 20, 30, 40) << QRectF(20, 10, 40, 30);
QTest::addRow("flip-180") << OutputTransform::Flipped180 << QRectF(10, 20, 30, 40) << QRectF(10, 140, 30, 40);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRectF(10, 20, 30, 40) << QRectF(20, 10, 40, 30);
QTest::addRow("flip-270") << OutputTransform::Flipped270 << QRectF(10, 20, 30, 40) << QRectF(140, 60, 40, 30);
}
void TestOutputTransform::matrix()

View file

@ -113,8 +113,8 @@ QRectF OutputTransform::map(const QRectF &rect, const QSizeF &bounds) const
rect.width(),
rect.height());
case Kind::Flipped90:
return QRectF(bounds.height() - (rect.y() + rect.height()),
bounds.width() - (rect.x() + rect.width()),
return QRectF(rect.y(),
rect.x(),
rect.height(),
rect.width());
case Kind::Flipped180:
@ -123,8 +123,8 @@ QRectF OutputTransform::map(const QRectF &rect, const QSizeF &bounds) const
rect.width(),
rect.height());
case Kind::Flipped270:
return QRectF(rect.y(),
rect.x(),
return QRectF(bounds.height() - (rect.y() + rect.height()),
bounds.width() - (rect.x() + rect.width()),
rect.height(),
rect.width());
default:
@ -158,8 +158,8 @@ QRect OutputTransform::map(const QRect &rect, const QSize &bounds) const
rect.width(),
rect.height());
case Kind::Flipped90:
return QRect(bounds.height() - (rect.y() + rect.height()),
bounds.width() - (rect.x() + rect.width()),
return QRect(rect.y(),
rect.x(),
rect.height(),
rect.width());
case Kind::Flipped180:
@ -168,8 +168,8 @@ QRect OutputTransform::map(const QRect &rect, const QSize &bounds) const
rect.width(),
rect.height());
case Kind::Flipped270:
return QRect(rect.y(),
rect.x(),
return QRect(bounds.height() - (rect.y() + rect.height()),
bounds.width() - (rect.x() + rect.width()),
rect.height(),
rect.width());
default:
@ -195,14 +195,14 @@ QPointF OutputTransform::map(const QPointF &point, const QSizeF &bounds) const
return QPointF(bounds.width() - point.x(),
point.y());
case Kind::Flipped90:
return QPointF(bounds.height() - point.y(),
bounds.width() - point.x());
return QPointF(point.y(),
point.x());
case Kind::Flipped180:
return QPointF(point.x(),
bounds.height() - point.y());
case Kind::Flipped270:
return QPointF(point.y(),
point.x());
return QPointF(bounds.height() - point.y(),
bounds.width() - point.x());
default:
Q_UNREACHABLE();
}
@ -226,14 +226,14 @@ QPoint OutputTransform::map(const QPoint &point, const QSize &bounds) const
return QPoint(bounds.width() - point.x(),
point.y());
case Kind::Flipped90:
return QPoint(bounds.height() - point.y(),
bounds.width() - point.x());
return QPoint(point.y(),
point.x());
case Kind::Flipped180:
return QPoint(point.x(),
bounds.height() - point.y());
case Kind::Flipped270:
return QPoint(point.y(),
point.x());
return QPoint(bounds.height() - point.y(),
bounds.width() - point.x());
default:
Q_UNREACHABLE();
}
@ -267,10 +267,30 @@ QSize OutputTransform::map(const QSize &size) const
OutputTransform OutputTransform::combine(OutputTransform other) const
{
// Combining a rotate-N or flip-N (mirror-x | rotate-N) transform with a rotate-M
// transform involves only adding rotation angles:
// rotate-N | rotate-M => rotate-(N + M)
// flip-N | rotate-M => mirror-x | rotate-N | rotate-M
// => mirror-x | rotate-(N + M)
// => flip-(N + M)
//
// rotate-N | mirror-x is the same as mirror-x | rotate-(360 - N). This can be used
// to derive the resulting transform if the other transform flips the x axis
// rotate-N | flip-M => rotate-N | mirror-x | rotate-M
// => mirror-x | rotate-(360 - N + M)
// => flip-(M - N)
// flip-N | flip-M => mirror-x | rotate-N | mirror-x | rotate-M
// => mirror-x | mirror-x | rotate-(360 - N + M)
// => rotate-(360 - N + M)
// => rotate-(M - N)
//
// The remaining code here relies on the bit pattern of transform enums, i.e. the
// lower two bits specify the rotation, the third bit indicates mirroring along the x axis.
const int flip = (m_kind ^ other.m_kind) & 0x4;
int rotate;
if (m_kind & 0x4) {
rotate = (m_kind - other.m_kind) & 0x3; // rotate counter-clockwise if flipped
if (other.m_kind & 0x4) {
rotate = (other.m_kind - m_kind) & 0x3;
} else {
rotate = (m_kind + other.m_kind) & 0x3;
}
@ -296,16 +316,16 @@ QMatrix4x4 OutputTransform::toMatrix() const
matrix.scale(-1, 1);
break;
case Kind::Flipped90:
matrix.scale(-1, 1);
matrix.rotate(-90, 0, 0, 1);
matrix.scale(-1, 1);
break;
case Kind::Flipped180:
matrix.scale(-1, 1);
matrix.rotate(-180, 0, 0, 1);
matrix.scale(-1, 1);
break;
case Kind::Flipped270:
matrix.scale(-1, 1);
matrix.rotate(-270, 0, 0, 1);
matrix.scale(-1, 1);
break;
default:
Q_UNREACHABLE();

View file

@ -43,9 +43,9 @@ public:
Rotated180 = 2, // rotate 180 degrees counterclockwise
Rotated270 = 3, // rotate 270 degrees counterclockwise
Flipped = 4, // mirror horizontally
Flipped90 = 5, // rotate 90 degrees counterclockwise, then mirror horizontally
Flipped180 = 6, // rotate 180 degrees counterclockwise, then mirror horizontally
Flipped270 = 7, // rotate 270 degrees counterclockwise, then mirror horizontally
Flipped90 = 5, // mirror horizontally, then rotate 90 degrees counterclockwise
Flipped180 = 6, // mirror horizontally, then rotate 180 degrees counterclockwise
Flipped270 = 7, // mirror horizontally, then rotate 270 degrees counterclockwise
};
OutputTransform() = default;