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.
icc-effect-5.20.5
Vlad Zahorodnii 2020-10-13 23:15:46 +03:00
parent 1fd9ae618a
commit 642be48bd2
4 changed files with 71 additions and 69 deletions

View File

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

View File

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

View File

@ -193,33 +193,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_backend->fd(), m_crtc->id(), pos.x(), pos.y());

View File

@ -320,9 +320,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);