File indexing completed on 2024-11-10 04:56:57

0001 /*
0002     SPDX-FileCopyrightText: 2010 Fredrik Höglund <fredrik@kde.org>
0003     SPDX-FileCopyrightText: 2014 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include "effect/effect.h"
0011 #include "opengl/glplatform.h"
0012 #include "opengl/glutils.h"
0013 
0014 #include <QList>
0015 #include <QVector2D>
0016 #include <unordered_map>
0017 
0018 namespace KWin
0019 {
0020 
0021 class ContrastManagerInterface;
0022 class ContrastShader;
0023 
0024 class ContrastEffect : public KWin::Effect
0025 {
0026     Q_OBJECT
0027 public:
0028     ContrastEffect();
0029     ~ContrastEffect() override;
0030 
0031     static bool supported();
0032     static bool enabledByDefault();
0033 
0034     static QMatrix4x4 colorMatrix(qreal contrast, qreal intensity, qreal saturation);
0035     void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) override;
0036 
0037     bool provides(Feature feature) override;
0038     bool isActive() const override;
0039 
0040     int requestedEffectChainPosition() const override
0041     {
0042         return 21;
0043     }
0044 
0045     bool eventFilter(QObject *watched, QEvent *event) override;
0046 
0047     bool blocksDirectScanout() const override;
0048 
0049 public Q_SLOTS:
0050     void slotWindowAdded(KWin::EffectWindow *w);
0051     void slotWindowDeleted(KWin::EffectWindow *w);
0052     void slotPropertyNotify(KWin::EffectWindow *w, long atom);
0053     void slotScreenGeometryChanged();
0054 
0055 private:
0056     QRegion contrastRegion(const EffectWindow *w) const;
0057     bool shouldContrast(const EffectWindow *w, int mask, const WindowPaintData &data) const;
0058     void updateContrastRegion(EffectWindow *w);
0059     void doContrast(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, const QRegion &shape, const QRect &screen, const float opacity, const QMatrix4x4 &screenProjection);
0060     void uploadRegion(std::span<QVector2D> map, const QRegion &region, qreal scale);
0061     Q_REQUIRED_RESULT bool uploadGeometry(GLVertexBuffer *vbo, const QRegion &region, qreal scale);
0062 
0063 private:
0064     std::unique_ptr<ContrastShader> m_shader;
0065     long m_net_wm_contrast_region = 0;
0066     QHash<const EffectWindow *, QMetaObject::Connection> m_contrastChangedConnections; // used only in Wayland to keep track of effect changed
0067     struct Data
0068     {
0069         QMatrix4x4 colorMatrix;
0070         QRegion contrastRegion;
0071         std::unique_ptr<GLTexture> texture;
0072         std::unique_ptr<GLFramebuffer> fbo;
0073     };
0074     std::unordered_map<const EffectWindow *, Data> m_windowData;
0075     static ContrastManagerInterface *s_contrastManager;
0076     static QTimer *s_contrastManagerRemoveTimer;
0077 };
0078 
0079 inline bool ContrastEffect::provides(Effect::Feature feature)
0080 {
0081     if (feature == Contrast) {
0082         return true;
0083     }
0084     return KWin::Effect::provides(feature);
0085 }
0086 
0087 } // namespace KWin