backends/drm: introduce DrmDisplayDevice
DrmDisplayDevice is a new parent class for both normal and lease outputs, which makes it possible to simplify a few things
This commit is contained in:
parent
ddb6dadfc2
commit
dd198461ea
12 changed files with 142 additions and 40 deletions
|
@ -13,6 +13,7 @@ set(DRM_SOURCES
|
|||
drm_gpu.cpp
|
||||
dumb_swapchain.cpp
|
||||
shadowbuffer.cpp
|
||||
drm_display_device.cpp
|
||||
drm_pipeline.cpp
|
||||
drm_pipeline_legacy.cpp
|
||||
drm_abstract_output.cpp
|
||||
|
|
|
@ -15,16 +15,11 @@ namespace KWin
|
|||
|
||||
DrmAbstractOutput::DrmAbstractOutput(DrmGpu *gpu)
|
||||
: AbstractWaylandOutput(gpu->platform())
|
||||
, DrmDisplayDevice(gpu)
|
||||
, m_renderLoop(new RenderLoop(this))
|
||||
, m_gpu(gpu)
|
||||
{
|
||||
}
|
||||
|
||||
DrmGpu *DrmAbstractOutput::gpu() const
|
||||
{
|
||||
return m_gpu;
|
||||
}
|
||||
|
||||
RenderLoop *DrmAbstractOutput::renderLoop() const
|
||||
{
|
||||
return m_renderLoop;
|
||||
|
|
|
@ -9,41 +9,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "abstract_wayland_output.h"
|
||||
#include "drm_display_device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DrmBackend;
|
||||
class DrmGpu;
|
||||
class DrmBuffer;
|
||||
class GbmBuffer;
|
||||
|
||||
class DrmAbstractOutput : public AbstractWaylandOutput
|
||||
class DrmAbstractOutput : public AbstractWaylandOutput, public DrmDisplayDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual bool present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion) = 0;
|
||||
DrmAbstractOutput(DrmGpu *gpu);
|
||||
|
||||
virtual bool needsSoftwareTransformation() const = 0;
|
||||
virtual QSize bufferSize() const = 0;
|
||||
virtual QSize sourceSize() const = 0;
|
||||
virtual bool isFormatSupported(uint32_t drmFormat) const = 0;
|
||||
virtual QVector<uint64_t> supportedModifiers(uint32_t drmFormat) const = 0;
|
||||
/**
|
||||
* returns the maximum bits per color channel that make sense to be used for this output
|
||||
*/
|
||||
virtual int maxBpc() const = 0;
|
||||
|
||||
DrmGpu *gpu() const;
|
||||
RenderLoop *renderLoop() const override;
|
||||
|
||||
protected:
|
||||
friend class DrmBackend;
|
||||
friend class DrmGpu;
|
||||
DrmAbstractOutput(DrmGpu *gpu);
|
||||
|
||||
RenderLoop *m_renderLoop;
|
||||
DrmGpu *m_gpu;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
24
src/backends/drm/drm_display_device.cpp
Normal file
24
src/backends/drm/drm_display_device.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include "drm_display_device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
DrmDisplayDevice::DrmDisplayDevice(DrmGpu *gpu)
|
||||
: m_gpu(gpu)
|
||||
{
|
||||
}
|
||||
|
||||
DrmGpu *DrmDisplayDevice::gpu() const
|
||||
{
|
||||
return m_gpu;
|
||||
}
|
||||
|
||||
}
|
41
src/backends/drm/drm_display_device.h
Normal file
41
src/backends/drm/drm_display_device.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QRegion>
|
||||
|
||||
#include "drm_object_plane.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DrmBuffer;
|
||||
class DrmGpu;
|
||||
|
||||
class DrmDisplayDevice
|
||||
{
|
||||
public:
|
||||
DrmDisplayDevice(DrmGpu *gpu);
|
||||
virtual ~DrmDisplayDevice() = default;
|
||||
|
||||
DrmGpu *gpu() const;
|
||||
|
||||
virtual bool present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion) = 0;
|
||||
virtual DrmPlane::Transformations softwareTransforms() const = 0;
|
||||
virtual QSize bufferSize() const = 0;
|
||||
virtual QSize sourceSize() const = 0;
|
||||
virtual bool isFormatSupported(uint32_t drmFormat) const = 0;
|
||||
virtual QVector<uint64_t> supportedModifiers(uint32_t drmFormat) const = 0;
|
||||
virtual int maxBpc() const = 0;
|
||||
|
||||
protected:
|
||||
DrmGpu *const m_gpu;
|
||||
};
|
||||
|
||||
}
|
|
@ -29,6 +29,7 @@ DrmLeaseOutput::DrmLeaseOutput(DrmPipeline *pipeline, KWaylandServer::DrmLeaseDe
|
|||
pipeline->connector()->modelName(),
|
||||
QStringLiteral("%1 %2").arg(pipeline->connector()->edid()->manufacturerString(), pipeline->connector()->modelName())
|
||||
)
|
||||
, DrmDisplayDevice(pipeline->gpu())
|
||||
, m_pipeline(pipeline)
|
||||
{
|
||||
qCDebug(KWIN_DRM) << "offering connector" << m_pipeline->connector()->id() << "for lease";
|
||||
|
@ -75,4 +76,45 @@ DrmPipeline *DrmLeaseOutput::pipeline() const
|
|||
return m_pipeline;
|
||||
}
|
||||
|
||||
bool DrmLeaseOutput::present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion)
|
||||
{
|
||||
Q_UNUSED(buffer)
|
||||
Q_UNUSED(damagedRegion)
|
||||
return false;
|
||||
}
|
||||
|
||||
DrmPlane::Transformations DrmLeaseOutput::softwareTransforms() const
|
||||
{
|
||||
return DrmPlane::Transformation::Rotate0;
|
||||
}
|
||||
|
||||
QSize DrmLeaseOutput::bufferSize() const
|
||||
{
|
||||
return m_pipeline->bufferSize();
|
||||
}
|
||||
|
||||
QSize DrmLeaseOutput::sourceSize() const
|
||||
{
|
||||
return m_pipeline->sourceSize();
|
||||
}
|
||||
|
||||
bool DrmLeaseOutput::isFormatSupported(uint32_t drmFormat) const
|
||||
{
|
||||
return m_pipeline->isFormatSupported(drmFormat);
|
||||
}
|
||||
|
||||
QVector<uint64_t> DrmLeaseOutput::supportedModifiers(uint32_t drmFormat) const
|
||||
{
|
||||
return m_pipeline->supportedModifiers(drmFormat);
|
||||
}
|
||||
|
||||
int DrmLeaseOutput::maxBpc() const
|
||||
{
|
||||
if (const auto prop = m_pipeline->connector()->getProp(DrmConnector::PropertyIndex::MaxBpc)) {
|
||||
return prop->maxValue();
|
||||
} else {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <QVector>
|
||||
#include <KWaylandServer/drmleasedevice_v1_interface.h>
|
||||
|
||||
#include "drm_display_device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -24,7 +26,7 @@ class DrmPipeline;
|
|||
* that is not used directly by the compositor but is instead leased out to
|
||||
* applications (usually VR compositors) that drive the output themselves
|
||||
*/
|
||||
class DrmLeaseOutput : public KWaylandServer::DrmLeaseConnectorV1Interface
|
||||
class DrmLeaseOutput : public KWaylandServer::DrmLeaseConnectorV1Interface, public DrmDisplayDevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -38,6 +40,14 @@ public:
|
|||
KWaylandServer::DrmLeaseV1Interface *lease() const;
|
||||
DrmPipeline *pipeline() const;
|
||||
|
||||
bool present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion) override;
|
||||
DrmPlane::Transformations softwareTransforms() const override;
|
||||
QSize bufferSize() const override;
|
||||
QSize sourceSize() const override;
|
||||
bool isFormatSupported(uint32_t drmFormat) const override;
|
||||
QVector<uint64_t> supportedModifiers(uint32_t drmFormat) const override;
|
||||
int maxBpc() const override;
|
||||
|
||||
private:
|
||||
DrmPipeline *m_pipeline;
|
||||
KWaylandServer::DrmLeaseV1Interface *m_lease = nullptr;
|
||||
|
|
|
@ -318,11 +318,6 @@ void DrmOutput::updateModes()
|
|||
}
|
||||
}
|
||||
|
||||
bool DrmOutput::needsSoftwareTransformation() const
|
||||
{
|
||||
return m_pipeline->pending.bufferTransformation != m_pipeline->pending.sourceTransformation;
|
||||
}
|
||||
|
||||
bool DrmOutput::present(const QSharedPointer<DrmBuffer> &buffer, QRegion damagedRegion)
|
||||
{
|
||||
if (!buffer || buffer->bufferId() == 0) {
|
||||
|
@ -472,4 +467,14 @@ bool DrmOutput::usesSoftwareCursor() const
|
|||
return !m_setCursorSuccessful || !m_moveCursorSuccessful;
|
||||
}
|
||||
|
||||
DrmPlane::Transformations DrmOutput::softwareTransforms() const
|
||||
{
|
||||
if (m_pipeline->pending.bufferTransformation == m_pipeline->pending.sourceTransformation) {
|
||||
return DrmPlane::Transformation::Rotate0;
|
||||
} else {
|
||||
// TODO handle sourceTransformation != Rotate0
|
||||
return m_pipeline->pending.sourceTransformation;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,7 +52,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;
|
||||
DrmPlane::Transformations softwareTransforms() const override;
|
||||
int maxBpc() const override;
|
||||
|
||||
bool queueChanges(const WaylandOutputConfig &config);
|
||||
|
|
|
@ -109,14 +109,14 @@ bool DrmVirtualOutput::setGammaRamp(const GammaRamp &gamma)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DrmVirtualOutput::needsSoftwareTransformation() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int DrmVirtualOutput::maxBpc() const
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
DrmPlane::Transformations DrmVirtualOutput::softwareTransforms() const
|
||||
{
|
||||
return DrmPlane::Transformation::Rotate0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
|
||||
int gammaRampSize() const override;
|
||||
bool setGammaRamp(const GammaRamp &gamma) override;
|
||||
bool needsSoftwareTransformation() const override;
|
||||
DrmPlane::Transformations softwareTransforms() const override;
|
||||
|
||||
private:
|
||||
void vblank(std::chrono::nanoseconds timestamp);
|
||||
|
|
|
@ -85,7 +85,7 @@ std::optional<QRegion> EglGbmLayer::startRendering()
|
|||
if (doesShadowBufferFit(m_oldShadowBuffer.data())) {
|
||||
m_shadowBuffer = m_oldShadowBuffer;
|
||||
} else {
|
||||
if (m_output->needsSoftwareTransformation()) {
|
||||
if (m_output->softwareTransforms() != DrmPlane::Transformations(DrmPlane::Transformation::Rotate0)) {
|
||||
const auto format = m_renderGpu->eglBackend()->gbmFormatForDrmFormat(m_gbmSurface->format());
|
||||
m_shadowBuffer = QSharedPointer<ShadowBuffer>::create(m_output->sourceSize(), format);
|
||||
if (!m_shadowBuffer->isComplete()) {
|
||||
|
@ -200,7 +200,7 @@ bool EglGbmLayer::doesGbmSurfaceFit(GbmSurface *surf) const
|
|||
|
||||
bool EglGbmLayer::doesShadowBufferFit(ShadowBuffer *buffer) const
|
||||
{
|
||||
if (m_output->needsSoftwareTransformation()) {
|
||||
if (m_output->softwareTransforms() != DrmPlane::Transformations(DrmPlane::Transformation::Rotate0)) {
|
||||
return buffer && buffer->texture()->size() == m_output->sourceSize() && buffer->drmFormat() == m_gbmSurface->format();
|
||||
} else {
|
||||
return buffer == nullptr;
|
||||
|
|
Loading…
Reference in a new issue