File indexing completed on 2024-06-09 05:25:54
0001 /* 0002 SPDX-FileCopyrightText: 2010 Fredrik Höglund <fredrik@kde.org> 0003 SPDX-FileCopyrightText: 2018 Alex Nemeth <alex.nemeth329@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include "effect/effect.h" 0011 #include "opengl/glutils.h" 0012 0013 #include <QList> 0014 0015 #include <unordered_map> 0016 0017 namespace KWin 0018 { 0019 0020 class BlurManagerInterface; 0021 0022 struct BlurRenderData 0023 { 0024 /// Temporary render targets needed for the Dual Kawase algorithm, the first texture 0025 /// contains not blurred background behind the window, it's cached. 0026 std::vector<std::unique_ptr<GLTexture>> textures; 0027 std::vector<std::unique_ptr<GLFramebuffer>> framebuffers; 0028 }; 0029 0030 struct BlurEffectData 0031 { 0032 /// The region that should be blurred behind the window 0033 std::optional<QRegion> content; 0034 0035 /// The region that should be blurred behind the frame 0036 std::optional<QRegion> frame; 0037 0038 /// The render data per screen. Screens can have different color spaces. 0039 std::unordered_map<Output *, BlurRenderData> render; 0040 }; 0041 0042 class BlurEffect : public KWin::Effect 0043 { 0044 Q_OBJECT 0045 0046 public: 0047 BlurEffect(); 0048 ~BlurEffect() override; 0049 0050 static bool supported(); 0051 static bool enabledByDefault(); 0052 0053 void reconfigure(ReconfigureFlags flags) override; 0054 void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; 0055 void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; 0056 void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override; 0057 0058 bool provides(Feature feature) override; 0059 bool isActive() const override; 0060 0061 int requestedEffectChainPosition() const override 0062 { 0063 return 20; 0064 } 0065 0066 bool eventFilter(QObject *watched, QEvent *event) override; 0067 0068 bool blocksDirectScanout() const override; 0069 0070 public Q_SLOTS: 0071 void slotWindowAdded(KWin::EffectWindow *w); 0072 void slotWindowDeleted(KWin::EffectWindow *w); 0073 void slotScreenRemoved(KWin::Output *screen); 0074 void slotPropertyNotify(KWin::EffectWindow *w, long atom); 0075 void setupDecorationConnections(EffectWindow *w); 0076 0077 private: 0078 void initBlurStrengthValues(); 0079 QRegion blurRegion(EffectWindow *w) const; 0080 QRegion decorationBlurRegion(const EffectWindow *w) const; 0081 bool decorationSupportsBlurBehind(const EffectWindow *w) const; 0082 bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const; 0083 void updateBlurRegion(EffectWindow *w); 0084 void blur(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data); 0085 GLTexture *ensureNoiseTexture(); 0086 0087 private: 0088 struct 0089 { 0090 std::unique_ptr<GLShader> shader; 0091 int mvpMatrixLocation; 0092 int offsetLocation; 0093 int halfpixelLocation; 0094 } m_downsamplePass; 0095 0096 struct 0097 { 0098 std::unique_ptr<GLShader> shader; 0099 int mvpMatrixLocation; 0100 int offsetLocation; 0101 int halfpixelLocation; 0102 } m_upsamplePass; 0103 0104 struct 0105 { 0106 std::unique_ptr<GLShader> shader; 0107 int mvpMatrixLocation; 0108 int noiseTextureSizeLocation; 0109 int texStartPosLocation; 0110 0111 std::unique_ptr<GLTexture> noiseTexture; 0112 qreal noiseTextureScale = 1.0; 0113 int noiseTextureStength = 0; 0114 } m_noisePass; 0115 0116 bool m_valid = false; 0117 long net_wm_blur_region = 0; 0118 QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top) 0119 QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top) 0120 Output *m_currentScreen = nullptr; 0121 0122 size_t m_iterationCount; // number of times the texture will be downsized to half size 0123 int m_offset; 0124 int m_expandSize; 0125 int m_noiseStrength; 0126 0127 struct OffsetStruct 0128 { 0129 float minOffset; 0130 float maxOffset; 0131 int expandSize; 0132 }; 0133 0134 QList<OffsetStruct> blurOffsets; 0135 0136 struct BlurValuesStruct 0137 { 0138 int iteration; 0139 float offset; 0140 }; 0141 0142 QList<BlurValuesStruct> blurStrengthValues; 0143 0144 QMap<EffectWindow *, QMetaObject::Connection> windowBlurChangedConnections; 0145 std::unordered_map<EffectWindow *, BlurEffectData> m_windows; 0146 0147 static BlurManagerInterface *s_blurManager; 0148 static QTimer *s_blurManagerRemoveTimer; 0149 }; 0150 0151 inline bool BlurEffect::provides(Effect::Feature feature) 0152 { 0153 if (feature == Blur) { 0154 return true; 0155 } 0156 return KWin::Effect::provides(feature); 0157 } 0158 0159 } // namespace KWin