drm: Properly check for the need for transformation

At the moment we were checking for size difference between the buffers
which works for rotation but not for flipped or up-side down screens.

This changes how we check it by comparing the effective transform vs the
supported one in drm to see if they differ.

Fixes https://invent.kde.org/plasma/plasma-phone-components/-/issues/112
This commit is contained in:
Aleix Pol 2021-09-10 19:12:27 +02:00
parent 5f306ae93d
commit 883dbfda17
6 changed files with 15 additions and 6 deletions

View file

@ -31,6 +31,7 @@ public:
virtual bool present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion) = 0;
virtual bool needsSoftwareTransformation() const = 0;
virtual bool isDpmsEnabled() const = 0;
virtual GbmBuffer *currentBuffer() const = 0;
virtual QSize sourceSize() const = 0;

View file

@ -346,6 +346,11 @@ void DrmOutput::updateModes()
}
}
bool DrmOutput::needsSoftwareTransformation() const
{
return m_pipeline->transformation() != outputToPlaneTransform(transform());
}
void DrmOutput::updateMode(const QSize &size, uint32_t refreshRate)
{
auto conn = m_pipeline->connector();

View file

@ -58,6 +58,7 @@ public:
QSize sourceSize() const override;
bool isFormatSupported(uint32_t drmFormat) const override;
QVector<uint64_t> supportedModifiers(uint32_t drmFormat) const override;
bool needsSoftwareTransformation() const override;
private:
friend class DrmGpu;

View file

@ -42,6 +42,9 @@ public:
Q_UNUSED(gamma);
return true;
}
bool needsSoftwareTransformation() const override {
return false;
}
private:
void vblank(std::chrono::nanoseconds timestamp);

View file

@ -179,7 +179,7 @@ bool EglGbmBackend::resetOutput(Output &output)
output.current = {};
output.current.gbmSurface = gbmSurface;
if (size == output.output->pixelSize()) {
if (!output.output->needsSoftwareTransformation()) {
output.current.shadowBuffer = nullptr;
} else {
makeContextCurrent(output.current);
@ -524,10 +524,9 @@ bool EglGbmBackend::doesRenderFit(DrmAbstractOutput *output, const Output::Rende
if (surfaceSize != render.gbmSurface->size()) {
return false;
}
QSize pixelSize = output->pixelSize();
bool needsTexture = surfaceSize != pixelSize;
bool needsTexture = output->needsSoftwareTransformation();
if (needsTexture) {
return render.shadowBuffer && render.shadowBuffer->textureSize() == pixelSize;
return render.shadowBuffer && render.shadowBuffer->textureSize() == output->pixelSize();
} else {
return render.shadowBuffer == nullptr;
}

View file

@ -358,7 +358,7 @@ bool EglStreamBackend::resetOutput(Output &o)
o.eglStream = stream;
o.eglSurface = eglSurface;
if (sourceSize != drmOutput->pixelSize()) {
if (drmOutput->needsSoftwareTransformation()) {
makeContextCurrent(o);
o.shadowBuffer = QSharedPointer<ShadowBuffer>::create(o.output->pixelSize());
if (!o.shadowBuffer->isComplete()) {
@ -482,7 +482,7 @@ bool EglStreamBackend::needsReset(const Output &o) const
if (surfaceSize != o.output->sourceSize()) {
return true;
}
bool needsTexture = surfaceSize != o.output->pixelSize();
bool needsTexture = o.output->needsSoftwareTransformation();
if (needsTexture) {
return !o.shadowBuffer || o.shadowBuffer->textureSize() != o.output->pixelSize();
} else {