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 ®ion, 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"