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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org>
0006     SPDX-FileCopyrightText: 2010 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "showpaint.h"
0012 
0013 #include "core/pixelgrid.h"
0014 #include "core/renderviewport.h"
0015 #include "effect/effecthandler.h"
0016 #include "opengl/glutils.h"
0017 
0018 #include <KGlobalAccel>
0019 #include <KLocalizedString>
0020 
0021 #include <QAction>
0022 #include <QPainter>
0023 
0024 namespace KWin
0025 {
0026 
0027 static const qreal s_alpha = 0.2;
0028 static const QList<QColor> s_colors{
0029     Qt::red,
0030     Qt::green,
0031     Qt::blue,
0032     Qt::cyan,
0033     Qt::magenta,
0034     Qt::yellow,
0035     Qt::gray};
0036 
0037 ShowPaintEffect::ShowPaintEffect()
0038 {
0039     auto *toggleAction = new QAction(this);
0040     toggleAction->setObjectName(QStringLiteral("Toggle"));
0041     toggleAction->setText(i18n("Toggle Show Paint"));
0042     KGlobalAccel::self()->setDefaultShortcut(toggleAction, {});
0043     KGlobalAccel::self()->setShortcut(toggleAction, {});
0044 
0045     connect(toggleAction, &QAction::triggered, this, &ShowPaintEffect::toggle);
0046 }
0047 
0048 void ShowPaintEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const QRegion &region, Output *screen)
0049 {
0050     m_painted = QRegion();
0051     effects->paintScreen(renderTarget, viewport, mask, region, screen);
0052     if (effects->isOpenGLCompositing()) {
0053         paintGL(viewport.projectionMatrix(), viewport.scale());
0054     } else if (effects->compositingType() == QPainterCompositing) {
0055         paintQPainter();
0056     }
0057     if (++m_colorIndex == s_colors.count()) {
0058         m_colorIndex = 0;
0059     }
0060 }
0061 
0062 void ShowPaintEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
0063 {
0064     m_painted += region;
0065     effects->paintWindow(renderTarget, viewport, w, mask, region, data);
0066 }
0067 
0068 void ShowPaintEffect::paintGL(const QMatrix4x4 &projection, qreal scale)
0069 {
0070     GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
0071     vbo->reset();
0072     ShaderBinder binder(ShaderTrait::UniformColor);
0073     binder.shader()->setUniform(GLShader::Mat4Uniform::ModelViewProjectionMatrix, projection);
0074     glEnable(GL_BLEND);
0075     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
0076     QColor color = s_colors[m_colorIndex];
0077     color.setAlphaF(s_alpha);
0078     binder.shader()->setUniform(GLShader::ColorUniform::Color, color);
0079     QList<QVector2D> verts;
0080     verts.reserve(m_painted.rectCount() * 12);
0081     for (const QRect &r : m_painted) {
0082         const auto deviceRect = snapToPixelGridF(scaledRect(r, scale));
0083         verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y()));
0084         verts.push_back(QVector2D(deviceRect.x(), deviceRect.y()));
0085         verts.push_back(QVector2D(deviceRect.x(), deviceRect.y() + deviceRect.height()));
0086         verts.push_back(QVector2D(deviceRect.x(), deviceRect.y() + deviceRect.height()));
0087         verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y() + deviceRect.height()));
0088         verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y()));
0089     }
0090     vbo->setVertices(verts);
0091     vbo->render(GL_TRIANGLES);
0092     glDisable(GL_BLEND);
0093 }
0094 
0095 void ShowPaintEffect::paintQPainter()
0096 {
0097     QColor color = s_colors[m_colorIndex];
0098     color.setAlphaF(s_alpha);
0099     for (const QRect &r : m_painted) {
0100         effects->scenePainter()->fillRect(r, color);
0101     }
0102 }
0103 
0104 bool ShowPaintEffect::isActive() const
0105 {
0106     return m_active;
0107 }
0108 
0109 void ShowPaintEffect::toggle()
0110 {
0111     m_active = !m_active;
0112     effects->addRepaintFull();
0113 }
0114 
0115 } // namespace KWin
0116 
0117 #include "moc_showpaint.cpp"