Commit f1741317 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

platforms/drm: Fix software flip output transforms

Currently, flip output transformations in the software fallback code
path are equivalent to normal rotate output transformations.

This change implements flip output transformations according to the
wl_output spec.
parent 3b8e489b
......@@ -311,45 +311,48 @@ AbstractWaylandOutput::Transform AbstractWaylandOutput::transform() const
return static_cast<Transform>(m_waylandOutputDevice->transform());
}
// TODO: Do we need to handle the flipped cases differently?
int transformToRotation(AbstractWaylandOutput::Transform transform)
{
switch (transform) {
case AbstractWaylandOutput::Transform::Normal:
case AbstractWaylandOutput::Transform::Flipped:
return 0;
case AbstractWaylandOutput::Transform::Rotated90:
case AbstractWaylandOutput::Transform::Flipped90:
return 90;
case AbstractWaylandOutput::Transform::Rotated180:
case AbstractWaylandOutput::Transform::Flipped180:
return 180;
case AbstractWaylandOutput::Transform::Rotated270:
case AbstractWaylandOutput::Transform::Flipped270:
return 270;
}
Q_UNREACHABLE();
return 0;
}
int AbstractWaylandOutput::rotation() const
{
return transformToRotation(transform());
}
QMatrix4x4 AbstractWaylandOutput::transformation() const
{
const QSize outputSize = modeSize();
const QSize logicalSize = pixelSize();
const QRect rect = geometry();
QMatrix4x4 matrix;
matrix.translate(outputSize.width()/2, outputSize.height()/2);
matrix.rotate(rotation(), 0, 0, 1);
matrix.translate(-logicalSize.width()/2, -logicalSize.height()/2);
matrix.scale(scale());
const QPoint topLeft = -globalPos();
matrix.translate(-topLeft.x(), -topLeft.y());
switch (transform()) {
case Transform::Normal:
case Transform::Flipped:
break;
case Transform::Rotated90:
case Transform::Flipped90:
matrix.translate(0, rect.width());
matrix.rotate(-90, 0, 0, 1);
break;
case Transform::Rotated180:
case Transform::Flipped180:
matrix.translate(rect.width(), rect.height());
matrix.rotate(-180, 0, 0, 1);
break;
case Transform::Rotated270:
case Transform::Flipped270:
matrix.translate(rect.height(), 0);
matrix.rotate(-270, 0, 0, 1);
break;
}
switch (transform()) {
case Transform::Flipped:
case Transform::Flipped90:
case Transform::Flipped180:
case Transform::Flipped270:
matrix.translate(rect.width(), 0);
matrix.scale(-1, 1);
break;
default:
break;
}
matrix.translate(-rect.x(), -rect.y());
return matrix;
}
......
......@@ -112,13 +112,6 @@ public:
QString description() const;
/**
* The current rotation of the output
*
* @return rotation in degrees
*/
int rotation() const;
/**
* Returns a matrix that can translate into the display's coordinates system
*/
......
......@@ -197,33 +197,10 @@ void DrmOutput::updateCursor()
void DrmOutput::moveCursor(Cursor *cursor, const QPoint &globalPos)
{
const QPoint localPos = globalPos - AbstractWaylandOutput::globalPos();
QPoint pos = localPos;
// TODO: Do we need to handle the flipped cases differently?
switch (transform()) {
case Transform::Normal:
case Transform::Flipped:
break;
case Transform::Rotated90:
case Transform::Flipped90:
pos = QPoint(localPos.y(), pixelSize().width() / scale() - localPos.x());
break;
case Transform::Rotated270:
case Transform::Flipped270:
pos = QPoint(pixelSize().height() / scale() - localPos.y(), localPos.x());
break;
case Transform::Rotated180:
case Transform::Flipped180:
pos = QPoint(pixelSize().width() / scale() - localPos.x(),
pixelSize().height() / scale() - localPos.y());
break;
default:
Q_UNREACHABLE();
}
pos *= scale();
const QMatrix4x4 hotspotMatrix = matrixForTransform(cursor->image().rect(), scale(), transform());
const QMatrix4x4 monitorMatrix = transformation();
QPoint pos = monitorMatrix.map(globalPos);
pos -= hotspotMatrix.map(cursor->hotspot());
drmModeMoveCursor(m_gpu->fd(), m_crtc->id(), pos.x(), pos.y());
......
......@@ -323,9 +323,38 @@ void EglGbmBackend::renderFramebufferToSurface(Output &output)
auto shader = ShaderManager::instance()->pushShader(ShaderTrait::MapTexture);
QMatrix4x4 rotationMatrix;
rotationMatrix.rotate(output.output->rotation(), 0, 0, 1);
shader->setUniform(GLShader::ModelViewProjectionMatrix, rotationMatrix);
QMatrix4x4 mvpMatrix;
const DrmOutput *drmOutput = output.output;
switch (drmOutput->transform()) {
case DrmOutput::Transform::Normal:
case DrmOutput::Transform::Flipped:
break;
case DrmOutput::Transform::Rotated90:
case DrmOutput::Transform::Flipped90:
mvpMatrix.rotate(90, 0, 0, 1);
break;
case DrmOutput::Transform::Rotated180:
case DrmOutput::Transform::Flipped180:
mvpMatrix.rotate(180, 0, 0, 1);
break;
case DrmOutput::Transform::Rotated270:
case DrmOutput::Transform::Flipped270:
mvpMatrix.rotate(270, 0, 0, 1);
break;
}
switch (drmOutput->transform()) {
case DrmOutput::Transform::Flipped:
case DrmOutput::Transform::Flipped90:
case DrmOutput::Transform::Flipped180:
case DrmOutput::Transform::Flipped270:
mvpMatrix.scale(-1, 1);
break;
default:
break;
}
shader->setUniform(GLShader::ModelViewProjectionMatrix, mvpMatrix);
glBindTexture(GL_TEXTURE_2D, output.render.texture);
output.render.vbo->render(GL_TRIANGLES);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment