diff --git a/src/effects.cpp b/src/effects.cpp index 32a6b37de0..d19841ec81 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -1895,6 +1895,11 @@ QRect EffectScreenImpl::geometry() const return m_platformOutput->geometry(); } +int EffectScreenImpl::refreshRate() const +{ + return m_platformOutput->refreshRate(); +} + EffectScreen::Transform EffectScreenImpl::transform() const { return EffectScreen::Transform(m_platformOutput->transform()); diff --git a/src/effects.h b/src/effects.h index db27189698..783043c551 100644 --- a/src/effects.h +++ b/src/effects.h @@ -390,6 +390,7 @@ public: QString name() const override; qreal devicePixelRatio() const override; QRect geometry() const override; + int refreshRate() const override; Transform transform() const override; static EffectScreenImpl *get(AbstractOutput *output); diff --git a/src/effects/showfps/showfps.cpp b/src/effects/showfps/showfps.cpp index 806e89957b..3015305690 100644 --- a/src/effects/showfps/showfps.cpp +++ b/src/effects/showfps/showfps.cpp @@ -47,8 +47,10 @@ ShowFpsEffect::ShowFpsEffect() ++i) { frames[i] = 0; } - m_noBenchmark->setAlignment(Qt::AlignTop | Qt::AlignRight); - m_noBenchmark->setText(i18n("This effect is not a benchmark")); + if (m_showNoBenchmark) { + m_noBenchmark->setAlignment(Qt::AlignTop | Qt::AlignRight); + m_noBenchmark->setText(i18n("This effect is not a benchmark")); + } reconfigure(ReconfigureAll); } @@ -62,6 +64,9 @@ void ShowFpsEffect::reconfigure(ReconfigureFlags) alpha = ShowFpsConfig::alpha(); x = ShowFpsConfig::x(); y = ShowFpsConfig::y(); + m_showNoBenchmark = ShowFpsConfig::showNoBenchmark(); + m_showGraph = ShowFpsConfig::showGraph(); + m_colorizeText = ShowFpsConfig::colorizeText(); const QSize screenSize = effects->virtualScreenSize(); if (x == -10000) { // there's no -0 :( x = screenSize.width() - 2 * NUM_PAINTS - FPS_WIDTH; @@ -125,6 +130,14 @@ void ShowFpsEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::millis paint_size[paints_pos] = 0; t.restart(); + + // detect highest monitor refresh rate + int num_screens = effects->screens().size(); + detectedMaxFps = 0; + for (int i = 0; i < num_screens; ++i) { + detectedMaxFps = std::max(effects->screens().at(i)->refreshRate(), detectedMaxFps); + } + detectedMaxFps /= 1000; // convert mHz to Hz (see kwineffects.h: EffectScreen) } void ShowFpsEffect::paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) @@ -158,16 +171,15 @@ void ShowFpsEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData ++fps; // count all frames in the last second } } - if (fps > MAX_TIME) { - fps = MAX_TIME; // keep it the same height - } if (effects->isOpenGLCompositing()) { paintGL(fps, data.projectionMatrix()); glFinish(); // make sure all rendering is done } else if (effects->compositingType() == QPainterCompositing) { paintQPainter(fps); } - m_noBenchmark->render(infiniteRegion(), 1.0, alpha); + if (m_showNoBenchmark) { + m_noBenchmark->render(infiniteRegion(), 1.0, alpha); + } } void ShowFpsEffect::paintGL(int fps, const QMatrix4x4 &projectionMatrix) @@ -180,54 +192,54 @@ void ShowFpsEffect::paintGL(int fps, const QMatrix4x4 &projectionMatrix) // means that the contents also blend with the background, I guess ShaderBinder binder(ShaderTrait::UniformColor); binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, projectionMatrix); - GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); - vbo->reset(); - QColor color(255, 255, 255); - color.setAlphaF(alpha); - vbo->setColor(color); - QVector verts; - verts.reserve(12); - verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y; - verts << x << y; - verts << x << y + MAX_TIME; - verts << x << y + MAX_TIME; - verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y + MAX_TIME; - verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y; - vbo->setData(6, 2, verts.constData(), nullptr); - vbo->render(GL_TRIANGLES); - y += MAX_TIME; // paint up from the bottom - color.setRed(0); - color.setGreen(0); - vbo->setColor(color); - verts.clear(); - verts << x + FPS_WIDTH << y - fps; - verts << x << y - fps; - verts << x << y; - verts << x << y; - verts << x + FPS_WIDTH << y; - verts << x + FPS_WIDTH << y - fps; - vbo->setData(6, 2, verts.constData(), nullptr); - vbo->render(GL_TRIANGLES); + if (m_showGraph) { + GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); + vbo->reset(); + QColor color(255, 255, 255); + color.setAlphaF(alpha); + vbo->setColor(color); + QVector verts; + verts.reserve(12); + verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y; + verts << x << y; + verts << x << y + MAX_TIME; + verts << x << y + MAX_TIME; + verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y + MAX_TIME; + verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y; + vbo->setData(6, 2, verts.constData(), nullptr); + vbo->render(GL_TRIANGLES); + y += MAX_TIME; // paint up from the bottom + color.setRed(0); + color.setGreen(0); + vbo->setColor(color); + verts.clear(); + verts << x + FPS_WIDTH << y - fps; + verts << x << y - fps; + verts << x << y; + verts << x << y; + verts << x + FPS_WIDTH << y; + verts << x + FPS_WIDTH << y - fps; + vbo->setData(6, 2, verts.constData(), nullptr); + vbo->render(GL_TRIANGLES); - color.setBlue(0); - vbo->setColor(color); - QVector vertices; - for (int i = 10; - i < MAX_TIME; - i += 10) { - vertices << x << y - i; - vertices << x + FPS_WIDTH << y - i; + color.setBlue(0); + vbo->setColor(color); + QVector vertices; + for (int i = 10; i < MAX_TIME; i += 10) { + vertices << x << y - i; + vertices << x + FPS_WIDTH << y - i; + } + vbo->setData(vertices.size() / 2, 2, vertices.constData(), nullptr); + vbo->render(GL_LINES); + x += FPS_WIDTH; + + // Paint FPS graph + paintFPSGraph(x, y); + x += NUM_PAINTS; + + // Paint amount of rendered pixels graph + paintDrawSizeGraph(x, y); } - vbo->setData(vertices.size() / 2, 2, vertices.constData(), nullptr); - vbo->render(GL_LINES); - x += FPS_WIDTH; - - // Paint FPS graph - paintFPSGraph(x, y); - x += NUM_PAINTS; - - // Paint amount of rendered pixels graph - paintDrawSizeGraph(x, y); // Paint FPS numerical value if (fpsTextRect.isValid()) { @@ -251,27 +263,29 @@ void ShowFpsEffect::paintQPainter(int fps) QPainter *painter = effects->scenePainter(); painter->save(); - QColor color(255, 255, 255); - color.setAlphaF(alpha); + if (m_showGraph) { + QColor color(255, 255, 255); + color.setAlphaF(alpha); - painter->setCompositionMode(QPainter::CompositionMode_SourceOver); - painter->fillRect(x, y, 2 * NUM_PAINTS + FPS_WIDTH, MAX_TIME, color); - color.setRed(0); - color.setGreen(0); - painter->fillRect(x, y + MAX_TIME - fps, FPS_WIDTH, fps, color); + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + painter->fillRect(x, y, 2 * NUM_PAINTS + FPS_WIDTH, MAX_TIME, color); + color.setRed(0); + color.setGreen(0); + painter->fillRect(x, y + MAX_TIME - fps, FPS_WIDTH, fps, color); - color.setBlue(0); - for (int i = 10; i < MAX_TIME; i += 10) { - painter->setPen(color); - painter->drawLine(x, y + MAX_TIME - i, x + FPS_WIDTH, y + MAX_TIME - i); + color.setBlue(0); + for (int i = 10; i < MAX_TIME; i += 10) { + painter->setPen(color); + painter->drawLine(x, y + MAX_TIME - i, x + FPS_WIDTH, y + MAX_TIME - i); + } + + // Paint FPS graph + paintFPSGraph(x + FPS_WIDTH, y + MAX_TIME - 1); + + // Paint amount of rendered pixels graph + paintDrawSizeGraph(x + FPS_WIDTH + NUM_PAINTS, y + MAX_TIME - 1); } - // Paint FPS graph - paintFPSGraph(x + FPS_WIDTH, y + MAX_TIME - 1); - - // Paint amount of rendered pixels graph - paintDrawSizeGraph(x + FPS_WIDTH + NUM_PAINTS, y + MAX_TIME - 1); - // Paint FPS numerical value painter->setPen(Qt::black); painter->drawText(fpsTextRect, textAlign, QString::number(fps)); @@ -417,7 +431,22 @@ QImage ShowFpsEffect::fpsTextImage(int fps) im.fill(Qt::transparent); QPainter painter(&im); painter.setFont(textFont); - painter.setPen(textColor); + QColor col = textColor; + if (detectedMaxFps > 0) { + fps = std::min(fps, detectedMaxFps); + } + if (m_colorizeText) { + if (fps >= detectedMaxFps * 0.75) { + col = QColor(0, 255, 0); // green + } else if (fps >= detectedMaxFps * 0.5) { + col = QColor(255, 255, 0); // yellow + } else if (fps >= detectedMaxFps * 0.25) { + col = QColor(255, 0, 0); // red + } else { + col = QColor(0, 0, 0); // black + } + } + painter.setPen(col); painter.drawText(QRect(0, 0, 100, 100), textAlign, QString::number(fps)); painter.end(); return im; diff --git a/src/effects/showfps/showfps.h b/src/effects/showfps/showfps.h index 6ca2b0bd90..5cf46af05f 100644 --- a/src/effects/showfps/showfps.h +++ b/src/effects/showfps/showfps.h @@ -30,6 +30,9 @@ class ShowFpsEffect Q_PROPERTY(int textAlign READ configuredTextAlign) Q_PROPERTY(QFont textFont READ configuredTextFont) Q_PROPERTY(QColor textColor READ configuredTextColor) + Q_PROPERTY(bool showGraph READ configuredShowGraph) + Q_PROPERTY(bool showNoBenchmark READ configuredShowNoBenchmark) + Q_PROPERTY(bool colorizeText READ configuredColorizeText) public: ShowFpsEffect(); ~ShowFpsEffect() override; @@ -77,6 +80,18 @@ public: { return textColor; } + bool configuredShowGraph() const + { + return m_showGraph; + } + bool configuredShowNoBenchmark() const + { + return m_showNoBenchmark; + } + bool configuredColorizeText() const + { + return m_colorizeText; + } private: void paintGL(int fps, const QMatrix4x4 &projectionMatrix); @@ -98,6 +113,10 @@ private: qint64 frames[MAX_FPS]; // the time when the frame was done int frames_pos; // position in the queue double alpha; + bool m_showNoBenchmark; + bool m_showGraph; + bool m_colorizeText; + int detectedMaxFps; int x; int y; QRect fps_rect; diff --git a/src/effects/showfps/showfps.kcfg b/src/effects/showfps/showfps.kcfg index b0cd4633b9..71cec6e2b2 100644 --- a/src/effects/showfps/showfps.kcfg +++ b/src/effects/showfps/showfps.kcfg @@ -24,5 +24,14 @@ 0 + + true + + + true + + + true + diff --git a/src/effects/showfps/showfps_config.ui b/src/effects/showfps/showfps_config.ui index 8fbd5f79df..65db6acf39 100644 --- a/src/effects/showfps/showfps_config.ui +++ b/src/effects/showfps/showfps_config.ui @@ -7,7 +7,7 @@ 0 0 356 - 180 + 250 @@ -148,6 +148,66 @@ + + + + Show graph: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ShowGraph + + + + + + + Show on active screen + + + + + + + Show Message: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ShowNoBenchmark + + + + + + + Show "not a benchmark" message + + + + + + + Colorize Text: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + kcfg_ColorizeText + + + + + + + Color text by value (green > yellow > red) + + + diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index 875b0a1450..bb8303766a 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -1954,6 +1954,7 @@ class KWINEFFECTS_EXPORT EffectScreen : public QObject Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged) Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged) Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(qreal refreshRate READ refreshRate CONSTANT) public: explicit EffectScreen(QObject *parent = nullptr); @@ -1973,6 +1974,11 @@ public: */ virtual QRect geometry() const = 0; + /** + * Returns the screen's refresh rate in milli-hertz. + */ + virtual int refreshRate() const = 0; + enum class Transform { Normal, Rotated90,