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.
This commit is contained in:
parent
3b8e489b6f
commit
f1741317cd
4 changed files with 71 additions and 69 deletions
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue