File indexing completed on 2024-05-19 16:34:48

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "scene/scene.h"
0013 
0014 #include "kwineffects.h"
0015 #include "utils/common.h"
0016 #include "window.h"
0017 
0018 #include <optional>
0019 
0020 #include <QElapsedTimer>
0021 #include <QMatrix4x4>
0022 
0023 namespace KWin
0024 {
0025 
0026 namespace Decoration
0027 {
0028 class DecoratedClientImpl;
0029 }
0030 
0031 class DecorationRenderer;
0032 class Deleted;
0033 class DragAndDropIconItem;
0034 class EffectWindowImpl;
0035 class GLTexture;
0036 class Item;
0037 class RenderLoop;
0038 class WorkspaceScene;
0039 class Shadow;
0040 class ShadowItem;
0041 class SurfaceItem;
0042 class WindowItem;
0043 
0044 class KWIN_EXPORT WorkspaceScene : public Scene
0045 {
0046     Q_OBJECT
0047 
0048 public:
0049     explicit WorkspaceScene(std::unique_ptr<ItemRenderer> renderer);
0050     ~WorkspaceScene() override;
0051 
0052     void initialize();
0053 
0054     QRegion damage() const override;
0055     SurfaceItem *scanoutCandidate() const override;
0056     void prePaint(SceneDelegate *delegate) override;
0057     void postPaint() override;
0058     void paint(RenderTarget *renderTarget, const QRegion &region) override;
0059 
0060     /**
0061      * @brief Creates the Scene specific Shadow subclass.
0062      *
0063      * An implementing class has to create a proper instance. It is not allowed to
0064      * return @c null.
0065      *
0066      * @param window The Window for which the Shadow needs to be created.
0067      */
0068     virtual std::unique_ptr<Shadow> createShadow(Window *window) = 0;
0069 
0070     virtual bool makeOpenGLContextCurrent();
0071     virtual void doneOpenGLContextCurrent();
0072     virtual bool supportsNativeFence() const;
0073 
0074     virtual DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0;
0075 
0076     /**
0077      * Whether the Scene is able to drive animations.
0078      * This is used as a hint to the effects system which effects can be supported.
0079      * If the Scene performs software rendering it is supposed to return @c false,
0080      * if rendering is hardware accelerated it should return @c true.
0081      */
0082     virtual bool animationsSupported() const = 0;
0083 
0084     virtual std::shared_ptr<GLTexture> textureForOutput(Output *output) const
0085     {
0086         return {};
0087     }
0088 
0089 Q_SIGNALS:
0090     void preFrameRender();
0091     void frameRendered();
0092 
0093 protected:
0094     void createStackingOrder();
0095     void clearStackingOrder();
0096     friend class EffectsHandlerImpl;
0097     // called after all effects had their paintScreen() called
0098     void finalPaintScreen(int mask, const QRegion &region, ScreenPaintData &data);
0099     // shared implementation of painting the screen in the generic
0100     // (unoptimized) way
0101     void preparePaintGenericScreen();
0102     void paintGenericScreen(int mask, const ScreenPaintData &data);
0103     // shared implementation of painting the screen in an optimized way
0104     void preparePaintSimpleScreen();
0105     void paintSimpleScreen(int mask, const QRegion &region);
0106     // called after all effects had their paintWindow() called
0107     void finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data);
0108     // shared implementation, starts painting the window
0109     void paintWindow(WindowItem *w, int mask, const QRegion &region);
0110     // called after all effects had their drawWindow() called
0111     void finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion &region, WindowPaintData &data);
0112 
0113     // saved data for 2nd pass of optimized screen painting
0114     struct Phase2Data
0115     {
0116         WindowItem *item = nullptr;
0117         QRegion region;
0118         QRegion opaque;
0119         int mask = 0;
0120     };
0121 
0122     struct PaintContext
0123     {
0124         QRegion damage;
0125         int mask = 0;
0126         QVector<Phase2Data> phase2Data;
0127     };
0128 
0129     // The screen that is being currently painted
0130     Output *painted_screen = nullptr;
0131     SceneDelegate *painted_delegate = nullptr;
0132 
0133     // windows in their stacking order
0134     QVector<WindowItem *> stacking_order;
0135 
0136 private:
0137     void createDndIconItem();
0138     void destroyDndIconItem();
0139 
0140     std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
0141     // how many times finalPaintScreen() has been called
0142     int m_paintScreenCount = 0;
0143     PaintContext m_paintContext;
0144     std::unique_ptr<DragAndDropIconItem> m_dndIcon;
0145 };
0146 
0147 } // namespace