File indexing completed on 2024-11-10 04:56:36

0001 /*
0002     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "utils/vsyncmonitor.h"
0010 
0011 #include <epoxy/glx.h>
0012 #include <fixx11h.h>
0013 
0014 #include <QThread>
0015 
0016 namespace KWin
0017 {
0018 
0019 /**
0020  * The SGIVideoSyncVsyncMonitorHelper class is responsible for waiting for vsync events on the
0021  * root window. Note that the helper runs on a separate thread.
0022  */
0023 class SGIVideoSyncVsyncMonitorHelper : public QObject
0024 {
0025     Q_OBJECT
0026 
0027 public:
0028     explicit SGIVideoSyncVsyncMonitorHelper();
0029     ~SGIVideoSyncVsyncMonitorHelper() override;
0030 
0031     bool isValid() const;
0032 
0033 public Q_SLOTS:
0034     void poll();
0035 
0036 Q_SIGNALS:
0037     void errorOccurred();
0038     void vblankOccurred(std::chrono::nanoseconds timestamp);
0039 
0040 private:
0041     ::Display *m_display = nullptr;
0042     ::Window m_dummyWindow = 0;
0043     GLXContext m_localContext = 0;
0044     GLXDrawable m_drawable = 0;
0045 };
0046 
0047 /**
0048  * The SGIVideoSyncVsyncMonitor class monitors vblank events using the GLX_SGI_video_sync
0049  * extension.
0050  *
0051  * Vblank events are monitored in a separated thread to avoid blocking the main thread. In
0052  * order to avoid locking up the main X11 connection, the worker thread establishes its own
0053  * X11 connection.
0054  */
0055 class SGIVideoSyncVsyncMonitor : public VsyncMonitor
0056 {
0057     Q_OBJECT
0058 
0059 public:
0060     static std::unique_ptr<SGIVideoSyncVsyncMonitor> create();
0061     ~SGIVideoSyncVsyncMonitor() override;
0062 
0063     bool isValid() const;
0064 
0065 public Q_SLOTS:
0066     void arm() override;
0067 
0068 private:
0069     explicit SGIVideoSyncVsyncMonitor();
0070 
0071     QThread m_thread;
0072     SGIVideoSyncVsyncMonitorHelper m_helper;
0073 };
0074 
0075 } // namespace KWin