/* SPDX-FileCopyrightText: 2010 Fredrik Höglund SPDX-FileCopyrightText: 2018 Alex Nemeth SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "effect/effect.h" #include "opengl/glutils.h" #include "window.h" #include #include #include #include #include namespace KWin { class BlurManagerInterface; struct BlurRenderData { /// Temporary render targets needed for the Dual Kawase algorithm, the first texture /// contains not blurred background behind the window, it's cached. std::vector> textures; std::vector> framebuffers; }; struct BlurEffectData { /// The region that should be blurred behind the window std::optional content; /// The region that should be blurred behind the frame std::optional frame; /// The render data per screen. Screens can have different color spaces. std::unordered_map render; }; class BlurEffect : public KWin::Effect { Q_OBJECT public: BlurEffect(); ~BlurEffect() override; static bool supported(); static bool enabledByDefault(); void reconfigure(ReconfigureFlags flags) override; void prePaintScreen(ScreenPrePaintData &data, std::chrono::milliseconds presentTime) override; void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::chrono::milliseconds presentTime) override; void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data) override; bool provides(Feature feature) override; bool isActive() const override; int requestedEffectChainPosition() const override { return 20; } bool eventFilter(QObject *watched, QEvent *event) override; bool blocksDirectScanout() const override; public Q_SLOTS: void slotWindowAdded(KWin::EffectWindow *w); void slotWindowDeleted(KWin::EffectWindow *w); void slotScreenRemoved(KWin::Output *screen); void slotPropertyNotify(KWin::EffectWindow *w, long atom); void setupDecorationConnections(EffectWindow *w); private: void initBlurStrengthValues(); QRegion blurRegion(EffectWindow *w, bool noRoundedCorners = false) const; QRegion decorationBlurRegion(const EffectWindow *w) const; bool decorationSupportsBlurBehind(const EffectWindow *w) const; bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const; bool shouldForceBlur(const EffectWindow *w) const; void updateBlurRegion(EffectWindow *w); void blur(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data); void ensureReflectTexture(); bool readMemory(bool* skipFunc); bool treatAsActive(const EffectWindow *w); private: struct { std::unique_ptr shader; std::unique_ptr reflectTexture; int mvpMatrixLocation; int screenResolutionLocation; int windowPosLocation; int windowSizeLocation; int opacityLocation; int translateTextureLocation; } m_reflectPass; struct { std::unique_ptr shader; int mvpMatrixLocation; int offsetLocation; int halfpixelLocation; } m_downsamplePass; struct { std::unique_ptr shader; int mvpMatrixLocation; int offsetLocation; int halfpixelLocation; int basicColorizationLocation; int aeroColorRLocation; int aeroColorGLocation; int aeroColorBLocation; int aeroColorALocation; int aeroColorBalanceLocation; int aeroAfterglowBalanceLocation; int aeroBlurBalanceLocation; int aeroColorizeLocation; } m_upsamplePass; bool m_valid = false; long net_wm_blur_region = 0; QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top) QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top) Output *m_currentScreen = nullptr; size_t m_iterationCount; // number of times the texture will be downsized to half size int m_offset; int m_expandSize; QStringList m_windowClasses; QStringList m_windowClassesColorization; bool m_blurMatching; bool m_blurNonMatching; bool m_blurMenus; bool m_blurDocks; bool m_paintAsTranslucent; QString m_texturePath; bool m_translateTexture; bool m_firstTimeConfig; int m_aeroIntensity; int m_aeroHue; int m_aeroSaturation; int m_aeroBrightness; float m_aeroColorR; float m_aeroColorG; float m_aeroColorB; float m_aeroColorA; int m_aeroPrimaryBalance; int m_aeroSecondaryBalance; int m_aeroBlurBalance; int m_aeroPrimaryBalanceInactive; int m_aeroBlurBalanceInactive; bool m_transparencyEnabled; bool m_basicColorization; struct OffsetStruct { float minOffset; float maxOffset; int expandSize; }; QList blurOffsets; struct BlurValuesStruct { int iteration; float offset; }; QList blurStrengthValues; QMap windowBlurChangedConnections; QMap windowExpandedGeometryChangedConnections; std::unordered_map m_windows; static BlurManagerInterface *s_blurManager; static QTimer *s_blurManagerRemoveTimer; QSharedMemory m_sharedMemory; }; inline bool BlurEffect::provides(Effect::Feature feature) { if (feature == Blur) { return true; } return KWin::Effect::provides(feature); } } // namespace KWin