backends/drm: rework how atomic commits are tracked

Pending buffers for drm planes and crtcs are no longer tracked in the planes
and crtcs themselves, but instead in a DrmCommit object that is used as
the user data for the pageflip handler. This way multiple commits can be
pending at the same time without causing conflicts, and the handling of
pending buffers is simplified as well.
This commit is contained in:
Xaver Hugl 2023-07-24 13:50:56 +02:00
parent fcf24d98bf
commit 7d02bc17d6
16 changed files with 217 additions and 170 deletions

View file

@ -1,10 +1,10 @@
set(mockDRM_SRCS
mock_drm.cpp
../../src/backends/drm/drm_abstract_output.cpp
../../src/backends/drm/drm_atomic_commit.cpp
../../src/backends/drm/drm_backend.cpp
../../src/backends/drm/drm_blob.cpp
../../src/backends/drm/drm_buffer.cpp
../../src/backends/drm/drm_commit.cpp
../../src/backends/drm/drm_commit_thread.cpp
../../src/backends/drm/drm_connector.cpp
../../src/backends/drm/drm_crtc.cpp

View file

@ -1,9 +1,9 @@
target_sources(kwin PRIVATE
drm_abstract_output.cpp
drm_atomic_commit.cpp
drm_backend.cpp
drm_blob.cpp
drm_buffer.cpp
drm_commit.cpp
drm_commit_thread.cpp
drm_connector.cpp
drm_crtc.cpp

View file

@ -1,60 +0,0 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_atomic_commit.h"
#include "drm_blob.h"
#include "drm_gpu.h"
#include "drm_object.h"
#include "drm_property.h"
namespace KWin
{
DrmAtomicCommit::DrmAtomicCommit(DrmGpu *gpu)
: m_gpu(gpu)
, m_req(drmModeAtomicAlloc())
{
}
void DrmAtomicCommit::addProperty(const DrmProperty &prop, uint64_t value)
{
drmModeAtomicAddProperty(m_req.get(), prop.drmObject()->id(), prop.propId(), value);
}
void DrmAtomicCommit::addBlob(const DrmProperty &prop, const std::shared_ptr<DrmBlob> &blob)
{
addProperty(prop, blob ? blob->blobId() : 0);
m_blobs[&prop] = blob;
}
bool DrmAtomicCommit::test()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK, m_gpu) == 0;
}
bool DrmAtomicCommit::testAllowModeset()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, m_gpu) == 0;
}
bool DrmAtomicCommit::commit()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, m_gpu) == 0;
}
bool DrmAtomicCommit::commitModeset()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_ALLOW_MODESET, m_gpu) == 0;
}
drmModeAtomicReq *DrmAtomicCommit::req() const
{
return m_req.get();
}
}

View file

@ -0,0 +1,126 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_commit.h"
#include "drm_blob.h"
#include "drm_buffer.h"
#include "drm_connector.h"
#include "drm_crtc.h"
#include "drm_gpu.h"
#include "drm_object.h"
#include "drm_property.h"
#include <QApplication>
#include <QThread>
namespace KWin
{
DrmCommit::DrmCommit(DrmGpu *gpu)
: m_gpu(gpu)
{
}
DrmCommit::~DrmCommit()
{
}
DrmGpu *DrmCommit::gpu() const
{
return m_gpu;
}
DrmAtomicCommit::DrmAtomicCommit(DrmGpu *gpu)
: DrmCommit(gpu)
, m_req(drmModeAtomicAlloc())
{
}
DrmAtomicCommit::~DrmAtomicCommit()
{
Q_ASSERT(QThread::currentThread() == QApplication::instance()->thread());
if (m_commitSuccessful) {
for (const auto &[plane, buffer] : m_buffers) {
plane->setCurrentBuffer(buffer);
}
}
}
void DrmAtomicCommit::addProperty(const DrmProperty &prop, uint64_t value)
{
drmModeAtomicAddProperty(m_req.get(), prop.drmObject()->id(), prop.propId(), value);
}
void DrmAtomicCommit::addBlob(const DrmProperty &prop, const std::shared_ptr<DrmBlob> &blob)
{
addProperty(prop, blob ? blob->blobId() : 0);
m_blobs[&prop] = blob;
}
void DrmAtomicCommit::addBuffer(DrmPlane *plane, const std::shared_ptr<DrmFramebuffer> &buffer)
{
addProperty(plane->fbId, buffer ? buffer->framebufferId() : 0);
m_buffers[plane] = buffer;
}
bool DrmAtomicCommit::test()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK, this) == 0;
}
bool DrmAtomicCommit::testAllowModeset()
{
return drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, this) == 0;
}
bool DrmAtomicCommit::commit()
{
m_commitSuccessful = (drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, this) == 0);
return m_commitSuccessful;
}
bool DrmAtomicCommit::commitModeset()
{
m_commitSuccessful = (drmModeAtomicCommit(m_gpu->fd(), m_req.get(), DRM_MODE_ATOMIC_ALLOW_MODESET, this) == 0);
return m_commitSuccessful;
}
drmModeAtomicReq *DrmAtomicCommit::req() const
{
return m_req.get();
}
DrmLegacyCommit::DrmLegacyCommit(DrmCrtc *crtc, const std::shared_ptr<DrmFramebuffer> &buffer)
: DrmCommit(crtc->gpu())
, m_crtc(crtc)
, m_buffer(buffer)
{
}
DrmLegacyCommit::~DrmLegacyCommit()
{
Q_ASSERT(QThread::currentThread() == QApplication::instance()->thread());
if (m_success) {
m_crtc->setCurrent(m_buffer);
}
}
bool DrmLegacyCommit::doModeset(DrmConnector *connector, DrmConnectorMode *mode)
{
uint32_t connectorId = connector->id();
m_success = (drmModeSetCrtc(gpu()->fd(), m_crtc->id(), m_buffer->framebufferId(), 0, 0, &connectorId, 1, mode->nativeMode()) == 0);
return m_success;
}
bool DrmLegacyCommit::doPageflip(uint32_t flags)
{
m_success = (drmModePageFlip(gpu()->fd(), m_crtc->id(), m_buffer->framebufferId(), flags, this) == 0);
return m_success;
}
}

View file

@ -12,6 +12,7 @@
#include <xf86drmMode.h>
#include <QHash>
#include <unordered_map>
#include "drm_pointer.h"
#include "drm_property.h"
@ -19,14 +20,33 @@
namespace KWin
{
class DrmGpu;
class DrmProperty;
class DrmBlob;
class DrmConnector;
class DrmConnectorMode;
class DrmCrtc;
class DrmFramebuffer;
class DrmGpu;
class DrmPlane;
class DrmProperty;
class DrmAtomicCommit
class DrmCommit
{
public:
virtual ~DrmCommit();
DrmGpu *gpu() const;
protected:
DrmCommit(DrmGpu *gpu);
DrmGpu *const m_gpu;
};
class DrmAtomicCommit : public DrmCommit
{
public:
DrmAtomicCommit(DrmGpu *gpu);
~DrmAtomicCommit() override;
void addProperty(const DrmProperty &prop, uint64_t value);
template<typename T>
@ -35,6 +55,7 @@ public:
addProperty(prop, prop.valueForEnum(enumValue));
}
void addBlob(const DrmProperty &prop, const std::shared_ptr<DrmBlob> &blob);
void addBuffer(DrmPlane *plane, const std::shared_ptr<DrmFramebuffer> &buffer);
bool test();
bool testAllowModeset();
@ -44,9 +65,25 @@ public:
drmModeAtomicReq *req() const;
private:
DrmGpu *const m_gpu;
DrmUniquePtr<drmModeAtomicReq> m_req;
QHash<const DrmProperty *, std::shared_ptr<DrmBlob>> m_blobs;
std::unordered_map<DrmPlane *, std::shared_ptr<DrmFramebuffer>> m_buffers;
bool m_commitSuccessful = false;
};
class DrmLegacyCommit : public DrmCommit
{
public:
DrmLegacyCommit(DrmCrtc *crtc, const std::shared_ptr<DrmFramebuffer> &buffer);
~DrmLegacyCommit() override;
bool doModeset(DrmConnector *connector, DrmConnectorMode *mode);
bool doPageflip(uint32_t flags);
private:
DrmCrtc *const m_crtc;
const std::shared_ptr<DrmFramebuffer> m_buffer;
bool m_success = false;
};
}

View file

@ -7,7 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_commit_thread.h"
#include "drm_atomic_commit.h"
#include "drm_commit.h"
#include "drm_gpu.h"
#include "utils/realtime.h"
@ -38,10 +38,14 @@ DrmCommitThread::DrmCommitThread()
}
// the other thread may replace the commit, but not erase it
Q_ASSERT(m_commit);
if (!m_commit->commit()) {
if (m_commit->commit()) {
// the atomic commit takes ownership of the object
m_commit.release();
} else {
m_droppedCommits.push_back(std::move(m_commit));
QMetaObject::invokeMethod(this, &DrmCommitThread::commitFailed, Qt::ConnectionType::QueuedConnection);
QMetaObject::invokeMethod(this, &DrmCommitThread::clearDroppedCommits, Qt::ConnectionType::QueuedConnection);
}
m_commit.reset();
}
}
}));
@ -75,4 +79,9 @@ bool DrmCommitThread::replaceCommit(std::unique_ptr<DrmAtomicCommit> &&commit)
}
}
void DrmCommitThread::clearDroppedCommits()
{
std::unique_lock lock(m_mutex);
m_droppedCommits.clear();
}
}

View file

@ -12,6 +12,7 @@
#include <QThread>
#include <condition_variable>
#include <mutex>
#include <vector>
namespace KWin
{
@ -33,11 +34,14 @@ Q_SIGNALS:
void commitFailed();
private:
void clearDroppedCommits();
std::unique_ptr<DrmAtomicCommit> m_commit;
std::unique_ptr<QThread> m_thread;
std::mutex m_mutex;
std::condition_variable m_commitPending;
std::chrono::nanoseconds m_targetPageflipTime;
std::vector<std::unique_ptr<DrmAtomicCommit>> m_droppedCommits;
};
}

View file

@ -8,7 +8,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_connector.h"
#include "drm_atomic_commit.h"
#include "drm_commit.h"
#include "drm_crtc.h"
#include "drm_gpu.h"
#include "drm_logging.h"

View file

@ -7,9 +7,9 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_crtc.h"
#include "drm_atomic_commit.h"
#include "drm_backend.h"
#include "drm_buffer.h"
#include "drm_commit.h"
#include "drm_gpu.h"
#include "drm_logging.h"
#include "drm_output.h"
@ -54,12 +54,6 @@ bool DrmCrtc::updateProperties()
return !gpu()->atomicModeSetting() || (modeId.isValid() && active.isValid());
}
void DrmCrtc::flipBuffer()
{
m_currentBuffer = m_nextBuffer;
m_nextBuffer = nullptr;
}
drmModeModeInfo DrmCrtc::queryCurrentMode()
{
m_crtc.reset(drmModeGetCrtc(gpu()->fd(), id()));
@ -76,21 +70,11 @@ std::shared_ptr<DrmFramebuffer> DrmCrtc::current() const
return m_currentBuffer;
}
std::shared_ptr<DrmFramebuffer> DrmCrtc::next() const
{
return m_nextBuffer;
}
void DrmCrtc::setCurrent(const std::shared_ptr<DrmFramebuffer> &buffer)
{
m_currentBuffer = buffer;
}
void DrmCrtc::setNext(const std::shared_ptr<DrmFramebuffer> &buffer)
{
m_nextBuffer = buffer;
}
int DrmCrtc::gammaRampSize() const
{
if (gpu()->atomicModeSetting()) {
@ -118,11 +102,8 @@ void DrmCrtc::disable(DrmAtomicCommit *commit)
commit->addProperty(modeId, 0);
}
void DrmCrtc::releaseBuffers()
void DrmCrtc::releaseCurrentBuffer()
{
if (m_nextBuffer) {
m_nextBuffer->releaseBuffer();
}
if (m_currentBuffer) {
m_currentBuffer->releaseBuffer();
}

View file

@ -37,11 +37,8 @@ public:
drmModeModeInfo queryCurrentMode();
std::shared_ptr<DrmFramebuffer> current() const;
std::shared_ptr<DrmFramebuffer> next() const;
void setCurrent(const std::shared_ptr<DrmFramebuffer> &buffer);
void setNext(const std::shared_ptr<DrmFramebuffer> &buffer);
void flipBuffer();
void releaseBuffers();
void releaseCurrentBuffer();
DrmProperty modeId;
DrmProperty active;
@ -55,7 +52,6 @@ public:
private:
DrmUniquePtr<drmModeCrtc> m_crtc;
std::shared_ptr<DrmFramebuffer> m_currentBuffer;
std::shared_ptr<DrmFramebuffer> m_nextBuffer;
int m_pipeIndex;
DrmPlane *m_primaryPlane;
DrmPlane *m_cursorPlane;

View file

@ -14,6 +14,7 @@
#include "core/session.h"
#include "drm_backend.h"
#include "drm_buffer.h"
#include "drm_commit.h"
#include "drm_connector.h"
#include "drm_crtc.h"
#include "drm_egl_backend.h"
@ -539,7 +540,8 @@ static std::chrono::nanoseconds convertTimestamp(clockid_t sourceClock, clockid_
void DrmGpu::pageFlipHandler(int fd, unsigned int sequence, unsigned int sec, unsigned int usec, unsigned int crtc_id, void *user_data)
{
DrmGpu *gpu = static_cast<DrmGpu *>(user_data);
const auto commit = static_cast<DrmCommit *>(user_data);
const auto gpu = commit->gpu();
// The static_cast<> here are for a 32-bit environment where
// sizeof(time_t) == sizeof(unsigned int) == 4 . Putting @p sec
@ -562,6 +564,7 @@ void DrmGpu::pageFlipHandler(int fd, unsigned int sequence, unsigned int sec, un
} else {
(*it)->pageFlipped(timestamp);
}
delete commit;
}
void DrmGpu::dispatchEvents()
@ -803,10 +806,10 @@ QSize DrmGpu::cursorSize() const
void DrmGpu::releaseBuffers()
{
for (const auto &plane : std::as_const(m_planes)) {
plane->releaseBuffers();
plane->releaseCurrentBuffer();
}
for (const auto &crtc : std::as_const(m_crtcs)) {
crtc->releaseBuffers();
crtc->releaseCurrentBuffer();
}
for (const auto &pipeline : std::as_const(m_pipelines)) {
pipeline->primaryLayer()->releaseBuffers();

View file

@ -10,7 +10,7 @@
#include <errno.h>
#include "drm_atomic_commit.h"
#include "drm_commit.h"
#include "drm_gpu.h"
#include "drm_logging.h"
#include "drm_pointer.h"

View file

@ -12,9 +12,9 @@
#include <errno.h>
#include "core/session.h"
#include "drm_atomic_commit.h"
#include "drm_backend.h"
#include "drm_buffer.h"
#include "drm_commit.h"
#include "drm_commit_thread.h"
#include "drm_connector.h"
#include "drm_crtc.h"
@ -139,19 +139,12 @@ DrmPipeline::Error DrmPipeline::commitPipelinesAtomic(const QVector<DrmPipeline
// The kernel fails commits with DRM_MODE_PAGE_FLIP_EVENT when a crtc is disabled in the commit
// and already was disabled before, to work around some quirks in old userspace.
// Instead of using DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, do the modeset in a blocking
// fashion without page flip events and directly call the pageFlipped method afterwards
// fashion without page flip events
if (!commit->commitModeset()) {
qCCritical(KWIN_DRM) << "Atomic modeset commit failed!" << strerror(errno);
return errnoToError();
}
std::for_each(pipelines.begin(), pipelines.end(), std::mem_fn(&DrmPipeline::atomicModesetSuccessful));
for (const auto &obj : unusedObjects) {
if (auto crtc = dynamic_cast<DrmCrtc *>(obj)) {
crtc->flipBuffer();
} else if (auto plane = dynamic_cast<DrmPlane *>(obj)) {
plane->flipBuffer();
}
}
return Error::None;
}
case CommitMode::Test: {
@ -221,15 +214,15 @@ bool DrmPipeline::prepareAtomicPresentation(DrmAtomicCommit *commit)
return false;
}
const auto fb = m_pending.layer->currentBuffer().get();
const auto fb = m_pending.layer->currentBuffer();
m_pending.crtc->primaryPlane()->set(commit, QPoint(0, 0), fb->buffer()->size(), centerBuffer(fb->buffer()->size(), m_pending.mode->size()));
commit->addProperty(m_pending.crtc->primaryPlane()->fbId, fb->framebufferId());
commit->addBuffer(m_pending.crtc->primaryPlane(), fb);
if (auto plane = m_pending.crtc->cursorPlane()) {
const auto layer = cursorLayer();
plane->set(commit, QPoint(0, 0), gpu()->cursorSize(), QRect(layer->position(), gpu()->cursorSize()));
commit->addProperty(plane->crtcId, layer->isVisible() ? m_pending.crtc->id() : 0);
commit->addProperty(plane->fbId, layer->isVisible() ? layer->currentBuffer()->framebufferId() : 0);
commit->addBuffer(plane, layer->isVisible() ? layer->currentBuffer() : nullptr);
}
return true;
}
@ -350,12 +343,6 @@ void DrmPipeline::atomicCommitSuccessful()
if (activePending()) {
m_pageflipPending = true;
}
if (m_pending.crtc) {
m_pending.crtc->primaryPlane()->setNext(m_pending.layer->currentBuffer());
if (m_pending.crtc->cursorPlane()) {
m_pending.crtc->cursorPlane()->setNext(cursorLayer()->currentBuffer());
}
}
m_current = m_pending;
}
@ -426,13 +413,6 @@ DrmGpu *DrmPipeline::gpu() const
void DrmPipeline::pageFlipped(std::chrono::nanoseconds timestamp)
{
m_current.crtc->flipBuffer();
if (m_current.crtc->primaryPlane()) {
m_current.crtc->primaryPlane()->flipBuffer();
}
if (m_current.crtc->cursorPlane()) {
m_current.crtc->cursorPlane()->flipBuffer();
}
m_pageflipPending = false;
if (m_output) {
m_output->pageFlipped(timestamp);

View file

@ -7,8 +7,9 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "drm_buffer.h"
#include "core/graphicsbuffer.h"
#include "drm_buffer.h"
#include "drm_commit.h"
#include "drm_connector.h"
#include "drm_crtc.h"
#include "drm_gpu.h"
@ -35,12 +36,14 @@ DrmPipeline::Error DrmPipeline::presentLegacy()
if (m_pending.syncMode == RenderLoopPrivate::SyncMode::Async || m_pending.syncMode == RenderLoopPrivate::SyncMode::AdaptiveAsync) {
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
}
if (drmModePageFlip(gpu()->fd(), m_pending.crtc->id(), buffer->framebufferId(), flags, gpu()) != 0) {
auto commit = std::make_unique<DrmLegacyCommit>(m_pending.crtc, buffer);
if (!commit->doPageflip(flags)) {
qCWarning(KWIN_DRM) << "Page flip failed:" << strerror(errno);
return errnoToError();
}
// the pageflip takes ownership of the object
commit.release();
m_pageflipPending = true;
m_pending.crtc->setNext(buffer);
return Error::None;
}
@ -51,21 +54,14 @@ void DrmPipeline::forceLegacyModeset()
DrmPipeline::Error DrmPipeline::legacyModeset()
{
uint32_t connId = m_connector->id();
if (!m_pending.layer->checkTestBuffer()) {
return Error::TestBufferFailed;
}
const auto buffer = m_pending.layer->currentBuffer();
if (drmModeSetCrtc(gpu()->fd(), m_pending.crtc->id(), buffer->framebufferId(), 0, 0, &connId, 1, m_pending.mode->nativeMode()) != 0) {
auto commit = std::make_unique<DrmLegacyCommit>(m_pending.crtc, m_pending.layer->currentBuffer());
if (!commit->doModeset(m_connector, m_pending.mode.get())) {
qCWarning(KWIN_DRM) << "Modeset failed!" << strerror(errno);
return errnoToError();
}
// make sure the buffer gets kept alive, or the modeset gets reverted by the kernel
if (m_pending.crtc->current()) {
m_pending.crtc->setNext(buffer);
} else {
m_pending.crtc->setCurrent(buffer);
}
return Error::None;
}

View file

@ -11,8 +11,8 @@
#include "config-kwin.h"
#include "drm_atomic_commit.h"
#include "drm_buffer.h"
#include "drm_commit.h"
#include "drm_gpu.h"
#include "drm_logging.h"
#include "drm_pointer.h"
@ -107,17 +107,6 @@ bool DrmPlane::updateProperties()
return true;
}
void DrmPlane::setNext(const std::shared_ptr<DrmFramebuffer> &b)
{
m_next = b;
}
void DrmPlane::flipBuffer()
{
m_current = m_next;
m_next = nullptr;
}
void DrmPlane::set(DrmAtomicCommit *commit, const QPoint &srcPos, const QSize &srcSize, const QRect &dst)
{
// Src* are in 16.16 fixed point format
@ -142,17 +131,12 @@ QMap<uint32_t, QVector<uint64_t>> DrmPlane::formats() const
return m_supportedFormats;
}
std::shared_ptr<DrmFramebuffer> DrmPlane::current() const
std::shared_ptr<DrmFramebuffer> DrmPlane::currentBuffer() const
{
return m_current;
}
std::shared_ptr<DrmFramebuffer> DrmPlane::next() const
{
return m_next;
}
void DrmPlane::setCurrent(const std::shared_ptr<DrmFramebuffer> &b)
void DrmPlane::setCurrentBuffer(const std::shared_ptr<DrmFramebuffer> &b)
{
m_current = b;
}
@ -160,15 +144,11 @@ void DrmPlane::setCurrent(const std::shared_ptr<DrmFramebuffer> &b)
void DrmPlane::disable(DrmAtomicCommit *commit)
{
commit->addProperty(crtcId, 0);
commit->addProperty(fbId, 0);
m_next = nullptr;
commit->addBuffer(this, nullptr);
}
void DrmPlane::releaseBuffers()
void DrmPlane::releaseCurrentBuffer()
{
if (m_next) {
m_next->releaseBuffer();
}
if (m_current) {
m_current->releaseBuffer();
}

View file

@ -35,16 +35,12 @@ public:
bool isCrtcSupported(int pipeIndex) const;
QMap<uint32_t, QVector<uint64_t>> formats() const;
std::shared_ptr<DrmFramebuffer> current() const;
std::shared_ptr<DrmFramebuffer> next() const;
void setCurrent(const std::shared_ptr<DrmFramebuffer> &b);
void setNext(const std::shared_ptr<DrmFramebuffer> &b);
void flipBuffer();
std::shared_ptr<DrmFramebuffer> currentBuffer() const;
void setCurrentBuffer(const std::shared_ptr<DrmFramebuffer> &b);
void releaseCurrentBuffer();
void set(DrmAtomicCommit *commit, const QPoint &srcPos, const QSize &srcSize, const QRect &dst);
void releaseBuffers();
enum class TypeIndex : uint64_t {
Overlay = 0,
Primary = 1,
@ -86,7 +82,6 @@ public:
private:
std::shared_ptr<DrmFramebuffer> m_current;
std::shared_ptr<DrmFramebuffer> m_next;
QMap<uint32_t, QVector<uint64_t>> m_supportedFormats;
uint32_t m_possibleCrtcs;