File indexing completed on 2024-05-12 05:31:30

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "effect/effect.h"
0010 #include "scene/itemgeometry.h"
0011 
0012 namespace KWin
0013 {
0014 
0015 class GLShader;
0016 class OffscreenEffectPrivate;
0017 class CrossFadeEffectPrivate;
0018 class ShaderEffectPrivate;
0019 
0020 /**
0021  * The OffscreenEffect class is the base class for effects that paint deformed windows.
0022  *
0023  * Under the hood, the OffscreenEffect will paint the window into an offscreen texture
0024  * and the offscreen texture will be transformed afterwards.
0025  *
0026  * The redirect() function must be called when the effect wants to transform a window.
0027  * Once the effect is no longer interested in the window, the unredirect() function
0028  * must be called.
0029  *
0030  * If a window is redirected into offscreen texture, the deform() function will be
0031  * called to transform the offscreen texture.
0032  */
0033 class KWIN_EXPORT OffscreenEffect : public Effect
0034 {
0035     Q_OBJECT
0036 
0037 public:
0038     explicit OffscreenEffect(QObject *parent = nullptr);
0039     ~OffscreenEffect() override;
0040 
0041     static bool supported();
0042 
0043 protected:
0044     void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const QRegion &region, WindowPaintData &data) override;
0045 
0046     /**
0047      * This function must be called when the effect wants to animate the specified
0048      * @a window.
0049      */
0050     void redirect(EffectWindow *window);
0051     /**
0052      * This function must be called when the effect is done animating the specified
0053      * @a window. The window will be automatically unredirected if it's deleted.
0054      */
0055     void unredirect(EffectWindow *window);
0056 
0057     /**
0058      * Override this function to transform the window.
0059      */
0060     virtual void apply(EffectWindow *window, int mask, WindowPaintData &data, WindowQuadList &quads);
0061 
0062     /**
0063      * Allows to specify a @p shader to draw the redirected texture for @p window.
0064      * Can only be called once the window is redirected.
0065      **/
0066     void setShader(EffectWindow *window, GLShader *shader);
0067 
0068     /**
0069      * Set what mode to use to snap the vertices of this effect.
0070      *
0071      * @see RenderGeometry::VertexSnappingMode
0072      */
0073     void setVertexSnappingMode(RenderGeometry::VertexSnappingMode mode);
0074 
0075 private Q_SLOTS:
0076     void handleWindowDamaged(EffectWindow *window);
0077     void handleWindowDeleted(EffectWindow *window);
0078 
0079 private:
0080     void setupConnections();
0081     void destroyConnections();
0082 
0083     std::unique_ptr<OffscreenEffectPrivate> d;
0084 };
0085 
0086 /**
0087  * The CrossFadeEffect class is the base class for effects that paints crossfades
0088  *
0089  * Windows are snapshotted at the time we want to start crossfading from. Hereafter we draw both the new contents
0090  * and the old pixmap at the ratio defined by WindowPaintData::crossFadeProgress
0091  *
0092  * Subclasses are responsible for driving the animation and calling unredirect after animation completes.
0093  *
0094  * If window geometry changes shape after this point our "old" pixmap is resized to fit approximately matching
0095  * frame geometry
0096  */
0097 class KWIN_EXPORT CrossFadeEffect : public Effect
0098 {
0099     Q_OBJECT
0100 public:
0101     explicit CrossFadeEffect(QObject *parent = nullptr);
0102     ~CrossFadeEffect() override;
0103 
0104     void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const QRegion &region, WindowPaintData &data) override;
0105 
0106     /**
0107      * This function must be called when the effect wants to animate the specified
0108      * @a window.
0109      */
0110     void redirect(EffectWindow *window);
0111     /**
0112      * This function must be called when the effect is done animating the specified
0113      * @a window. The window will be automatically unredirected if it's deleted.
0114      */
0115     void unredirect(EffectWindow *window);
0116 
0117     /**
0118      * Allows to specify a @p shader to draw the redirected texture for @p window.
0119      * Can only be called once the window is redirected.
0120      * @since 5.25
0121      **/
0122     void setShader(EffectWindow *window, GLShader *shader);
0123 
0124     static bool supported();
0125 
0126 private:
0127     void handleWindowDeleted(EffectWindow *window);
0128     std::unique_ptr<CrossFadeEffectPrivate> d;
0129 };
0130 
0131 } // namespace KWin