File indexing completed on 2024-04-28 05:30:13

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
0006     SPDX-FileCopyrightText: 2012 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #pragma once
0012 
0013 #include "compositor.h"
0014 #include <QSet>
0015 
0016 namespace KWin
0017 {
0018 
0019 class X11CompositorSelectionOwner;
0020 class X11SyncManager;
0021 class X11Window;
0022 
0023 class KWIN_EXPORT X11Compositor final : public Compositor
0024 {
0025     Q_OBJECT
0026 public:
0027     enum SuspendReason {
0028         NoReasonSuspend = 0,
0029         UserSuspend = 1 << 0,
0030         BlockRuleSuspend = 1 << 1,
0031         AllReasonSuspend = 0xff
0032     };
0033     Q_DECLARE_FLAGS(SuspendReasons, SuspendReason)
0034     Q_ENUM(SuspendReason)
0035     Q_FLAG(SuspendReasons)
0036 
0037     static X11Compositor *create(QObject *parent = nullptr);
0038     ~X11Compositor() override;
0039 
0040     X11SyncManager *syncManager() const;
0041 
0042     /**
0043      * Toggles compositing, that is if the Compositor is suspended it will be resumed
0044      * and if the Compositor is active it will be suspended.
0045      * Invoked by keybinding (shortcut default: Shift + Alt + F12).
0046      */
0047     void toggle();
0048 
0049     /**
0050      * @brief Suspends the Compositor if it is currently active.
0051      *
0052      * Note: it is possible that the Compositor is not able to suspend. Use isActive to check
0053      * whether the Compositor has been suspended.
0054      *
0055      * @return void
0056      * @see resume
0057      * @see isActive
0058      */
0059     void suspend(SuspendReason reason);
0060 
0061     /**
0062      * @brief Resumes the Compositor if it is currently suspended.
0063      *
0064      * Note: it is possible that the Compositor cannot be resumed, that is there might be Clients
0065      * blocking the usage of Compositing or the Scene might be broken. Use isActive to check
0066      * whether the Compositor has been resumed. Also check isCompositingPossible and
0067      * isOpenGLBroken.
0068      *
0069      * Note: The starting of the Compositor can require some time and is partially done threaded.
0070      * After this method returns the setup may not have been completed.
0071      *
0072      * @return void
0073      * @see suspend
0074      * @see isActive
0075      * @see isCompositingPossible
0076      * @see isOpenGLBroken
0077      */
0078     void resume(SuspendReason reason);
0079 
0080     enum class OpenGLSafePoint {
0081         PreInit,
0082         PostInit,
0083         PreFrame,
0084         PostFrame,
0085         PostLastGuardedFrame
0086     };
0087     /**
0088      * This method is invoked before and after creating the OpenGL rendering Scene.
0089      * An implementing Platform can use it to detect crashes triggered by the OpenGL implementation.
0090      * This can be used for openGLCompositingIsBroken.
0091      *
0092      * The default implementation does nothing.
0093      * @see openGLCompositingIsBroken.
0094      */
0095     void createOpenGLSafePoint(OpenGLSafePoint safePoint);
0096 
0097     void inhibit(Window *window) override;
0098     void uninhibit(Window *window) override;
0099 
0100     void reinitialize() override;
0101     bool compositingPossible() const override;
0102     QString compositingNotPossibleReason() const override;
0103     bool openGLCompositingIsBroken() const override;
0104 
0105     static X11Compositor *self();
0106 
0107 protected:
0108     void start() override;
0109     void stop() override;
0110     void composite(RenderLoop *renderLoop) override;
0111 
0112 private:
0113     explicit X11Compositor(QObject *parent);
0114 
0115     bool attemptOpenGLCompositing();
0116 
0117     void releaseCompositorSelection();
0118     void destroyCompositorSelection();
0119 
0120     std::unique_ptr<QThread> m_openGLFreezeProtectionThread;
0121     std::unique_ptr<QTimer> m_openGLFreezeProtection;
0122     std::unique_ptr<X11SyncManager> m_syncManager;
0123     std::unique_ptr<X11CompositorSelectionOwner> m_selectionOwner;
0124     QTimer m_releaseSelectionTimer;
0125     /**
0126      * Whether the Compositor is currently suspended, 8 bits encoding the reason
0127      */
0128     SuspendReasons m_suspended;
0129     QSet<Window *> m_inhibitors;
0130     int m_framesToTestForSafety = 3;
0131 };
0132 
0133 } // namespace KWin