backends/drm: port qpainter to layers
This commit is contained in:
parent
153d5965f8
commit
ddb6dadfc2
7 changed files with 173 additions and 37 deletions
|
@ -18,6 +18,7 @@ set(DRM_SOURCES
|
|||
drm_abstract_output.cpp
|
||||
drm_virtual_output.cpp
|
||||
drm_lease_output.cpp
|
||||
drm_qpainter_layer.cpp
|
||||
egl_gbm_backend.cpp
|
||||
egl_gbm_layer.cpp
|
||||
drm_buffer_gbm.cpp
|
||||
|
|
47
src/backends/drm/drm_layer.h
Normal file
47
src/backends/drm/drm_layer.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
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 <optional>
|
||||
#include <QRegion>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class SurfaceItem;
|
||||
class DrmBuffer;
|
||||
class DrmAbstractOutput;
|
||||
|
||||
class DrmLayer
|
||||
{
|
||||
public:
|
||||
virtual ~DrmLayer() = default;
|
||||
|
||||
virtual std::optional<QRegion> startRendering() = 0;
|
||||
virtual bool endRendering(const QRegion &damagedRegion) = 0;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @returns a buffer for atomic test commits
|
||||
* If no fitting buffer is available, a new current buffer is created
|
||||
*/
|
||||
virtual QSharedPointer<DrmBuffer> testBuffer() = 0;
|
||||
|
||||
virtual QSharedPointer<DrmBuffer> currentBuffer() const = 0;
|
||||
virtual DrmAbstractOutput *output() const = 0;
|
||||
};
|
||||
|
||||
}
|
71
src/backends/drm/drm_qpainter_layer.cpp
Normal file
71
src/backends/drm/drm_qpainter_layer.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
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_qpainter_layer.h"
|
||||
#include "dumb_swapchain.h"
|
||||
#include "drm_abstract_output.h"
|
||||
#include "drm_buffer.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
DrmQPainterLayer::DrmQPainterLayer(DrmAbstractOutput *output)
|
||||
: m_output(output)
|
||||
{
|
||||
}
|
||||
|
||||
std::optional<QRegion> DrmQPainterLayer::startRendering()
|
||||
{
|
||||
if (!doesSwapchainFit()) {
|
||||
m_swapchain = QSharedPointer<DumbSwapchain>::create(m_output->gpu(), m_output->sourceSize(), DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
QRegion needsRepaint;
|
||||
if (!m_swapchain->acquireBuffer(m_output->geometry(), &needsRepaint)) {
|
||||
return std::optional<QRegion>();
|
||||
}
|
||||
return needsRepaint;
|
||||
}
|
||||
|
||||
bool DrmQPainterLayer::endRendering(const QRegion &damagedRegion)
|
||||
{
|
||||
m_swapchain->releaseBuffer(m_swapchain->currentBuffer(), damagedRegion);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DrmQPainterLayer::scanout(SurfaceItem *surfaceItem)
|
||||
{
|
||||
Q_UNUSED(surfaceItem);
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmQPainterLayer::testBuffer()
|
||||
{
|
||||
if (!doesSwapchainFit()) {
|
||||
m_swapchain = QSharedPointer<DumbSwapchain>::create(m_output->gpu(), m_output->sourceSize(), DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
return m_swapchain->currentBuffer();
|
||||
}
|
||||
|
||||
bool DrmQPainterLayer::doesSwapchainFit() const
|
||||
{
|
||||
return m_swapchain && m_swapchain->size() == m_output->sourceSize();
|
||||
}
|
||||
|
||||
QSharedPointer<DrmBuffer> DrmQPainterLayer::currentBuffer() const
|
||||
{
|
||||
return m_swapchain ? m_swapchain->currentBuffer() : nullptr;
|
||||
}
|
||||
|
||||
DrmAbstractOutput *DrmQPainterLayer::output() const
|
||||
{
|
||||
return m_output;
|
||||
}
|
||||
|
||||
}
|
35
src/backends/drm/drm_qpainter_layer.h
Normal file
35
src/backends/drm/drm_qpainter_layer.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
class DumbSwapchain;
|
||||
|
||||
class DrmQPainterLayer : public DrmLayer {
|
||||
public:
|
||||
DrmQPainterLayer(DrmAbstractOutput *output);
|
||||
|
||||
std::optional<QRegion> startRendering() override;
|
||||
bool endRendering(const QRegion &damagedRegion) override;
|
||||
bool scanout(SurfaceItem *surfaceItem) override;
|
||||
QSharedPointer<DrmBuffer> testBuffer() override;
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const override;
|
||||
DrmAbstractOutput *output() const override;
|
||||
|
||||
private:
|
||||
bool doesSwapchainFit() const;
|
||||
|
||||
QSharedPointer<DumbSwapchain> m_swapchain;
|
||||
DrmAbstractOutput *const m_output;
|
||||
};
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#pragma once
|
||||
#include "drm_layer.h"
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QPointer>
|
||||
|
@ -33,35 +34,20 @@ class DrmGpu;
|
|||
class SurfaceItem;
|
||||
class GLTexture;
|
||||
|
||||
class EglGbmLayer {
|
||||
class EglGbmLayer : public DrmLayer
|
||||
{
|
||||
public:
|
||||
EglGbmLayer(DrmGpu *renderGpu, DrmAbstractOutput *output);
|
||||
~EglGbmLayer();
|
||||
|
||||
std::optional<QRegion> startRendering();
|
||||
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
|
||||
*/
|
||||
bool scanout(SurfaceItem *surfaceItem);
|
||||
|
||||
/**
|
||||
* @returns a buffer for atomic test commits
|
||||
* If no fitting buffer is available, one is created
|
||||
*/
|
||||
QSharedPointer<DrmBuffer> testBuffer();
|
||||
|
||||
/**
|
||||
* only temporarily here, should be migrated out!
|
||||
*/
|
||||
std::optional<QRegion> startRendering() override;
|
||||
bool endRendering(const QRegion &damagedRegion) override;
|
||||
bool scanout(SurfaceItem *surfaceItem) override;
|
||||
QSharedPointer<DrmBuffer> testBuffer() override;
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const override;
|
||||
QSharedPointer<GLTexture> texture() const;
|
||||
|
||||
QSharedPointer<DrmBuffer> currentBuffer() const;
|
||||
|
||||
DrmAbstractOutput *output() const;
|
||||
DrmAbstractOutput *output() const override;
|
||||
int bufferAge() const;
|
||||
EGLSurface eglSurface() const;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "drm_gpu.h"
|
||||
#include "drm_buffer.h"
|
||||
#include "renderloop_p.h"
|
||||
#include "drm_qpainter_layer.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
|
@ -22,6 +23,9 @@ DrmQPainterBackend::DrmQPainterBackend(DrmBackend *backend)
|
|||
: QPainterBackend()
|
||||
, m_backend(backend)
|
||||
{
|
||||
connect(m_backend, &DrmBackend::outputEnabled, this, [this] (const auto output) {
|
||||
m_swapchains[output] = QSharedPointer<DrmQPainterLayer>::create(static_cast<DrmAbstractOutput*>(output));
|
||||
});
|
||||
connect(m_backend, &DrmBackend::outputDisabled, this, [this] (const auto output) {
|
||||
m_swapchains.remove(output);
|
||||
});
|
||||
|
@ -29,26 +33,19 @@ DrmQPainterBackend::DrmQPainterBackend(DrmBackend *backend)
|
|||
|
||||
QImage *DrmQPainterBackend::bufferForScreen(AbstractOutput *output)
|
||||
{
|
||||
return m_swapchains[output]->currentBuffer()->image();
|
||||
return static_cast<DrmDumbBuffer*>(m_swapchains[output]->currentBuffer().data())->image();
|
||||
}
|
||||
|
||||
QRegion DrmQPainterBackend::beginFrame(AbstractOutput *output)
|
||||
{
|
||||
const auto drmOutput = static_cast<DrmAbstractOutput*>(output);
|
||||
if (!m_swapchains[output] || m_swapchains[output]->size() != drmOutput->sourceSize()) {
|
||||
m_swapchains[output] = QSharedPointer<DumbSwapchain>::create(drmOutput->gpu(), drmOutput->sourceSize(), DRM_FORMAT_XRGB8888);
|
||||
}
|
||||
QRegion needsRepainting;
|
||||
m_swapchains[output]->acquireBuffer(output->geometry(), &needsRepainting);
|
||||
return needsRepainting;
|
||||
return m_swapchains[output]->startRendering().value_or(QRegion());
|
||||
}
|
||||
|
||||
void DrmQPainterBackend::endFrame(AbstractOutput *output, const QRegion &renderedRegion, const QRegion &damage)
|
||||
{
|
||||
Q_UNUSED(renderedRegion)
|
||||
QSharedPointer<DrmDumbBuffer> back = m_swapchains[output]->currentBuffer();
|
||||
m_swapchains[output]->releaseBuffer(back, damage);
|
||||
static_cast<DrmAbstractOutput*>(output)->present(back, output->geometry());
|
||||
m_swapchains[output]->endRendering(damage);
|
||||
static_cast<DrmAbstractOutput*>(output)->present(m_swapchains[output]->currentBuffer(), output->geometry());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,9 +20,8 @@ namespace KWin
|
|||
{
|
||||
|
||||
class DrmBackend;
|
||||
class DrmDumbBuffer;
|
||||
class DrmAbstractOutput;
|
||||
class DrmGpu;
|
||||
class DrmQPainterLayer;
|
||||
|
||||
class DrmQPainterBackend : public QPainterBackend
|
||||
{
|
||||
|
@ -35,7 +34,7 @@ public:
|
|||
void endFrame(AbstractOutput *output, const QRegion &renderedRegion, const QRegion &damagedRegion) override;
|
||||
|
||||
private:
|
||||
QMap<AbstractOutput *, QSharedPointer<DumbSwapchain>> m_swapchains;
|
||||
QMap<AbstractOutput *, QSharedPointer<DrmQPainterLayer>> m_swapchains;
|
||||
DrmBackend *m_backend;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue