/* SPDX-FileCopyrightText: 2020 Vlad Zahorodnii SPDX-License-Identifier: GPL-2.0-or-later */ #include "softwarevsyncmonitor.h" namespace KWin { SoftwareVsyncMonitor *SoftwareVsyncMonitor::create(QObject *parent) { return new SoftwareVsyncMonitor(parent); } SoftwareVsyncMonitor::SoftwareVsyncMonitor(QObject *parent) : VsyncMonitor(parent) , m_softwareClock(new QTimer(this)) { connect(m_softwareClock, &QTimer::timeout, this, &SoftwareVsyncMonitor::handleSyntheticVsync); m_softwareClock->setSingleShot(true); } int SoftwareVsyncMonitor::refreshRate() const { return m_refreshRate; } void SoftwareVsyncMonitor::setRefreshRate(int refreshRate) { m_refreshRate = refreshRate; } void SoftwareVsyncMonitor::handleSyntheticVsync() { emit vblankOccurred(m_vblankTimestamp); } template T alignTimestamp(const T ×tamp, const T &alignment) { return timestamp + ((alignment - (timestamp % alignment)) % alignment); } void SoftwareVsyncMonitor::arm() { if (m_softwareClock->isActive()) { return; } const std::chrono::nanoseconds currentTime(std::chrono::steady_clock::now().time_since_epoch()); const std::chrono::nanoseconds vblankInterval(1'000'000'000'000ull / m_refreshRate); m_vblankTimestamp = alignTimestamp(currentTime, vblankInterval); m_softwareClock->start(std::chrono::duration_cast(m_vblankTimestamp - currentTime)); } } // namespace KWin