File indexing completed on 2024-11-10 04:57:23
0001 /* 0002 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "utils/softwarevsyncmonitor.h" 0008 0009 namespace KWin 0010 { 0011 0012 std::unique_ptr<SoftwareVsyncMonitor> SoftwareVsyncMonitor::create() 0013 { 0014 return std::unique_ptr<SoftwareVsyncMonitor>{new SoftwareVsyncMonitor()}; 0015 } 0016 0017 SoftwareVsyncMonitor::SoftwareVsyncMonitor() 0018 { 0019 connect(&m_softwareClock, &QTimer::timeout, this, &SoftwareVsyncMonitor::handleSyntheticVsync); 0020 m_softwareClock.setSingleShot(true); 0021 } 0022 0023 int SoftwareVsyncMonitor::refreshRate() const 0024 { 0025 return m_refreshRate; 0026 } 0027 0028 void SoftwareVsyncMonitor::setRefreshRate(int refreshRate) 0029 { 0030 m_refreshRate = refreshRate; 0031 } 0032 0033 void SoftwareVsyncMonitor::handleSyntheticVsync() 0034 { 0035 Q_EMIT vblankOccurred(m_vblankTimestamp); 0036 } 0037 0038 template<typename T> 0039 T alignTimestamp(const T ×tamp, const T &alignment) 0040 { 0041 return timestamp + ((alignment - (timestamp % alignment)) % alignment); 0042 } 0043 0044 void SoftwareVsyncMonitor::arm() 0045 { 0046 if (m_softwareClock.isActive()) { 0047 return; 0048 } 0049 0050 const std::chrono::nanoseconds currentTime(std::chrono::steady_clock::now().time_since_epoch()); 0051 const std::chrono::nanoseconds vblankInterval(1'000'000'000'000ull / m_refreshRate); 0052 0053 m_vblankTimestamp = alignTimestamp(currentTime, vblankInterval); 0054 0055 m_softwareClock.start(std::chrono::duration_cast<std::chrono::milliseconds>(m_vblankTimestamp - currentTime)); 0056 } 0057 0058 } // namespace KWin 0059 0060 #include "moc_softwarevsyncmonitor.cpp"