effects/invert: Port to OffscreenEffect

Allows us to drop WindowPaintData.shader and to encapsulate rendering of
windows, which is needed to provide YUV->RGB conversion path.
This commit is contained in:
Vlad Zahorodnii 2022-06-10 22:43:06 +03:00
parent 69859aec28
commit 4363b25b2d
2 changed files with 47 additions and 22 deletions

View file

@ -58,6 +58,7 @@ InvertEffect::InvertEffect()
KGlobalAccel::self()->setShortcut(c, QList<QKeySequence>()); KGlobalAccel::self()->setShortcut(c, QList<QKeySequence>());
connect(c, &QAction::triggered, this, &InvertEffect::toggleScreenInversion); connect(c, &QAction::triggered, this, &InvertEffect::toggleScreenInversion);
connect(effects, &EffectsHandler::windowAdded, this, &InvertEffect::slotWindowAdded);
connect(effects, &EffectsHandler::windowClosed, this, &InvertEffect::slotWindowClosed); connect(effects, &EffectsHandler::windowClosed, this, &InvertEffect::slotWindowClosed);
} }
@ -68,6 +69,26 @@ bool InvertEffect::supported()
return effects->compositingType() == OpenGLCompositing; return effects->compositingType() == OpenGLCompositing;
} }
bool InvertEffect::isInvertable(EffectWindow *window) const
{
return m_allWindows != m_windows.contains(window);
}
void InvertEffect::invert(EffectWindow *window)
{
if (m_valid && !m_inited) {
m_valid = loadData();
}
redirect(window);
setShader(window, m_shader.get());
}
void InvertEffect::uninvert(EffectWindow *window)
{
unredirect(window);
}
bool InvertEffect::loadData() bool InvertEffect::loadData()
{ {
ensureResources(); ensureResources();
@ -82,25 +103,10 @@ bool InvertEffect::loadData()
return true; return true;
} }
void InvertEffect::drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) void InvertEffect::slotWindowAdded(KWin::EffectWindow *w)
{ {
// Load if we haven't already if (isInvertable(w)) {
if (m_valid && !m_inited) { invert(w);
m_valid = loadData();
}
bool useShader = m_valid && (m_allWindows != m_windows.contains(w));
if (useShader) {
ShaderManager *shaderManager = ShaderManager::instance();
shaderManager->pushShader(m_shader.get());
data.shader = m_shader.get();
}
effects->drawWindow(w, mask, region, data);
if (useShader) {
ShaderManager::instance()->popShader();
} }
} }
@ -112,6 +118,16 @@ void InvertEffect::slotWindowClosed(EffectWindow *w)
void InvertEffect::toggleScreenInversion() void InvertEffect::toggleScreenInversion()
{ {
m_allWindows = !m_allWindows; m_allWindows = !m_allWindows;
const auto windows = effects->stackingOrder();
for (EffectWindow *window : windows) {
if (isInvertable(window)) {
invert(window);
} else {
uninvert(window);
}
}
effects->addRepaintFull(); effects->addRepaintFull();
} }
@ -125,6 +141,11 @@ void InvertEffect::toggleWindow()
} else { } else {
m_windows.removeOne(effects->activeWindow()); m_windows.removeOne(effects->activeWindow());
} }
if (isInvertable(effects->activeWindow())) {
invert(effects->activeWindow());
} else {
uninvert(effects->activeWindow());
}
effects->activeWindow()->addRepaintFull(); effects->activeWindow()->addRepaintFull();
} }

View file

@ -11,7 +11,7 @@
#ifndef KWIN_INVERT_H #ifndef KWIN_INVERT_H
#define KWIN_INVERT_H #define KWIN_INVERT_H
#include <kwineffects.h> #include <kwinoffscreeneffect.h>
namespace KWin namespace KWin
{ {
@ -21,17 +21,15 @@ class GLShader;
/** /**
* Inverts desktop's colors * Inverts desktop's colors
*/ */
class InvertEffect : public Effect class InvertEffect : public OffscreenEffect
{ {
Q_OBJECT Q_OBJECT
public: public:
InvertEffect(); InvertEffect();
~InvertEffect() override; ~InvertEffect() override;
void drawWindow(EffectWindow *w, int mask, const QRegion &region, WindowPaintData &data) override;
bool isActive() const override; bool isActive() const override;
bool provides(Feature) override; bool provides(Feature) override;
int requestedEffectChainPosition() const override; int requestedEffectChainPosition() const override;
static bool supported(); static bool supported();
@ -39,12 +37,18 @@ public:
public Q_SLOTS: public Q_SLOTS:
void toggleScreenInversion(); void toggleScreenInversion();
void toggleWindow(); void toggleWindow();
void slotWindowAdded(KWin::EffectWindow *w);
void slotWindowClosed(KWin::EffectWindow *w); void slotWindowClosed(KWin::EffectWindow *w);
protected: protected:
bool loadData(); bool loadData();
private: private:
bool isInvertable(EffectWindow *window) const;
void invert(EffectWindow *window);
void uninvert(EffectWindow *window);
bool m_inited; bool m_inited;
bool m_valid; bool m_valid;
std::unique_ptr<GLShader> m_shader; std::unique_ptr<GLShader> m_shader;