Commit dfea5798 authored by Roman Gilg's avatar Roman Gilg Committed by David Edmundson

[platforms/drm] Add hardware transformation API

Summary:
Planes might be able to do transformations without compositing required.
When changing the current transform try this with the primary plane. If this
fails fall back to no transformation at all through hardware and communicate
the fact and other information through some getters.

Also adds an environment variable to never do hardware transformations.

Test Plan: Compiles.

Reviewers: #kwin

Subscribers: zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D25906
parent ed576818
......@@ -650,35 +650,64 @@ bool DrmOutput::dpmsLegacyApply()
return true;
}
void DrmOutput::updateTransform(Transform transform)
{
DrmPlane::Transformation planeTransform;
// TODO: Do we want to support reflections (flips)?
DrmPlane::Transformations outputToPlaneTransform(DrmOutput::Transform transform)
{
using OutTrans = DrmOutput::Transform;
using PlaneTrans = DrmPlane::Transformation;
// TODO: Do we want to support reflections (flips)?
switch (transform) {
case OutTrans::Normal:
case OutTrans::Flipped:
return PlaneTrans::Rotate0;
case OutTrans::Rotated90:
case OutTrans::Flipped90:
return PlaneTrans::Rotate90;
case OutTrans::Rotated180:
case OutTrans::Flipped180:
return PlaneTrans::Rotate180;
case OutTrans::Rotated270:
case OutTrans::Flipped270:
return PlaneTrans::Rotate270;
default:
Q_UNREACHABLE();
}
}
switch (transform) {
case Transform::Normal:
case Transform::Flipped:
planeTransform = DrmPlane::Transformation::Rotate0;
break;
case Transform::Rotated90:
case Transform::Flipped90:
planeTransform = DrmPlane::Transformation::Rotate90;
break;
case Transform::Rotated180:
case Transform::Flipped180:
planeTransform = DrmPlane::Transformation::Rotate180;
break;
case Transform::Rotated270:
case Transform::Flipped270:
planeTransform = DrmPlane::Transformation::Rotate270;
break;
default:
Q_UNREACHABLE();
bool DrmOutput::hardwareTransforms() const
{
if (!m_primaryPlane) {
return false;
}
return m_primaryPlane->transformation() == outputToPlaneTransform(transform());
}
if (m_primaryPlane) {
m_primaryPlane->setTransformation(planeTransform);
int DrmOutput::rotation() const
{
return transformToRotation(transform());
}
void DrmOutput::updateTransform(Transform transform)
{
const auto planeTransform = outputToPlaneTransform(transform);
if (m_primaryPlane) {
// At the moment we have to exclude hardware transforms for vertical buffers.
// For that we need to support other buffers and graceful fallback from atomic tests.
// Reason is that standard linear buffers are not suitable.
const bool isPortrait = transform == Transform::Rotated90
|| transform == Transform::Flipped90
|| transform == Transform::Rotated270
|| transform == Transform::Flipped270;
if (!qEnvironmentVariableIsSet("KWIN_DRM_SW_ROTATIONS_ONLY") &&
(m_primaryPlane->supportedTransformations() & planeTransform) &&
!isPortrait) {
m_primaryPlane->setTransformation(planeTransform);
} else {
m_primaryPlane->setTransformation(DrmPlane::Transformation::Rotate0);
}
}
m_modesetRequested = true;
......
......@@ -83,6 +83,21 @@ public:
bool supportsTransformations() const;
/**
* Drm planes might be capable of realizing the current output transform without usage
* of compositing. This is a getter to query the current state of that
*
* @return true if the hardware realizes the transform without further assistance
*/
bool hardwareTransforms() const;
/**
* The current rotation of the output
*
* @return rotation in degree
*/
int rotation() const;
private:
friend class DrmBackend;
friend class DrmCrtc; // TODO: For use of setModeLegacy. Remove later when we allow multiple connectors per crtc
......
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