[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
This commit is contained in:
parent
ed5768181e
commit
dfea5798f1
2 changed files with 69 additions and 25 deletions
|
@ -650,35 +650,64 @@ bool DrmOutput::dpmsLegacyApply()
|
|||
return true;
|
||||
}
|
||||
|
||||
void DrmOutput::updateTransform(Transform transform)
|
||||
{
|
||||
DrmPlane::Transformation planeTransform;
|
||||
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 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;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
bool DrmOutput::hardwareTransforms() const
|
||||
{
|
||||
if (!m_primaryPlane) {
|
||||
return false;
|
||||
}
|
||||
return m_primaryPlane->transformation() == outputToPlaneTransform(transform());
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue