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 #pragma once
0011 
0012 #include <kwin_export.h>
0013 #include <xcb/xcb.h>
0014 
0015 #include <QHash>
0016 #include <QObject>
0017 #include <QRegion>
0018 #include <QTimer>
0019 #include <memory>
0020 
0021 namespace KWin
0022 {
0023 
0024 class Output;
0025 class CursorScene;
0026 class RenderBackend;
0027 class RenderLayer;
0028 class RenderLoop;
0029 class RenderTarget;
0030 class WorkspaceScene;
0031 class Window;
0032 class OutputFrame;
0033 
0034 class KWIN_EXPORT Compositor : public QObject
0035 {
0036     Q_OBJECT
0037 public:
0038     enum class State {
0039         On = 0,
0040         Off,
0041         Starting,
0042         Stopping
0043     };
0044 
0045     ~Compositor() override;
0046     static Compositor *self();
0047 
0048     /**
0049      * Re-initializes the Compositor completely.
0050      * Connected to the D-Bus signal org.kde.KWin /KWin reinitCompositing
0051      */
0052     virtual void reinitialize();
0053 
0054     /**
0055      * Whether the Compositor is active. That is a Scene is present and the Compositor is
0056      * not shutting down itself.
0057      */
0058     bool isActive();
0059 
0060     WorkspaceScene *scene() const
0061     {
0062         return m_scene.get();
0063     }
0064     CursorScene *cursorScene() const
0065     {
0066         return m_cursorScene.get();
0067     }
0068     RenderBackend *backend() const
0069     {
0070         return m_backend.get();
0071     }
0072 
0073     /**
0074      * @brief Static check to test whether the Compositor is available and active.
0075      *
0076      * @return bool @c true if there is a Compositor and it is active, @c false otherwise
0077      */
0078     static bool compositing()
0079     {
0080         return s_compositor != nullptr && s_compositor->isActive();
0081     }
0082 
0083     // for delayed supportproperty management of effects
0084     void keepSupportProperty(xcb_atom_t atom);
0085     void removeSupportProperty(xcb_atom_t atom);
0086 
0087     /**
0088      * Whether Compositing is possible in the Platform.
0089      * Returning @c false in this method makes only sense if requiresCompositing returns @c false.
0090      *
0091      * The default implementation returns @c true.
0092      * @see requiresCompositing
0093      */
0094     virtual bool compositingPossible() const;
0095     /**
0096      * Returns a user facing text explaining why compositing is not possible in case
0097      * compositingPossible returns @c false.
0098      *
0099      * The default implementation returns an empty string.
0100      * @see compositingPossible
0101      */
0102     virtual QString compositingNotPossibleReason() const;
0103     /**
0104      * Whether OpenGL compositing is broken.
0105      * The Platform can implement this method if it is able to detect whether OpenGL compositing
0106      * broke (e.g. triggered a crash in a previous run).
0107      *
0108      * Default implementation returns @c false.
0109      * @see createOpenGLSafePoint
0110      */
0111     virtual bool openGLCompositingIsBroken() const;
0112 
0113     virtual void inhibit(Window *window);
0114     virtual void uninhibit(Window *window);
0115 
0116 Q_SIGNALS:
0117     void compositingToggled(bool active);
0118     void aboutToDestroy();
0119     void aboutToToggleCompositing();
0120     void sceneCreated();
0121 
0122 protected:
0123     explicit Compositor(QObject *parent = nullptr);
0124 
0125     virtual void start() = 0;
0126     virtual void stop() = 0;
0127 
0128     static Compositor *s_compositor;
0129 
0130 protected Q_SLOTS:
0131     virtual void composite(RenderLoop *renderLoop);
0132 
0133 private Q_SLOTS:
0134     void handleFrameRequested(RenderLoop *renderLoop);
0135 
0136 protected:
0137     void deleteUnusedSupportProperties();
0138 
0139     Output *findOutput(RenderLoop *loop) const;
0140 
0141     void addSuperLayer(RenderLayer *layer);
0142     void removeSuperLayer(RenderLayer *layer);
0143 
0144     void prePaintPass(RenderLayer *layer, QRegion *damage);
0145     void postPaintPass(RenderLayer *layer);
0146     void paintPass(RenderLayer *layer, const RenderTarget &renderTarget, const QRegion &region);
0147     void framePass(RenderLayer *layer, OutputFrame *frame);
0148 
0149     State m_state = State::Off;
0150     QList<xcb_atom_t> m_unusedSupportProperties;
0151     QTimer m_unusedSupportPropertyTimer;
0152     std::unique_ptr<WorkspaceScene> m_scene;
0153     std::unique_ptr<CursorScene> m_cursorScene;
0154     std::unique_ptr<RenderBackend> m_backend;
0155     QHash<RenderLoop *, RenderLayer *> m_superlayers;
0156 };
0157 
0158 } // namespace KWin