Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Vogtinator:kwinperf
kwin5
0001-Fake-vblank-synchronized-page-flips-on-vir...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Fake-vblank-synchronized-page-flips-on-virtual-DRM-d.patch of Package kwin5
From 4a71ca5a3af3fa54399d8da82ed01032bfdf1482 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Sat, 7 Aug 2021 13:26:49 +0200 Subject: [PATCH] Fake vblank synchronized page flips on virtual DRM drivers --- src/plugins/platforms/drm/drm_gpu.cpp | 28 +++++++++++++++++++++++---- src/plugins/platforms/drm/drm_gpu.h | 3 +++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/drm/drm_gpu.cpp b/src/plugins/platforms/drm/drm_gpu.cpp index 405d7ec8f..389782afa 100644 --- a/src/plugins/platforms/drm/drm_gpu.cpp +++ b/src/plugins/platforms/drm/drm_gpu.cpp @@ -72,10 +72,19 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device qCDebug(KWIN_DRM) << "drmModeAddFB2WithModifiers is" << (m_addFB2ModifiersSupported ? "supported" : "not supported") << "on GPU" << m_devNode; } - // find out if this GPU is using the NVidia proprietary driver DrmScopedPointer<drmVersion> version(drmGetVersion(fd)); + qCDebug(KWIN_DRM) << m_devNode << "uses driver" << version->name; + + // find out if this GPU is using the NVidia proprietary driver m_useEglStreams = strstr(version->name, "nvidia-drm"); + // Some drivers don't have page flips synced to the refresh rate, do it ourselves + m_fakeVblankWait = strstr(version->name, "virtio") || strstr(version->name, "qxl") + || strstr(version->name, "bochs"); + if (m_fakeVblankWait) { + qCDebug(KWIN_DRM) << "Faking wait for Vblank on" << m_devNode; + } + m_socketNotifier = new QSocketNotifier(fd, QSocketNotifier::Read, this); connect(m_socketNotifier, &QSocketNotifier::activated, this, &DrmGpu::dispatchEvents); @@ -393,7 +402,7 @@ static std::chrono::nanoseconds convertTimestamp(clockid_t sourceClock, clockid_ return convertTimestamp(targetCurrentTime) - delta; } -static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) +void DrmGpu::pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { Q_UNUSED(fd) Q_UNUSED(frame) @@ -426,9 +435,20 @@ static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsign timestamp = std::chrono::steady_clock::now().time_since_epoch(); } + RenderLoop *renderLoop = output->renderLoop(); + + if(output->gpu()->m_fakeVblankWait) { + // Page flips don't wait for vblank, they complete as fast as possible. + // To avoid rendering at unlimited speed, make sure there's at least + // the vblank interval between consecutive presentations. + const std::chrono::nanoseconds vblankInterval(1'000'000'000'000ull / renderLoop->refreshRate()); + const auto fakePresented = renderLoop->lastPresentationTimestamp() + vblankInterval; + if (fakePresented > timestamp) + timestamp = fakePresented; + } + output->pageFlipped(); - RenderLoopPrivate *renderLoopPrivate = RenderLoopPrivate::get(output->renderLoop()); - renderLoopPrivate->notifyFrameCompleted(timestamp); + RenderLoopPrivate::get(renderLoop)->notifyFrameCompleted(timestamp); } void DrmGpu::dispatchEvents() diff --git a/src/plugins/platforms/drm/drm_gpu.h b/src/plugins/platforms/drm/drm_gpu.h index c8d0450da..5a32dcdbc 100644 --- a/src/plugins/platforms/drm/drm_gpu.h +++ b/src/plugins/platforms/drm/drm_gpu.h @@ -114,6 +114,8 @@ private: void removeOutput(DrmOutput *output); void tryAMS(); + static void pageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data); + DrmBackend* const m_backend; QPointer<AbstractEglDrmBackend> m_eglBackend; @@ -123,6 +125,7 @@ private: const dev_t m_deviceId; bool m_atomicModeSetting; bool m_useEglStreams; + bool m_fakeVblankWait; gbm_device* m_gbmDevice; EGLDisplay m_eglDisplay = EGL_NO_DISPLAY; clockid_t m_presentationClock; -- 2.32.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor