backends/drm: split out layers for lease outputs and remove DrmDisplayDevice
This commit is contained in:
parent
aac7f50d8b
commit
0cd453690b
26 changed files with 235 additions and 208 deletions
|
@ -13,7 +13,6 @@ set(DRM_SOURCES
|
|||
drm_gpu.cpp
|
||||
dumb_swapchain.cpp
|
||||
shadowbuffer.cpp
|
||||
drm_display_device.cpp
|
||||
drm_layer.cpp
|
||||
drm_pipeline.cpp
|
||||
drm_pipeline_legacy.cpp
|
||||
|
@ -28,6 +27,7 @@ set(DRM_SOURCES
|
|||
gbm_dmabuf.cpp
|
||||
placeholderinputeventfilter.cpp
|
||||
virtual_egl_gbm_layer.cpp
|
||||
drm_lease_egl_gbm_layer.cpp
|
||||
)
|
||||
|
||||
add_library(KWinWaylandDrmBackend MODULE ${DRM_SOURCES})
|
||||
|
|
|
@ -16,8 +16,8 @@ namespace KWin
|
|||
|
||||
DrmAbstractOutput::DrmAbstractOutput(DrmGpu *gpu)
|
||||
: AbstractWaylandOutput(gpu->platform())
|
||||
, DrmDisplayDevice(gpu)
|
||||
, m_renderLoop(new RenderLoop(this))
|
||||
, m_gpu(gpu)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,6 @@ RenderLoop *DrmAbstractOutput::renderLoop() const
|
|||
return m_renderLoop;
|
||||
}
|
||||
|
||||
QRect DrmAbstractOutput::renderGeometry() const
|
||||
{
|
||||
return geometry();
|
||||
}
|
||||
|
||||
void DrmAbstractOutput::frameFailed() const
|
||||
{
|
||||
RenderLoopPrivate::get(m_renderLoop)->notifyFrameFailed();
|
||||
|
@ -57,4 +52,9 @@ QVector<int32_t> DrmAbstractOutput::regionToRects(const QRegion ®ion) const
|
|||
return rects;
|
||||
}
|
||||
|
||||
DrmGpu *DrmAbstractOutput::gpu() const
|
||||
{
|
||||
return m_gpu;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,29 +9,34 @@
|
|||
#pragma once
|
||||
|
||||
#include "abstract_wayland_output.h"
|
||||
#include "drm_display_device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DrmBackend;
|
||||
class DrmGpu;
|
||||
class DrmOutputLayer;
|
||||
|
||||
class DrmAbstractOutput : public AbstractWaylandOutput, public DrmDisplayDevice
|
||||
class DrmAbstractOutput : public AbstractWaylandOutput
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DrmAbstractOutput(DrmGpu *gpu);
|
||||
|
||||
RenderLoop *renderLoop() const override;
|
||||
QRect renderGeometry() const override;
|
||||
void frameFailed() const override;
|
||||
void pageFlipped(std::chrono::nanoseconds timestamp) const override;
|
||||
QVector<int32_t> regionToRects(const QRegion ®ion) const override;
|
||||
void frameFailed() const;
|
||||
void pageFlipped(std::chrono::nanoseconds timestamp) const;
|
||||
QVector<int32_t> regionToRects(const QRegion ®ion) const;
|
||||
DrmGpu *gpu() const;
|
||||
|
||||
virtual bool present() = 0;
|
||||
virtual DrmOutputLayer *outputLayer() const = 0;
|
||||
|
||||
protected:
|
||||
friend class DrmGpu;
|
||||
|
||||
RenderLoop *m_renderLoop;
|
||||
DrmGpu *const m_gpu;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
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 DrmOutputLayer;
|
||||
|
||||
class DrmDisplayDevice
|
||||
{
|
||||
public:
|
||||
DrmDisplayDevice(DrmGpu *gpu);
|
||||
virtual ~DrmDisplayDevice() = default;
|
||||
|
||||
DrmGpu *gpu() const;
|
||||
|
||||
virtual bool present() = 0;
|
||||
virtual void frameFailed() const = 0;
|
||||
virtual void pageFlipped(std::chrono::nanoseconds timestamp) const = 0;
|
||||
virtual QRect renderGeometry() const = 0;
|
||||
virtual DrmOutputLayer *outputLayer() const = 0;
|
||||
virtual QVector<int32_t> regionToRects(const QRegion ®ion) const = 0;
|
||||
|
||||
protected:
|
||||
DrmGpu *const m_gpu;
|
||||
};
|
||||
|
||||
}
|
|
@ -309,9 +309,9 @@ bool DrmGpu::updateOutputs()
|
|||
if (testPendingConfiguration()) {
|
||||
for (const auto &pipeline : qAsConst(m_pipelines)) {
|
||||
pipeline->applyPendingChanges();
|
||||
if (const auto drmOutput = dynamic_cast<DrmAbstractOutput*>(pipeline->displayDevice()); drmOutput && !pipeline->pending.crtc) {
|
||||
if (pipeline->output() && !pipeline->pending.crtc) {
|
||||
pipeline->pending.enabled = false;
|
||||
drmOutput->setEnabled(false);
|
||||
pipeline->output()->setEnabled(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -740,7 +740,7 @@ bool DrmGpu::maybeModeset()
|
|||
if (pipeline->modesetPresentPending()) {
|
||||
pipeline->resetModesetPresentPending();
|
||||
if (!ok) {
|
||||
pipeline->displayDevice()->frameFailed();
|
||||
pipeline->output()->frameFailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
#include "drm_layer.h"
|
||||
#include "drm_pipeline.h"
|
||||
#include "drm_display_device.h"
|
||||
|
||||
#include <QMatrix4x4>
|
||||
|
||||
|
@ -22,11 +21,43 @@ void DrmOutputLayer::aboutToStartPainting(const QRegion &damagedRegion)
|
|||
Q_UNUSED(damagedRegion)
|
||||
}
|
||||
|
||||
bool DrmOutputLayer::scanout(SurfaceItem *surfaceItem)
|
||||
{
|
||||
Q_UNUSED(surfaceItem)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<QRegion> DrmOutputLayer::startRendering()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
bool DrmOutputLayer::endRendering(const QRegion &damagedRegion)
|
||||
{
|
||||
Q_UNUSED(damagedRegion)
|
||||
return false;
|
||||
}
|
||||
|
||||
QRegion DrmOutputLayer::currentDamage() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
QSharedPointer<GLTexture> DrmOutputLayer::texture() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DrmPipelineLayer::DrmPipelineLayer(DrmPipeline *pipeline)
|
||||
: m_pipeline(pipeline)
|
||||
{
|
||||
}
|
||||
|
||||
bool DrmPipelineLayer::hasDirectScanoutBuffer() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "drm_layer.moc"
|
||||
|
|
|
@ -28,19 +28,19 @@ public:
|
|||
virtual ~DrmOutputLayer();
|
||||
|
||||
virtual void aboutToStartPainting(const QRegion &damagedRegion);
|
||||
virtual std::optional<QRegion> startRendering() = 0;
|
||||
virtual bool endRendering(const QRegion &damagedRegion) = 0;
|
||||
virtual std::optional<QRegion> startRendering();
|
||||
virtual bool endRendering(const QRegion &damagedRegion);
|
||||
|
||||
/**
|
||||
* attempts to directly scan out the current buffer of the surfaceItem
|
||||
* @returns true if scanout was successful
|
||||
* false if rendering is required
|
||||
*/
|
||||
virtual bool scanout(SurfaceItem *surfaceItem) = 0;
|
||||
virtual bool scanout(SurfaceItem *surfaceItem);
|
||||
|
||||
virtual QSharedPointer<GLTexture> texture() const = 0;
|
||||
virtual QSharedPointer<GLTexture> texture() const;
|
||||
|
||||
virtual QRegion currentDamage() const = 0;
|
||||
virtual QRegion currentDamage() const;
|
||||
};
|
||||
|
||||
class DrmPipelineLayer : public DrmOutputLayer
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
virtual QSharedPointer<DrmBuffer> testBuffer() = 0;
|
||||
|
||||
virtual QSharedPointer<DrmBuffer> currentBuffer() const = 0;
|
||||
virtual bool hasDirectScanoutBuffer() const = 0;
|
||||
virtual bool hasDirectScanoutBuffer() const;
|
||||
|
||||
protected:
|
||||
DrmPipeline *const m_pipeline;
|
||||
|
|
60
src/backends/drm/drm_lease_egl_gbm_layer.cpp
Normal file
60
src/backends/drm/drm_lease_egl_gbm_layer.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
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_lease_egl_gbm_layer.h"
|
||||
#include "drm_buffer_gbm.h"
|
||||
#include "egl_gbm_backend.h"
|
||||
#include "drm_pipeline.h"
|
||||
#include "drm_gpu.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
#include <gbm.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
DrmLeaseEglGbmLayer::DrmLeaseEglGbmLayer(EglGbmBackend *backend, DrmPipeline *pipeline)
|
||||
: DrmPipelineLayer(pipeline)
|
||||
{
|
||||
connect(backend, &EglGbmBackend::aboutToBeDestroyed, this, [this]() {
|
||||
m_buffer.reset();
|
||||
});
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmLeaseEglGbmLayer::testBuffer()
|
||||
{
|
||||
const auto mods = m_pipeline->supportedModifiers(DRM_FORMAT_XRGB8888);
|
||||
const auto size = m_pipeline->sourceSize();
|
||||
if (!m_buffer || m_buffer->size() != size || !(mods.isEmpty() || mods.contains(m_buffer->modifier()))) {
|
||||
gbm_bo *newBo;
|
||||
if (mods.isEmpty()) {
|
||||
newBo = gbm_bo_create(m_pipeline->gpu()->gbmDevice(), size.width(), size.height(), DRM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT);
|
||||
} else {
|
||||
QVector<uint64_t> modifiers;
|
||||
modifiers.reserve(mods.count());
|
||||
for (const auto &mod : mods) {
|
||||
modifiers << mod;
|
||||
}
|
||||
newBo = gbm_bo_create_with_modifiers(m_pipeline->gpu()->gbmDevice(), size.width(), size.height(), DRM_FORMAT_XRGB8888, modifiers.constData(), mods.count());
|
||||
}
|
||||
if (newBo) {
|
||||
m_buffer = QSharedPointer<DrmGbmBuffer>::create(m_pipeline->gpu(), nullptr, newBo);
|
||||
} else {
|
||||
qCWarning(KWIN_DRM) << "Failed to create gbm_bo for lease output";
|
||||
}
|
||||
}
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmLeaseEglGbmLayer::currentBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
}
|
31
src/backends/drm/drm_lease_egl_gbm_layer.h
Normal file
31
src/backends/drm/drm_lease_egl_gbm_layer.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
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 "drm_layer.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class EglGbmBackend;
|
||||
|
||||
class DrmLeaseEglGbmLayer : public DrmPipelineLayer
|
||||
{
|
||||
public:
|
||||
DrmLeaseEglGbmLayer(EglGbmBackend *backend, DrmPipeline *pipeline);
|
||||
|
||||
QSharedPointer<DrmBuffer> testBuffer() override;
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const override;
|
||||
|
||||
private:
|
||||
QSharedPointer<DrmBuffer> m_buffer;
|
||||
};
|
||||
|
||||
}
|
|
@ -30,16 +30,13 @@ 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)
|
||||
{
|
||||
m_pipeline->setDisplayDevice(this);
|
||||
qCDebug(KWIN_DRM) << "offering connector" << m_pipeline->connector()->id() << "for lease";
|
||||
}
|
||||
|
||||
DrmLeaseOutput::~DrmLeaseOutput()
|
||||
{
|
||||
m_pipeline->setDisplayDevice(nullptr);
|
||||
qCDebug(KWIN_DRM) << "revoking lease offer for connector" << m_pipeline->connector()->id();
|
||||
}
|
||||
|
||||
|
@ -79,34 +76,4 @@ DrmPipeline *DrmLeaseOutput::pipeline() const
|
|||
return m_pipeline;
|
||||
}
|
||||
|
||||
bool DrmLeaseOutput::present()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect DrmLeaseOutput::renderGeometry() const
|
||||
{
|
||||
return QRect(QPoint(), m_pipeline->sourceSize());
|
||||
}
|
||||
|
||||
DrmOutputLayer *DrmLeaseOutput::outputLayer() const
|
||||
{
|
||||
return m_pipeline->pending.layer.data();
|
||||
}
|
||||
|
||||
void DrmLeaseOutput::frameFailed() const
|
||||
{
|
||||
}
|
||||
|
||||
void DrmLeaseOutput::pageFlipped(std::chrono::nanoseconds timestamp) const
|
||||
{
|
||||
Q_UNUSED(timestamp)
|
||||
}
|
||||
|
||||
QVector<int32_t> DrmLeaseOutput::regionToRects(const QRegion ®ion) const
|
||||
{
|
||||
Q_UNUSED(region)
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#include <QVector>
|
||||
#include <KWaylandServer/drmleasedevice_v1_interface.h>
|
||||
|
||||
#include "drm_display_device.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
|
@ -26,7 +24,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, public DrmDisplayDevice
|
||||
class DrmLeaseOutput : public KWaylandServer::DrmLeaseConnectorV1Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -40,13 +38,6 @@ public:
|
|||
KWaylandServer::DrmLeaseV1Interface *lease() const;
|
||||
DrmPipeline *pipeline() const;
|
||||
|
||||
bool present() override;
|
||||
QRect renderGeometry() const override;
|
||||
DrmOutputLayer *outputLayer() const override;
|
||||
void frameFailed() const override;
|
||||
void pageFlipped(std::chrono::nanoseconds timestamp) const override;
|
||||
QVector<int32_t> regionToRects(const QRegion ®ion) const override;
|
||||
|
||||
private:
|
||||
DrmPipeline *m_pipeline;
|
||||
KWaylandServer::DrmLeaseV1Interface *m_lease = nullptr;
|
||||
|
|
|
@ -377,8 +377,8 @@ bool DrmConnector::updateProperties()
|
|||
if (!m_pipeline->pending.mode) {
|
||||
m_pipeline->pending.mode = m_modes.constFirst();
|
||||
}
|
||||
if (const auto output = dynamic_cast<DrmOutput*>(m_pipeline->displayDevice())) {
|
||||
output->updateModes();
|
||||
if (m_pipeline->output()) {
|
||||
m_pipeline->output()->updateModes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ DrmOutput::DrmOutput(DrmPipeline *pipeline)
|
|||
, m_pipeline(pipeline)
|
||||
, m_connector(pipeline->connector())
|
||||
{
|
||||
m_pipeline->setDisplayDevice(this);
|
||||
m_pipeline->setOutput(this);
|
||||
const auto conn = m_pipeline->connector();
|
||||
m_renderLoop->setRefreshRate(m_pipeline->pending.mode->refreshRate());
|
||||
setSubPixelInternal(conn->subpixel());
|
||||
|
@ -79,7 +79,7 @@ DrmOutput::DrmOutput(DrmPipeline *pipeline)
|
|||
|
||||
DrmOutput::~DrmOutput()
|
||||
{
|
||||
m_pipeline->setDisplayDevice(nullptr);
|
||||
m_pipeline->setOutput(nullptr);
|
||||
}
|
||||
|
||||
static bool isCursorSpriteCompatible(const QImage *buffer, const QImage *sprite)
|
||||
|
|
|
@ -32,8 +32,7 @@ namespace KWin
|
|||
{
|
||||
|
||||
DrmPipeline::DrmPipeline(DrmConnector *conn)
|
||||
: m_displayDevice(nullptr)
|
||||
, m_connector(conn)
|
||||
: m_connector(conn)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -309,8 +308,8 @@ bool DrmPipeline::setCursor(const QSharedPointer<DrmDumbBuffer> &buffer, const Q
|
|||
}
|
||||
if (result) {
|
||||
m_next = pending;
|
||||
if (const auto drmOutput = dynamic_cast<DrmOutput*>(m_displayDevice); drmOutput && (visibleBefore || isCursorVisible())) {
|
||||
drmOutput->renderLoop()->scheduleRepaint();
|
||||
if (m_output && (visibleBefore || isCursorVisible())) {
|
||||
m_output->renderLoop()->scheduleRepaint();
|
||||
}
|
||||
} else {
|
||||
pending = m_next;
|
||||
|
@ -334,8 +333,8 @@ bool DrmPipeline::moveCursor(QPoint pos)
|
|||
}
|
||||
if (result) {
|
||||
m_next = pending;
|
||||
if (const auto drmOutput = dynamic_cast<DrmOutput*>(m_displayDevice); drmOutput && (visibleBefore || isCursorVisible())) {
|
||||
drmOutput->renderLoop()->scheduleRepaint();
|
||||
if (m_output && (visibleBefore || isCursorVisible())) {
|
||||
m_output->renderLoop()->scheduleRepaint();
|
||||
}
|
||||
} else {
|
||||
pending = m_next;
|
||||
|
@ -395,12 +394,19 @@ void DrmPipeline::pageFlipped(std::chrono::nanoseconds timestamp)
|
|||
m_current.crtc->cursorPlane()->flipBuffer();
|
||||
}
|
||||
m_pageflipPending = false;
|
||||
m_displayDevice->pageFlipped(timestamp);
|
||||
if (m_output) {
|
||||
m_output->pageFlipped(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
void DrmPipeline::setDisplayDevice(DrmDisplayDevice *device)
|
||||
void DrmPipeline::setOutput(DrmOutput *output)
|
||||
{
|
||||
m_displayDevice = device;
|
||||
m_output = output;
|
||||
}
|
||||
|
||||
DrmOutput *DrmPipeline::output() const
|
||||
{
|
||||
return m_output;
|
||||
}
|
||||
|
||||
static const QMap<uint32_t, QVector<uint64_t>> legacyFormats = {
|
||||
|
@ -483,11 +489,6 @@ DrmCrtc *DrmPipeline::currentCrtc() const
|
|||
return m_current.crtc;
|
||||
}
|
||||
|
||||
DrmDisplayDevice *DrmPipeline::displayDevice() const
|
||||
{
|
||||
return m_displayDevice;
|
||||
}
|
||||
|
||||
DrmGammaRamp::DrmGammaRamp(DrmGpu *gpu, const GammaRamp &lut)
|
||||
: m_gpu(gpu)
|
||||
, m_lut(lut)
|
||||
|
|
|
@ -32,7 +32,6 @@ class DrmDumbBuffer;
|
|||
class GammaRamp;
|
||||
class DrmConnectorMode;
|
||||
class DrmPipelineLayer;
|
||||
class DrmDisplayDevice;
|
||||
|
||||
class DrmGammaRamp
|
||||
{
|
||||
|
@ -94,8 +93,8 @@ public:
|
|||
QVector<uint64_t> supportedModifiers(uint32_t drmFormat) const;
|
||||
QMap<uint32_t, QVector<uint64_t>> supportedFormats() const;
|
||||
|
||||
void setDisplayDevice(DrmDisplayDevice *device);
|
||||
DrmDisplayDevice *displayDevice() const;
|
||||
void setOutput(DrmOutput *output);
|
||||
DrmOutput *output() const;
|
||||
|
||||
struct State {
|
||||
DrmCrtc *crtc = nullptr;
|
||||
|
@ -154,7 +153,7 @@ private:
|
|||
static void printFlags(uint32_t flags);
|
||||
static void printProps(DrmObject *object, PrintMode mode);
|
||||
|
||||
DrmDisplayDevice *m_displayDevice = nullptr;
|
||||
DrmOutput *m_output = nullptr;
|
||||
DrmConnector *m_connector = nullptr;
|
||||
|
||||
bool m_pageflipPending = false;
|
||||
|
|
|
@ -15,16 +15,17 @@
|
|||
#include "drm_backend.h"
|
||||
#include "drm_pipeline.h"
|
||||
#include "drm_virtual_output.h"
|
||||
#include "drm_output.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
DrmQPainterLayer::DrmQPainterLayer(DrmPipeline *pipeline)
|
||||
DrmQPainterLayer::DrmQPainterLayer(DrmQPainterBackend *backend, DrmPipeline *pipeline)
|
||||
: DrmPipelineLayer(pipeline)
|
||||
{
|
||||
connect(static_cast<DrmQPainterBackend*>(pipeline->gpu()->platform()->renderBackend()), &DrmQPainterBackend::aboutToBeDestroyed, this, [this]() {
|
||||
connect(backend, &DrmQPainterBackend::aboutToBeDestroyed, this, [this]() {
|
||||
m_swapchain.reset();
|
||||
});
|
||||
}
|
||||
|
@ -35,7 +36,7 @@ std::optional<QRegion> DrmQPainterLayer::startRendering()
|
|||
m_swapchain = QSharedPointer<DumbSwapchain>::create(m_pipeline->gpu(), m_pipeline->sourceSize(), DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
QRegion needsRepaint;
|
||||
if (!m_swapchain->acquireBuffer(m_pipeline->displayDevice()->renderGeometry(), &needsRepaint)) {
|
||||
if (!m_swapchain->acquireBuffer(m_pipeline->output()->geometry(), &needsRepaint)) {
|
||||
return std::optional<QRegion>();
|
||||
}
|
||||
return needsRepaint;
|
||||
|
@ -48,12 +49,6 @@ bool DrmQPainterLayer::endRendering(const QRegion &damagedRegion)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DrmQPainterLayer::scanout(SurfaceItem *surfaceItem)
|
||||
{
|
||||
Q_UNUSED(surfaceItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmQPainterLayer::testBuffer()
|
||||
{
|
||||
if (!doesSwapchainFit()) {
|
||||
|
@ -77,16 +72,6 @@ QRegion DrmQPainterLayer::currentDamage() const
|
|||
return m_currentDamage;
|
||||
}
|
||||
|
||||
bool DrmQPainterLayer::hasDirectScanoutBuffer() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<GLTexture> DrmQPainterLayer::texture() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QImage *DrmQPainterLayer::image()
|
||||
{
|
||||
return m_swapchain ? m_swapchain->currentBuffer()->image() : nullptr;
|
||||
|
@ -112,17 +97,6 @@ bool DrmVirtualQPainterLayer::endRendering(const QRegion &damagedRegion)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DrmVirtualQPainterLayer::scanout(SurfaceItem *surfaceItem)
|
||||
{
|
||||
Q_UNUSED(surfaceItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<GLTexture> DrmVirtualQPainterLayer::texture() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QRegion DrmVirtualQPainterLayer::currentDamage() const
|
||||
{
|
||||
return m_currentDamage;
|
||||
|
@ -133,4 +107,27 @@ QImage *DrmVirtualQPainterLayer::image()
|
|||
return &m_image;
|
||||
}
|
||||
|
||||
|
||||
DrmLeaseQPainterLayer::DrmLeaseQPainterLayer(DrmQPainterBackend *backend, DrmPipeline *pipeline)
|
||||
: DrmPipelineLayer(pipeline)
|
||||
{
|
||||
connect(backend, &DrmQPainterBackend::aboutToBeDestroyed, this, [this]() {
|
||||
m_buffer.reset();
|
||||
});
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmLeaseQPainterLayer::testBuffer()
|
||||
{
|
||||
const auto size = m_pipeline->sourceSize();
|
||||
if (!m_buffer || m_buffer->size() != size) {
|
||||
m_buffer = QSharedPointer<DrmDumbBuffer>::create(m_pipeline->gpu(), size, DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmLeaseQPainterLayer::currentBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace KWin
|
|||
class DumbSwapchain;
|
||||
class DrmPipeline;
|
||||
class DrmVirtualOutput;
|
||||
class DrmQPainterBackend;
|
||||
class DrmDumbBuffer;
|
||||
|
||||
class QPainterLayer
|
||||
{
|
||||
|
@ -26,19 +28,16 @@ public:
|
|||
virtual QImage *image() = 0;
|
||||
};
|
||||
|
||||
class DrmQPainterLayer : public DrmPipelineLayer, QPainterLayer
|
||||
class DrmQPainterLayer : public DrmPipelineLayer, public QPainterLayer
|
||||
{
|
||||
public:
|
||||
DrmQPainterLayer(DrmPipeline *pipeline);
|
||||
DrmQPainterLayer(DrmQPainterBackend *backend, DrmPipeline *pipeline);
|
||||
|
||||
std::optional<QRegion> startRendering() override;
|
||||
bool endRendering(const QRegion &damagedRegion) override;
|
||||
bool scanout(SurfaceItem *surfaceItem) override;
|
||||
QSharedPointer<DrmBuffer> testBuffer() override;
|
||||
QSharedPointer<GLTexture> texture() const override;
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const override;
|
||||
QRegion currentDamage() const override;
|
||||
bool hasDirectScanoutBuffer() const override;
|
||||
QImage *image() override;
|
||||
|
||||
private:
|
||||
|
@ -48,16 +47,14 @@ private:
|
|||
QRegion m_currentDamage;
|
||||
};
|
||||
|
||||
class DrmVirtualQPainterLayer : public DrmOutputLayer, QPainterLayer
|
||||
class DrmVirtualQPainterLayer : public DrmOutputLayer, public QPainterLayer
|
||||
{
|
||||
public:
|
||||
DrmVirtualQPainterLayer(DrmVirtualOutput *output);
|
||||
|
||||
std::optional<QRegion> startRendering() override;
|
||||
bool endRendering(const QRegion &damagedRegion) override;
|
||||
bool scanout(SurfaceItem *surfaceItem) override;
|
||||
|
||||
QSharedPointer<GLTexture> texture() const override;
|
||||
QRegion currentDamage() const override;
|
||||
QImage *image() override;
|
||||
|
||||
|
@ -67,4 +64,16 @@ private:
|
|||
DrmVirtualOutput *const m_output;
|
||||
};
|
||||
|
||||
class DrmLeaseQPainterLayer : public DrmPipelineLayer
|
||||
{
|
||||
public:
|
||||
DrmLeaseQPainterLayer(DrmQPainterBackend *backend, DrmPipeline *pipeline);
|
||||
|
||||
QSharedPointer<DrmBuffer> testBuffer() override;
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const override;
|
||||
|
||||
private:
|
||||
QSharedPointer<DrmDumbBuffer> m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ namespace KWin
|
|||
{
|
||||
|
||||
class DrmPipelineLayer;
|
||||
class DrmDisplayDevice;
|
||||
class DrmVirtualOutput;
|
||||
class DrmPipeline;
|
||||
class DrmOutputLayer;
|
||||
|
|
|
@ -74,7 +74,7 @@ void DrmVirtualOutput::setDpmsMode(DpmsMode mode)
|
|||
|
||||
void DrmVirtualOutput::updateEnablement(bool enable)
|
||||
{
|
||||
gpu()->platform()->enableOutput(this, enable);
|
||||
m_gpu->platform()->enableOutput(this, enable);
|
||||
}
|
||||
|
||||
int DrmVirtualOutput::gammaRampSize() const
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "egl_dmabuf.h"
|
||||
#include "egl_gbm_layer.h"
|
||||
#include "virtual_egl_gbm_layer.h"
|
||||
#include "drm_lease_egl_gbm_layer.h"
|
||||
// kwin libs
|
||||
#include <kwinglplatform.h>
|
||||
#include <kwineglimagetexture.h>
|
||||
|
@ -289,7 +290,11 @@ EGLConfig EglGbmBackend::config(uint32_t format) const
|
|||
|
||||
QSharedPointer<DrmPipelineLayer> EglGbmBackend::createDrmPipelineLayer(DrmPipeline *pipeline)
|
||||
{
|
||||
return QSharedPointer<EglGbmLayer>::create(this, pipeline);
|
||||
if (pipeline->output()) {
|
||||
return QSharedPointer<EglGbmLayer>::create(this, pipeline);
|
||||
} else {
|
||||
return QSharedPointer<DrmLeaseEglGbmLayer>::create(this, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<DrmOutputLayer> EglGbmBackend::createLayer(DrmVirtualOutput *output)
|
||||
|
|
|
@ -38,7 +38,6 @@ class ShadowBuffer;
|
|||
class DrmBackend;
|
||||
class DrmGpu;
|
||||
class EglGbmLayer;
|
||||
class DrmDisplayDevice;
|
||||
class DrmOutputLayer;
|
||||
class DrmPipeline;
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ std::optional<QRegion> EglGbmLayer::startRendering()
|
|||
if (!m_gbmSurface->makeContextCurrent()) {
|
||||
return std::optional<QRegion>();
|
||||
}
|
||||
auto repaintRegion = m_gbmSurface->repaintRegion(m_pipeline->displayDevice()->renderGeometry());
|
||||
auto repaintRegion = m_gbmSurface->repaintRegion(m_pipeline->output()->geometry());
|
||||
|
||||
// shadow buffer
|
||||
if (doesShadowBufferFit(m_shadowBuffer.data())) {
|
||||
|
@ -124,7 +124,7 @@ std::optional<QRegion> EglGbmLayer::startRendering()
|
|||
void EglGbmLayer::aboutToStartPainting(const QRegion &damagedRegion)
|
||||
{
|
||||
if (m_gbmSurface->bufferAge() > 0 && !damagedRegion.isEmpty() && m_eglBackend->supportsPartialUpdate()) {
|
||||
QVector<EGLint> rects = m_pipeline->displayDevice()->regionToRects(damagedRegion);
|
||||
QVector<EGLint> rects = m_pipeline->output()->regionToRects(damagedRegion);
|
||||
const bool correct = eglSetDamageRegionKHR(m_eglBackend->eglDisplay(), m_gbmSurface->eglSurface(), rects.data(), rects.count() / 4);
|
||||
if (!correct) {
|
||||
qCWarning(KWIN_DRM) << "eglSetDamageRegionKHR failed:" << getEglErrorString();
|
||||
|
@ -178,7 +178,7 @@ bool EglGbmLayer::renderTestBuffer()
|
|||
return false;
|
||||
}
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (!endRendering(m_pipeline->displayDevice()->renderGeometry())) {
|
||||
if (!endRendering(m_pipeline->output()->geometry())) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -438,11 +438,11 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem)
|
|||
surfaceItem->resetDamage();
|
||||
for (const auto &rect : trackedDamage) {
|
||||
auto damageRect = QRect(rect);
|
||||
damageRect.translate(m_pipeline->displayDevice()->renderGeometry().topLeft());
|
||||
damageRect.translate(m_pipeline->output()->geometry().topLeft());
|
||||
damage |= damageRect;
|
||||
}
|
||||
} else {
|
||||
damage = m_pipeline->displayDevice()->renderGeometry();
|
||||
damage = m_pipeline->output()->geometry();
|
||||
}
|
||||
if (m_pipeline->testScanout()) {
|
||||
m_currentBuffer = m_scanoutBuffer;
|
||||
|
|
|
@ -28,12 +28,7 @@ namespace KWin
|
|||
class GbmSurface;
|
||||
class DumbSwapchain;
|
||||
class ShadowBuffer;
|
||||
class DrmBuffer;
|
||||
class DrmGpu;
|
||||
class SurfaceItem;
|
||||
class GLTexture;
|
||||
class EglGbmBackend;
|
||||
class DrmPipeline;
|
||||
|
||||
class EglGbmLayer : public DrmPipelineLayer
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "renderloop_p.h"
|
||||
#include "drm_qpainter_layer.h"
|
||||
#include "drm_virtual_output.h"
|
||||
#include "drm_pipeline.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
|
@ -54,7 +55,11 @@ void DrmQPainterBackend::endFrame(AbstractOutput *output, const QRegion &rendere
|
|||
|
||||
QSharedPointer<DrmPipelineLayer> DrmQPainterBackend::createDrmPipelineLayer(DrmPipeline *pipeline)
|
||||
{
|
||||
return QSharedPointer<DrmQPainterLayer>::create(pipeline);
|
||||
if (pipeline->output()) {
|
||||
return QSharedPointer<DrmQPainterLayer>::create(this, pipeline);
|
||||
} else {
|
||||
return QSharedPointer<DrmLeaseQPainterLayer>::create(this, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<DrmOutputLayer> DrmQPainterBackend::createLayer(DrmVirtualOutput *output)
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class DrmDisplayDevice;
|
||||
|
||||
class ShadowBuffer
|
||||
{
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue