diff --git a/autotests/drm/drmTest.cpp b/autotests/drm/drmTest.cpp index c25adc8b9c..232feca65b 100644 --- a/autotests/drm/drmTest.cpp +++ b/autotests/drm/drmTest.cpp @@ -384,7 +384,7 @@ void DrmTest::testModeset() layer->beginFrame(); output->renderLoop()->prepareNewFrame(); output->renderLoop()->beginPaint(); - const auto frame = std::make_shared(output->renderLoop()); + const auto frame = std::make_shared(output->renderLoop(), std::chrono::nanoseconds(1'000'000'000'000 / output->refreshRate())); layer->endFrame(infiniteRegion(), infiniteRegion(), frame.get()); QVERIFY(output->present(frame)); diff --git a/src/backends/drm/drm_abstract_output.cpp b/src/backends/drm/drm_abstract_output.cpp index 88255a4367..22500dda94 100644 --- a/src/backends/drm/drm_abstract_output.cpp +++ b/src/backends/drm/drm_abstract_output.cpp @@ -34,7 +34,7 @@ void DrmAbstractOutput::frameFailed() const void DrmAbstractOutput::pageFlipped(std::chrono::nanoseconds timestamp, PresentationMode mode) { - m_frame->presented(std::chrono::nanoseconds(1'000'000'000'000 / refreshRate()), timestamp, mode); + m_frame->presented(timestamp, mode); m_frame.reset(); } diff --git a/src/backends/virtual/virtual_output.cpp b/src/backends/virtual/virtual_output.cpp index 209087da4b..e3332b2385 100644 --- a/src/backends/virtual/virtual_output.cpp +++ b/src/backends/virtual/virtual_output.cpp @@ -75,8 +75,10 @@ void VirtualOutput::updateEnabled(bool enabled) void VirtualOutput::vblank(std::chrono::nanoseconds timestamp) { - m_frame->presented(std::chrono::nanoseconds(1'000'000'000'000 / refreshRate()), timestamp, PresentationMode::VSync); - m_frame.reset(); + if (m_frame) { + m_frame->presented(timestamp, PresentationMode::VSync); + m_frame.reset(); + } } } diff --git a/src/backends/wayland/wayland_output.cpp b/src/backends/wayland/wayland_output.cpp index edb00c676e..c471cc7882 100644 --- a/src/backends/wayland/wayland_output.cpp +++ b/src/backends/wayland/wayland_output.cpp @@ -125,8 +125,7 @@ WaylandOutput::WaylandOutput(const QString &name, WaylandBackend *backend) connect(m_surface.get(), &KWayland::Client::Surface::frameRendered, this, [this]() { Q_ASSERT(m_frame); - const auto primary = Compositor::self()->backend()->primaryLayer(this); - m_frame->presented(std::chrono::nanoseconds(1'000'000'000'000 / refreshRate()), std::chrono::steady_clock::now().time_since_epoch(), PresentationMode::VSync); + m_frame->presented(std::chrono::steady_clock::now().time_since_epoch(), PresentationMode::VSync); m_frame.reset(); }); diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp index f4d8411ca1..5c98053238 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp @@ -441,7 +441,7 @@ OutputLayer *EglBackend::primaryLayer(Output *output) void EglBackend::vblank(std::chrono::nanoseconds timestamp) { - m_frame->presented(std::chrono::nanoseconds::zero(), timestamp, PresentationMode::VSync); + m_frame->presented(timestamp, PresentationMode::VSync); m_frame.reset(); } diff --git a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp index a518d0cd43..f8c209d47d 100644 --- a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp @@ -714,7 +714,7 @@ void GlxBackend::present(Output *output, const std::shared_ptr &fra void GlxBackend::vblank(std::chrono::nanoseconds timestamp) { - m_frame->presented(std::chrono::nanoseconds::zero(), timestamp, PresentationMode::VSync); + m_frame->presented(timestamp, PresentationMode::VSync); m_frame.reset(); } diff --git a/src/backends/x11/windowed/x11_windowed_output.cpp b/src/backends/x11/windowed/x11_windowed_output.cpp index 81825d9d0b..f116aeafbd 100644 --- a/src/backends/x11/windowed/x11_windowed_output.cpp +++ b/src/backends/x11/windowed/x11_windowed_output.cpp @@ -308,7 +308,7 @@ void X11WindowedOutput::resize(const QSize &pixelSize) void X11WindowedOutput::handlePresentCompleteNotify(xcb_present_complete_notify_event_t *event) { std::chrono::microseconds timestamp(event->ust); - m_frame->presented(std::chrono::nanoseconds(1'000'000'000'000 / refreshRate()), timestamp, PresentationMode::VSync); + m_frame->presented(timestamp, PresentationMode::VSync); m_frame.reset(); } diff --git a/src/compositor_wayland.cpp b/src/compositor_wayland.cpp index de7d7ed5d3..935ec133b4 100644 --- a/src/compositor_wayland.cpp +++ b/src/compositor_wayland.cpp @@ -290,7 +290,7 @@ void WaylandCompositor::composite(RenderLoop *renderLoop) superLayer->setOutputLayer(primaryLayer); renderLoop->prepareNewFrame(); - auto frame = std::make_shared(renderLoop); + auto frame = std::make_shared(renderLoop, std::chrono::nanoseconds(1'000'000'000'000 / output->refreshRate())); if (primaryLayer->needsRepaint() || superLayer->needsRepaint()) { renderLoop->beginPaint(); diff --git a/src/compositor_x11.cpp b/src/compositor_x11.cpp index 7db12838e5..4602d3b164 100644 --- a/src/compositor_x11.cpp +++ b/src/compositor_x11.cpp @@ -457,7 +457,7 @@ void X11Compositor::composite(RenderLoop *renderLoop) superLayer->setOutputLayer(primaryLayer); renderLoop->prepareNewFrame(); - auto frame = std::make_shared(renderLoop); + auto frame = std::make_shared(renderLoop, std::chrono::nanoseconds(1'000'000'000'000) / renderLoop->refreshRate()); if (primaryLayer->needsRepaint() || superLayer->needsRepaint()) { renderLoop->beginPaint(); diff --git a/src/core/renderbackend.cpp b/src/core/renderbackend.cpp index c8c8dac755..fed1b5fa48 100644 --- a/src/core/renderbackend.cpp +++ b/src/core/renderbackend.cpp @@ -42,8 +42,9 @@ std::optional CpuRenderTimeQuery::query() }; } -OutputFrame::OutputFrame(RenderLoop *loop) +OutputFrame::OutputFrame(RenderLoop *loop, std::chrono::nanoseconds refreshDuration) : m_loop(loop) + , m_refreshDuration(refreshDuration) { } @@ -74,12 +75,12 @@ std::optional OutputFrame::queryRenderTime() const return ret.end - ret.start; } -void OutputFrame::presented(std::chrono::nanoseconds refreshDuration, std::chrono::nanoseconds timestamp, PresentationMode mode) +void OutputFrame::presented(std::chrono::nanoseconds timestamp, PresentationMode mode) { std::optional renderTime = queryRenderTime(); RenderLoopPrivate::get(m_loop)->notifyFrameCompleted(timestamp, renderTime, mode); for (const auto &feedback : m_feedbacks) { - feedback->presented(refreshDuration, timestamp, mode); + feedback->presented(m_refreshDuration, timestamp, mode); } } diff --git a/src/core/renderbackend.h b/src/core/renderbackend.h index 313c0b668c..a7c0671a84 100644 --- a/src/core/renderbackend.h +++ b/src/core/renderbackend.h @@ -75,10 +75,10 @@ private: class KWIN_EXPORT OutputFrame { public: - explicit OutputFrame(RenderLoop *loop); + explicit OutputFrame(RenderLoop *loop, std::chrono::nanoseconds refreshDuration); ~OutputFrame(); - void presented(std::chrono::nanoseconds refreshDuration, std::chrono::nanoseconds timestamp, PresentationMode mode); + void presented(std::chrono::nanoseconds timestamp, PresentationMode mode); void failed(); void addFeedback(std::unique_ptr &&feedback); @@ -97,6 +97,7 @@ private: std::optional queryRenderTime() const; RenderLoop *const m_loop; + const std::chrono::nanoseconds m_refreshDuration; std::vector> m_feedbacks; std::optional m_contentType; PresentationMode m_presentationMode = PresentationMode::VSync;