backends: port vsync helpers to std::unique_ptr

This commit is contained in:
Xaver Hugl 2022-06-01 12:57:56 +02:00
parent 4cab9c4fc7
commit e745577b4c
17 changed files with 77 additions and 95 deletions

View file

@ -22,7 +22,7 @@ namespace KWin
DrmVirtualOutput::DrmVirtualOutput(const QString &name, DrmGpu *gpu, const QSize &size, Type type)
: DrmAbstractOutput(gpu)
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create())
{
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &DrmVirtualOutput::vblank);

View file

@ -19,9 +19,9 @@ VirtualOutput::VirtualOutput(VirtualBackend *parent)
: Output(parent)
, m_backend(parent)
, m_renderLoop(new RenderLoop(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create())
{
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &VirtualOutput::vblank);
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &VirtualOutput::vblank);
static int identifier = -1;
m_identifier = ++identifier;
@ -41,7 +41,7 @@ RenderLoop *VirtualOutput::renderLoop() const
SoftwareVsyncMonitor *VirtualOutput::vsyncMonitor() const
{
return m_vsyncMonitor;
return m_vsyncMonitor.get();
}
void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)

View file

@ -43,7 +43,7 @@ private:
VirtualBackend *m_backend;
RenderLoop *m_renderLoop;
SoftwareVsyncMonitor *m_vsyncMonitor;
std::unique_ptr<SoftwareVsyncMonitor> m_vsyncMonitor;
int m_gammaSize = 200;
bool m_gammaResult = true;
int m_identifier;

View file

@ -50,13 +50,13 @@ EglBackend::EglBackend(Display *display, X11StandalonePlatform *backend)
// There is no any way to determine when a buffer swap completes with EGL. Fallback
// to software vblank events. Could we use the Present extension to get notified when
// the overlay window is actually presented on the screen?
m_vsyncMonitor = SoftwareVsyncMonitor::create(this);
m_vsyncMonitor = SoftwareVsyncMonitor::create();
connect(backend->renderLoop(), &RenderLoop::refreshRateChanged, this, [this, backend]() {
m_vsyncMonitor->setRefreshRate(backend->renderLoop()->refreshRate());
});
m_vsyncMonitor->setRefreshRate(backend->renderLoop()->refreshRate());
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &EglBackend::vblank);
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &EglBackend::vblank);
connect(screens(), &Screens::sizeChanged, this, &EglBackend::screenGeometryChanged);
}
@ -106,7 +106,7 @@ void EglBackend::init()
return;
}
m_fbo.reset(new GLFramebuffer(0, screens()->size()));
m_fbo = std::make_unique<GLFramebuffer>(0, screens()->size());
kwinApp()->platform()->setSceneEglDisplay(shareDisplay);
kwinApp()->platform()->setSceneEglGlobalShareContext(shareContext);
@ -119,7 +119,7 @@ void EglBackend::screenGeometryChanged()
// The back buffer contents are now undefined
m_bufferAge = 0;
m_fbo.reset(new GLFramebuffer(0, screens()->size()));
m_fbo = std::make_unique<GLFramebuffer>(0, screens()->size());
}
OutputLayerBeginFrameInfo EglBackend::beginFrame()

View file

@ -56,7 +56,7 @@ private:
void vblank(std::chrono::nanoseconds timestamp);
X11StandalonePlatform *m_backend;
SoftwareVsyncMonitor *m_vsyncMonitor;
std::unique_ptr<SoftwareVsyncMonitor> m_vsyncMonitor;
DamageJournal m_damageJournal;
std::unique_ptr<GLFramebuffer> m_fbo;
int m_bufferAge = 0;

View file

@ -141,8 +141,7 @@ GlxBackend::GlxBackend(Display *display, X11StandalonePlatform *backend)
GlxBackend::~GlxBackend()
{
delete m_vsyncMonitor;
m_vsyncMonitor.reset();
// No completion events will be received for in-flight frames, this may lock the
// render loop. We need to ensure that the render loop is back to its initial state
// if the render backend is about to be destroyed.
@ -303,23 +302,23 @@ void GlxBackend::init()
// option. NVIDIA doesn't provide any extension such as GLX_INTEL_swap_event.
if (!forceSoftwareVsync) {
if (!m_vsyncMonitor) {
m_vsyncMonitor = SGIVideoSyncVsyncMonitor::create(this);
m_vsyncMonitor = SGIVideoSyncVsyncMonitor::create();
}
if (!m_vsyncMonitor) {
m_vsyncMonitor = OMLSyncControlVsyncMonitor::create(this);
m_vsyncMonitor = OMLSyncControlVsyncMonitor::create();
}
}
if (!m_vsyncMonitor) {
SoftwareVsyncMonitor *monitor = SoftwareVsyncMonitor::create(this);
std::unique_ptr<SoftwareVsyncMonitor> monitor = SoftwareVsyncMonitor::create();
RenderLoop *renderLoop = m_backend->renderLoop();
monitor->setRefreshRate(renderLoop->refreshRate());
connect(renderLoop, &RenderLoop::refreshRateChanged, this, [this, monitor]() {
monitor->setRefreshRate(m_backend->renderLoop()->refreshRate());
connect(renderLoop, &RenderLoop::refreshRateChanged, this, [this, m = monitor.get()]() {
m->setRefreshRate(m_backend->renderLoop()->refreshRate());
});
m_vsyncMonitor = monitor;
m_vsyncMonitor = std::move(monitor);
}
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &GlxBackend::vblank);
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &GlxBackend::vblank);
}
setIsDirectRendering(bool(glXIsDirect(display(), ctx)));

View file

@ -133,7 +133,7 @@ private:
bool m_haveSGISwapControl = false;
Display *m_x11Display;
X11StandalonePlatform *m_backend;
VsyncMonitor *m_vsyncMonitor = nullptr;
std::unique_ptr<VsyncMonitor> m_vsyncMonitor;
std::unique_ptr<GlxLayer> m_layer;
friend class GlxPixmapTexturePrivate;
};

View file

@ -17,7 +17,7 @@
namespace KWin
{
OMLSyncControlVsyncMonitor *OMLSyncControlVsyncMonitor::create(QObject *parent)
std::unique_ptr<OMLSyncControlVsyncMonitor> OMLSyncControlVsyncMonitor::create()
{
const char *extensions = glXQueryExtensionsString(QX11Info::display(),
QX11Info::appScreen());
@ -25,16 +25,15 @@ OMLSyncControlVsyncMonitor *OMLSyncControlVsyncMonitor::create(QObject *parent)
return nullptr; // GLX_OML_sync_control is unsupported.
}
OMLSyncControlVsyncMonitor *monitor = new OMLSyncControlVsyncMonitor(parent);
std::unique_ptr<OMLSyncControlVsyncMonitor> monitor{new OMLSyncControlVsyncMonitor()};
if (monitor->isValid()) {
return monitor;
} else {
return nullptr;
}
delete monitor;
return nullptr;
}
OMLSyncControlVsyncMonitorHelper::OMLSyncControlVsyncMonitorHelper(QObject *parent)
: QObject(parent)
OMLSyncControlVsyncMonitorHelper::OMLSyncControlVsyncMonitorHelper()
{
// Establish a new X11 connection to avoid locking up the main X11 connection.
m_display = XOpenDisplay(DisplayString(QX11Info::display()));
@ -126,39 +125,33 @@ void OMLSyncControlVsyncMonitorHelper::poll()
Q_EMIT vblankOccurred(std::chrono::microseconds(ust));
}
OMLSyncControlVsyncMonitor::OMLSyncControlVsyncMonitor(QObject *parent)
: VsyncMonitor(parent)
, m_thread(new QThread)
, m_helper(new OMLSyncControlVsyncMonitorHelper)
OMLSyncControlVsyncMonitor::OMLSyncControlVsyncMonitor()
{
m_helper->moveToThread(m_thread);
m_helper.moveToThread(&m_thread);
connect(m_helper, &OMLSyncControlVsyncMonitorHelper::errorOccurred,
connect(&m_helper, &OMLSyncControlVsyncMonitorHelper::errorOccurred,
this, &OMLSyncControlVsyncMonitor::errorOccurred);
connect(m_helper, &OMLSyncControlVsyncMonitorHelper::vblankOccurred,
connect(&m_helper, &OMLSyncControlVsyncMonitorHelper::vblankOccurred,
this, &OMLSyncControlVsyncMonitor::vblankOccurred);
m_thread->setObjectName(QStringLiteral("vsync event monitor"));
m_thread->start();
m_thread.setObjectName(QStringLiteral("vsync event monitor"));
m_thread.start();
}
OMLSyncControlVsyncMonitor::~OMLSyncControlVsyncMonitor()
{
m_thread->quit();
m_thread->wait();
delete m_helper;
delete m_thread;
m_thread.quit();
m_thread.wait();
}
bool OMLSyncControlVsyncMonitor::isValid() const
{
return m_helper->isValid();
return m_helper.isValid();
}
void OMLSyncControlVsyncMonitor::arm()
{
QMetaObject::invokeMethod(m_helper, &OMLSyncControlVsyncMonitorHelper::poll);
QMetaObject::invokeMethod(&m_helper, &OMLSyncControlVsyncMonitorHelper::poll);
}
} // namespace KWin

View file

@ -12,6 +12,7 @@
#include <fixx11h.h>
#include <QThread>
#include <memory>
namespace KWin
{
@ -25,7 +26,7 @@ class OMLSyncControlVsyncMonitorHelper : public QObject
Q_OBJECT
public:
explicit OMLSyncControlVsyncMonitorHelper(QObject *parent = nullptr);
explicit OMLSyncControlVsyncMonitorHelper();
~OMLSyncControlVsyncMonitorHelper() override;
bool isValid() const;
@ -57,7 +58,7 @@ class OMLSyncControlVsyncMonitor : public VsyncMonitor
Q_OBJECT
public:
static OMLSyncControlVsyncMonitor *create(QObject *parent);
static std::unique_ptr<OMLSyncControlVsyncMonitor> create();
~OMLSyncControlVsyncMonitor() override;
bool isValid() const;
@ -66,10 +67,10 @@ public Q_SLOTS:
void arm() override;
private:
explicit OMLSyncControlVsyncMonitor(QObject *parent = nullptr);
explicit OMLSyncControlVsyncMonitor();
QThread *m_thread = nullptr;
OMLSyncControlVsyncMonitorHelper *m_helper = nullptr;
QThread m_thread;
OMLSyncControlVsyncMonitorHelper m_helper;
};
} // namespace KWin

View file

@ -17,7 +17,7 @@
namespace KWin
{
SGIVideoSyncVsyncMonitor *SGIVideoSyncVsyncMonitor::create(QObject *parent)
std::unique_ptr<SGIVideoSyncVsyncMonitor> SGIVideoSyncVsyncMonitor::create()
{
const char *extensions = glXQueryExtensionsString(QX11Info::display(),
QX11Info::appScreen());
@ -25,16 +25,15 @@ SGIVideoSyncVsyncMonitor *SGIVideoSyncVsyncMonitor::create(QObject *parent)
return nullptr; // GLX_SGI_video_sync is unsupported.
}
SGIVideoSyncVsyncMonitor *monitor = new SGIVideoSyncVsyncMonitor(parent);
std::unique_ptr<SGIVideoSyncVsyncMonitor> monitor{new SGIVideoSyncVsyncMonitor()};
if (monitor->isValid()) {
return monitor;
} else {
return nullptr;
}
delete monitor;
return nullptr;
}
SGIVideoSyncVsyncMonitorHelper::SGIVideoSyncVsyncMonitorHelper(QObject *parent)
: QObject(parent)
SGIVideoSyncVsyncMonitorHelper::SGIVideoSyncVsyncMonitorHelper()
{
// Establish a new X11 connection to avoid locking up the main X11 connection.
m_display = XOpenDisplay(DisplayString(QX11Info::display()));
@ -128,39 +127,33 @@ void SGIVideoSyncVsyncMonitorHelper::poll()
Q_EMIT vblankOccurred(std::chrono::steady_clock::now().time_since_epoch());
}
SGIVideoSyncVsyncMonitor::SGIVideoSyncVsyncMonitor(QObject *parent)
: VsyncMonitor(parent)
, m_thread(new QThread)
, m_helper(new SGIVideoSyncVsyncMonitorHelper)
SGIVideoSyncVsyncMonitor::SGIVideoSyncVsyncMonitor()
{
m_helper->moveToThread(m_thread);
m_helper.moveToThread(&m_thread);
connect(m_helper, &SGIVideoSyncVsyncMonitorHelper::errorOccurred,
connect(&m_helper, &SGIVideoSyncVsyncMonitorHelper::errorOccurred,
this, &SGIVideoSyncVsyncMonitor::errorOccurred);
connect(m_helper, &SGIVideoSyncVsyncMonitorHelper::vblankOccurred,
connect(&m_helper, &SGIVideoSyncVsyncMonitorHelper::vblankOccurred,
this, &SGIVideoSyncVsyncMonitor::vblankOccurred);
m_thread->setObjectName(QStringLiteral("vsync event monitor"));
m_thread->start();
m_thread.setObjectName(QStringLiteral("vsync event monitor"));
m_thread.start();
}
SGIVideoSyncVsyncMonitor::~SGIVideoSyncVsyncMonitor()
{
m_thread->quit();
m_thread->wait();
delete m_helper;
delete m_thread;
m_thread.quit();
m_thread.wait();
}
bool SGIVideoSyncVsyncMonitor::isValid() const
{
return m_helper->isValid();
return m_helper.isValid();
}
void SGIVideoSyncVsyncMonitor::arm()
{
QMetaObject::invokeMethod(m_helper, &SGIVideoSyncVsyncMonitorHelper::poll);
QMetaObject::invokeMethod(&m_helper, &SGIVideoSyncVsyncMonitorHelper::poll);
}
} // namespace KWin

View file

@ -25,7 +25,7 @@ class SGIVideoSyncVsyncMonitorHelper : public QObject
Q_OBJECT
public:
explicit SGIVideoSyncVsyncMonitorHelper(QObject *parent = nullptr);
explicit SGIVideoSyncVsyncMonitorHelper();
~SGIVideoSyncVsyncMonitorHelper() override;
bool isValid() const;
@ -57,7 +57,7 @@ class SGIVideoSyncVsyncMonitor : public VsyncMonitor
Q_OBJECT
public:
static SGIVideoSyncVsyncMonitor *create(QObject *parent);
static std::unique_ptr<SGIVideoSyncVsyncMonitor> create();
~SGIVideoSyncVsyncMonitor() override;
bool isValid() const;
@ -66,10 +66,10 @@ public Q_SLOTS:
void arm() override;
private:
explicit SGIVideoSyncVsyncMonitor(QObject *parent = nullptr);
explicit SGIVideoSyncVsyncMonitor();
QThread *m_thread = nullptr;
SGIVideoSyncVsyncMonitorHelper *m_helper = nullptr;
QThread m_thread;
SGIVideoSyncVsyncMonitorHelper m_helper;
};
} // namespace KWin

View file

@ -28,7 +28,7 @@ namespace KWin
X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend)
: Output(backend)
, m_renderLoop(new RenderLoop(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create())
, m_backend(backend)
{
m_window = xcb_generate_id(m_backend->connection());
@ -39,7 +39,7 @@ X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend)
.name = QStringLiteral("X11-%1").arg(identifier),
});
connect(m_vsyncMonitor, &VsyncMonitor::vblankOccurred, this, &X11WindowedOutput::vblank);
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &X11WindowedOutput::vblank);
}
X11WindowedOutput::~X11WindowedOutput()
@ -57,7 +57,7 @@ RenderLoop *X11WindowedOutput::renderLoop() const
SoftwareVsyncMonitor *X11WindowedOutput::vsyncMonitor() const
{
return m_vsyncMonitor;
return m_vsyncMonitor.get();
}
void X11WindowedOutput::init(const QPoint &logicalPosition, const QSize &pixelSize)

View file

@ -76,7 +76,7 @@ private:
xcb_window_t m_window = XCB_WINDOW_NONE;
NETWinInfo *m_winInfo = nullptr;
RenderLoop *m_renderLoop;
SoftwareVsyncMonitor *m_vsyncMonitor;
std::unique_ptr<SoftwareVsyncMonitor> m_vsyncMonitor;
QPoint m_hostPosition;
X11WindowedBackend *m_backend;

View file

@ -9,17 +9,15 @@
namespace KWin
{
SoftwareVsyncMonitor *SoftwareVsyncMonitor::create(QObject *parent)
std::unique_ptr<SoftwareVsyncMonitor> SoftwareVsyncMonitor::create()
{
return new SoftwareVsyncMonitor(parent);
return std::unique_ptr<SoftwareVsyncMonitor>{new SoftwareVsyncMonitor()};
}
SoftwareVsyncMonitor::SoftwareVsyncMonitor(QObject *parent)
: VsyncMonitor(parent)
, m_softwareClock(new QTimer(this))
SoftwareVsyncMonitor::SoftwareVsyncMonitor()
{
connect(m_softwareClock, &QTimer::timeout, this, &SoftwareVsyncMonitor::handleSyntheticVsync);
m_softwareClock->setSingleShot(true);
connect(&m_softwareClock, &QTimer::timeout, this, &SoftwareVsyncMonitor::handleSyntheticVsync);
m_softwareClock.setSingleShot(true);
}
int SoftwareVsyncMonitor::refreshRate() const
@ -45,7 +43,7 @@ T alignTimestamp(const T &timestamp, const T &alignment)
void SoftwareVsyncMonitor::arm()
{
if (m_softwareClock->isActive()) {
if (m_softwareClock.isActive()) {
return;
}
@ -54,7 +52,7 @@ void SoftwareVsyncMonitor::arm()
m_vblankTimestamp = alignTimestamp(currentTime, vblankInterval);
m_softwareClock->start(std::chrono::duration_cast<std::chrono::milliseconds>(m_vblankTimestamp - currentTime));
m_softwareClock.start(std::chrono::duration_cast<std::chrono::milliseconds>(m_vblankTimestamp - currentTime));
}
} // namespace KWin

View file

@ -9,6 +9,7 @@
#include "vsyncmonitor.h"
#include <QTimer>
#include <memory>
namespace KWin
{
@ -26,7 +27,7 @@ class KWIN_EXPORT SoftwareVsyncMonitor : public VsyncMonitor
Q_OBJECT
public:
static SoftwareVsyncMonitor *create(QObject *parent);
static std::unique_ptr<SoftwareVsyncMonitor> create();
int refreshRate() const;
void setRefreshRate(int refreshRate);
@ -35,10 +36,10 @@ public Q_SLOTS:
void arm() override;
private:
explicit SoftwareVsyncMonitor(QObject *parent = nullptr);
explicit SoftwareVsyncMonitor();
void handleSyntheticVsync();
QTimer *m_softwareClock = nullptr;
QTimer m_softwareClock;
int m_refreshRate = 60000;
std::chrono::nanoseconds m_vblankTimestamp = std::chrono::nanoseconds::zero();
};

View file

@ -9,9 +9,6 @@
namespace KWin
{
VsyncMonitor::VsyncMonitor(QObject *parent)
: QObject(parent)
{
}
VsyncMonitor::VsyncMonitor() = default;
} // namespace KWin

View file

@ -23,7 +23,7 @@ class KWIN_EXPORT VsyncMonitor : public QObject
Q_OBJECT
public:
explicit VsyncMonitor(QObject *parent = nullptr);
explicit VsyncMonitor();
public Q_SLOTS:
virtual void arm() = 0;