/* KWin - the KDE window manager This file is part of the KDE project. SPDX-FileCopyrightText: 2023 Xaver Hugl SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include #include #include #include #include namespace KWin { class DrmGpu; class DrmCommit; class DrmAtomicCommit; class DrmLegacyCommit; using TimePoint = std::chrono::steady_clock::time_point; class DrmCommitThread : public QObject { Q_OBJECT public: explicit DrmCommitThread(DrmGpu *gpu, const QString &name); ~DrmCommitThread(); void addCommit(std::unique_ptr &&commit); void setPendingCommit(std::unique_ptr &&commit); void setModeInfo(uint32_t maximum, std::chrono::nanoseconds vblankTime); void pageFlipped(std::chrono::nanoseconds timestamp); bool pageflipsPending(); /** * @return how long before the desired presentation timestamp the commit has to be added * in order to get presented at that timestamp */ std::chrono::nanoseconds safetyMargin() const; /** * attempts to submit the currently scheduled commits as a single one, * if there isn't already a commit pending * * @returns if there's a pending commit after this method returns */ bool drain(); private: void clearDroppedCommits(); TimePoint estimateNextVblank(TimePoint now) const; void optimizeCommits(TimePoint pageflipTarget); void submit(); std::unique_ptr m_committed; std::vector> m_commits; std::unique_ptr m_thread; std::mutex m_mutex; std::condition_variable m_commitPending; TimePoint m_lastPageflip; TimePoint m_targetPageflipTime; std::chrono::nanoseconds m_minVblankInterval; std::vector> m_commitsToDelete; bool m_vrr = false; bool m_tearing = false; std::chrono::nanoseconds m_safetyMargin{0}; }; }