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
parent
1fd9ae618a
commit
642be48bd2
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue