effects/showfps: add new options
- added option to remove the frametime graph - added option to remove the "this is a benchmark" message - location of the fps counter is now on the "active" monitor by default - removed the hard-limit of 100 for the FPS counter - added option to color the text based off the FPS value
This commit is contained in:
parent
9de9b93325
commit
41526bd8dd
7 changed files with 200 additions and 71 deletions
|
@ -1895,6 +1895,11 @@ QRect EffectScreenImpl::geometry() const
|
||||||
return m_platformOutput->geometry();
|
return m_platformOutput->geometry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EffectScreenImpl::refreshRate() const
|
||||||
|
{
|
||||||
|
return m_platformOutput->refreshRate();
|
||||||
|
}
|
||||||
|
|
||||||
EffectScreen::Transform EffectScreenImpl::transform() const
|
EffectScreen::Transform EffectScreenImpl::transform() const
|
||||||
{
|
{
|
||||||
return EffectScreen::Transform(m_platformOutput->transform());
|
return EffectScreen::Transform(m_platformOutput->transform());
|
||||||
|
|
|
@ -390,6 +390,7 @@ public:
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
qreal devicePixelRatio() const override;
|
qreal devicePixelRatio() const override;
|
||||||
QRect geometry() const override;
|
QRect geometry() const override;
|
||||||
|
int refreshRate() const override;
|
||||||
Transform transform() const override;
|
Transform transform() const override;
|
||||||
|
|
||||||
static EffectScreenImpl *get(AbstractOutput *output);
|
static EffectScreenImpl *get(AbstractOutput *output);
|
||||||
|
|
|
@ -47,8 +47,10 @@ ShowFpsEffect::ShowFpsEffect()
|
||||||
++i) {
|
++i) {
|
||||||
frames[i] = 0;
|
frames[i] = 0;
|
||||||
}
|
}
|
||||||
m_noBenchmark->setAlignment(Qt::AlignTop | Qt::AlignRight);
|
if (m_showNoBenchmark) {
|
||||||
m_noBenchmark->setText(i18n("This effect is not a benchmark"));
|
m_noBenchmark->setAlignment(Qt::AlignTop | Qt::AlignRight);
|
||||||
|
m_noBenchmark->setText(i18n("This effect is not a benchmark"));
|
||||||
|
}
|
||||||
reconfigure(ReconfigureAll);
|
reconfigure(ReconfigureAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +64,9 @@ void ShowFpsEffect::reconfigure(ReconfigureFlags)
|
||||||
alpha = ShowFpsConfig::alpha();
|
alpha = ShowFpsConfig::alpha();
|
||||||
x = ShowFpsConfig::x();
|
x = ShowFpsConfig::x();
|
||||||
y = ShowFpsConfig::y();
|
y = ShowFpsConfig::y();
|
||||||
|
m_showNoBenchmark = ShowFpsConfig::showNoBenchmark();
|
||||||
|
m_showGraph = ShowFpsConfig::showGraph();
|
||||||
|
m_colorizeText = ShowFpsConfig::colorizeText();
|
||||||
const QSize screenSize = effects->virtualScreenSize();
|
const QSize screenSize = effects->virtualScreenSize();
|
||||||
if (x == -10000) { // there's no -0 :(
|
if (x == -10000) { // there's no -0 :(
|
||||||
x = screenSize.width() - 2 * NUM_PAINTS - FPS_WIDTH;
|
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;
|
paint_size[paints_pos] = 0;
|
||||||
t.restart();
|
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)
|
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
|
++fps; // count all frames in the last second
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fps > MAX_TIME) {
|
|
||||||
fps = MAX_TIME; // keep it the same height
|
|
||||||
}
|
|
||||||
if (effects->isOpenGLCompositing()) {
|
if (effects->isOpenGLCompositing()) {
|
||||||
paintGL(fps, data.projectionMatrix());
|
paintGL(fps, data.projectionMatrix());
|
||||||
glFinish(); // make sure all rendering is done
|
glFinish(); // make sure all rendering is done
|
||||||
} else if (effects->compositingType() == QPainterCompositing) {
|
} else if (effects->compositingType() == QPainterCompositing) {
|
||||||
paintQPainter(fps);
|
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)
|
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
|
// means that the contents also blend with the background, I guess
|
||||||
ShaderBinder binder(ShaderTrait::UniformColor);
|
ShaderBinder binder(ShaderTrait::UniformColor);
|
||||||
binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, projectionMatrix);
|
binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, projectionMatrix);
|
||||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
if (m_showGraph) {
|
||||||
vbo->reset();
|
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||||
QColor color(255, 255, 255);
|
vbo->reset();
|
||||||
color.setAlphaF(alpha);
|
QColor color(255, 255, 255);
|
||||||
vbo->setColor(color);
|
color.setAlphaF(alpha);
|
||||||
QVector<float> verts;
|
vbo->setColor(color);
|
||||||
verts.reserve(12);
|
QVector<float> verts;
|
||||||
verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
|
verts.reserve(12);
|
||||||
verts << x << y;
|
verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
|
||||||
verts << x << y + MAX_TIME;
|
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 << y + MAX_TIME;
|
||||||
verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
|
verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y + MAX_TIME;
|
||||||
vbo->setData(6, 2, verts.constData(), nullptr);
|
verts << x + 2 * NUM_PAINTS + FPS_WIDTH << y;
|
||||||
vbo->render(GL_TRIANGLES);
|
vbo->setData(6, 2, verts.constData(), nullptr);
|
||||||
y += MAX_TIME; // paint up from the bottom
|
vbo->render(GL_TRIANGLES);
|
||||||
color.setRed(0);
|
y += MAX_TIME; // paint up from the bottom
|
||||||
color.setGreen(0);
|
color.setRed(0);
|
||||||
vbo->setColor(color);
|
color.setGreen(0);
|
||||||
verts.clear();
|
vbo->setColor(color);
|
||||||
verts << x + FPS_WIDTH << y - fps;
|
verts.clear();
|
||||||
verts << x << y - fps;
|
verts << x + FPS_WIDTH << y - fps;
|
||||||
verts << x << y;
|
verts << x << y - fps;
|
||||||
verts << x << y;
|
verts << x << y;
|
||||||
verts << x + FPS_WIDTH << y;
|
verts << x << y;
|
||||||
verts << x + FPS_WIDTH << y - fps;
|
verts << x + FPS_WIDTH << y;
|
||||||
vbo->setData(6, 2, verts.constData(), nullptr);
|
verts << x + FPS_WIDTH << y - fps;
|
||||||
vbo->render(GL_TRIANGLES);
|
vbo->setData(6, 2, verts.constData(), nullptr);
|
||||||
|
vbo->render(GL_TRIANGLES);
|
||||||
|
|
||||||
color.setBlue(0);
|
color.setBlue(0);
|
||||||
vbo->setColor(color);
|
vbo->setColor(color);
|
||||||
QVector<float> vertices;
|
QVector<float> vertices;
|
||||||
for (int i = 10;
|
for (int i = 10; i < MAX_TIME; i += 10) {
|
||||||
i < MAX_TIME;
|
vertices << x << y - i;
|
||||||
i += 10) {
|
vertices << x + FPS_WIDTH << y - i;
|
||||||
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
|
// Paint FPS numerical value
|
||||||
if (fpsTextRect.isValid()) {
|
if (fpsTextRect.isValid()) {
|
||||||
|
@ -251,27 +263,29 @@ void ShowFpsEffect::paintQPainter(int fps)
|
||||||
QPainter *painter = effects->scenePainter();
|
QPainter *painter = effects->scenePainter();
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
QColor color(255, 255, 255);
|
if (m_showGraph) {
|
||||||
color.setAlphaF(alpha);
|
QColor color(255, 255, 255);
|
||||||
|
color.setAlphaF(alpha);
|
||||||
|
|
||||||
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
painter->fillRect(x, y, 2 * NUM_PAINTS + FPS_WIDTH, MAX_TIME, color);
|
painter->fillRect(x, y, 2 * NUM_PAINTS + FPS_WIDTH, MAX_TIME, color);
|
||||||
color.setRed(0);
|
color.setRed(0);
|
||||||
color.setGreen(0);
|
color.setGreen(0);
|
||||||
painter->fillRect(x, y + MAX_TIME - fps, FPS_WIDTH, fps, color);
|
painter->fillRect(x, y + MAX_TIME - fps, FPS_WIDTH, fps, color);
|
||||||
|
|
||||||
color.setBlue(0);
|
color.setBlue(0);
|
||||||
for (int i = 10; i < MAX_TIME; i += 10) {
|
for (int i = 10; i < MAX_TIME; i += 10) {
|
||||||
painter->setPen(color);
|
painter->setPen(color);
|
||||||
painter->drawLine(x, y + MAX_TIME - i, x + FPS_WIDTH, y + MAX_TIME - i);
|
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
|
// Paint FPS numerical value
|
||||||
painter->setPen(Qt::black);
|
painter->setPen(Qt::black);
|
||||||
painter->drawText(fpsTextRect, textAlign, QString::number(fps));
|
painter->drawText(fpsTextRect, textAlign, QString::number(fps));
|
||||||
|
@ -417,7 +431,22 @@ QImage ShowFpsEffect::fpsTextImage(int fps)
|
||||||
im.fill(Qt::transparent);
|
im.fill(Qt::transparent);
|
||||||
QPainter painter(&im);
|
QPainter painter(&im);
|
||||||
painter.setFont(textFont);
|
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.drawText(QRect(0, 0, 100, 100), textAlign, QString::number(fps));
|
||||||
painter.end();
|
painter.end();
|
||||||
return im;
|
return im;
|
||||||
|
|
|
@ -30,6 +30,9 @@ class ShowFpsEffect
|
||||||
Q_PROPERTY(int textAlign READ configuredTextAlign)
|
Q_PROPERTY(int textAlign READ configuredTextAlign)
|
||||||
Q_PROPERTY(QFont textFont READ configuredTextFont)
|
Q_PROPERTY(QFont textFont READ configuredTextFont)
|
||||||
Q_PROPERTY(QColor textColor READ configuredTextColor)
|
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:
|
public:
|
||||||
ShowFpsEffect();
|
ShowFpsEffect();
|
||||||
~ShowFpsEffect() override;
|
~ShowFpsEffect() override;
|
||||||
|
@ -77,6 +80,18 @@ public:
|
||||||
{
|
{
|
||||||
return textColor;
|
return textColor;
|
||||||
}
|
}
|
||||||
|
bool configuredShowGraph() const
|
||||||
|
{
|
||||||
|
return m_showGraph;
|
||||||
|
}
|
||||||
|
bool configuredShowNoBenchmark() const
|
||||||
|
{
|
||||||
|
return m_showNoBenchmark;
|
||||||
|
}
|
||||||
|
bool configuredColorizeText() const
|
||||||
|
{
|
||||||
|
return m_colorizeText;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintGL(int fps, const QMatrix4x4 &projectionMatrix);
|
void paintGL(int fps, const QMatrix4x4 &projectionMatrix);
|
||||||
|
@ -98,6 +113,10 @@ private:
|
||||||
qint64 frames[MAX_FPS]; // the time when the frame was done
|
qint64 frames[MAX_FPS]; // the time when the frame was done
|
||||||
int frames_pos; // position in the queue
|
int frames_pos; // position in the queue
|
||||||
double alpha;
|
double alpha;
|
||||||
|
bool m_showNoBenchmark;
|
||||||
|
bool m_showGraph;
|
||||||
|
bool m_colorizeText;
|
||||||
|
int detectedMaxFps;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
QRect fps_rect;
|
QRect fps_rect;
|
||||||
|
|
|
@ -24,5 +24,14 @@
|
||||||
<entry name="Y" type="Int">
|
<entry name="Y" type="Int">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="ShowGraph" type="Bool">
|
||||||
|
<default>true</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="ShowNoBenchmark" type="Bool">
|
||||||
|
<default>true</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="ColorizeText" type="Bool">
|
||||||
|
<default>true</default>
|
||||||
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
</kcfg>
|
</kcfg>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>356</width>
|
<width>356</width>
|
||||||
<height>180</height>
|
<height>250</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
|
@ -148,6 +148,66 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show graph:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>kcfg_ShowGraph</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QCheckBox" name="kcfg_ShowGraph">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show on active screen</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Message:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>kcfg_ShowNoBenchmark</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QCheckBox" name="kcfg_ShowNoBenchmark">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show "not a benchmark" message</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Colorize Text:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>kcfg_ColorizeText</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QCheckBox" name="kcfg_ColorizeText">
|
||||||
|
<property name="text">
|
||||||
|
<string>Color text by value (green > yellow > red)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1954,6 +1954,7 @@ class KWINEFFECTS_EXPORT EffectScreen : public QObject
|
||||||
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
|
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
|
||||||
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
|
Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged)
|
||||||
Q_PROPERTY(QString name READ name CONSTANT)
|
Q_PROPERTY(QString name READ name CONSTANT)
|
||||||
|
Q_PROPERTY(qreal refreshRate READ refreshRate CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EffectScreen(QObject *parent = nullptr);
|
explicit EffectScreen(QObject *parent = nullptr);
|
||||||
|
@ -1973,6 +1974,11 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual QRect geometry() const = 0;
|
virtual QRect geometry() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the screen's refresh rate in milli-hertz.
|
||||||
|
*/
|
||||||
|
virtual int refreshRate() const = 0;
|
||||||
|
|
||||||
enum class Transform {
|
enum class Transform {
|
||||||
Normal,
|
Normal,
|
||||||
Rotated90,
|
Rotated90,
|
||||||
|
|
Loading…
Reference in a new issue