Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show FPS in QML

Is there a "simple" way to show the FPS (frame rate) in a QML/c++ application. All animations and views are done in QML and the application logic is in c++.

I already tried setting QML_SHOW_FRAMERATE in Linux before starting the application but it didn't help:

export QML_SHOW_FRAMERATE=1
like image 263
luffy Avatar asked Feb 22 '16 12:02

luffy


People also ask

How to add FPS qquickitem in QML?

You have to create your own FPS QQuickItem (or QQuickPaintedItem) and register in your main.cpp to be available in your QML code. Here an example.

How can I See my fps in-game?

Here are a few popular examples: Call of Duty: Warzone: Go to Options > General > Telemetry and enable Frames Per Second (FPS) Counter. Dota 2: Head to Settings > Options > Advanced Options > Display Network Information. Fortnite: Look under Settings > Video > Show FPS. League of Legends: Press Ctrl+F in-game to view frame rate and latency stats.

How do I See my fps in Call of duty Warzone?

Call of Duty: Warzone: Go to Options > General > Telemetry and enable Frames Per Second (FPS) Counter. Dota 2: Head to Settings > Options > Advanced Options > Display Network Information. Fortnite: Look under Settings > Video > Show FPS. League of Legends: Press Ctrl+F in-game to view frame rate and latency stats.

Where is the fps counter on Windows 10?

Windows 10 has a built-in FPS counter hidden in its little-known Xbox Game Bar. Despite its name, the Xbox Game Bar is a powerful full-screen overlay you can use in PC games. Here’s how to show your frames per second (FPS) in games. This feature is part of the Game Bar.


3 Answers

I studied to topic a bit. I typically used the approach described by @Miguel Angel, but I recently implemented a simpler one using the QQuickWindow::frameSwapped() signal. Code and info can be found here: https://github.com/carlonluca/lqtutils#lqtutils_uih. It is simple to integrate in another app.

I compared these two techniques with the one from @forlayo: the first two seem to always agree on the measurement, the other is typically different.

This is the comparison: https://youtu.be/p_y_kL85R4A.

I also wrote a blog post with some more info: https://thebugfreeblog.blogspot.com/2021/09/measure-framerate-qt.html

like image 119
Luca Carlon Avatar answered Oct 11 '22 12:10

Luca Carlon


You have to create your own FPS QQuickItem (or QQuickPaintedItem) and register in your main.cpp to be available in your QML code.

Here an example.

class FPSText: public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(int fps READ fps NOTIFY fpsChanged)
public:
    FPSText(QQuickItem *parent = 0);
    ~FPSText();
    void paint(QPainter *);
    Q_INVOKABLE int fps()const;

signals:
    void fpsChanged(int);

private:
    void recalculateFPS();
    int _currentFPS;
    int _cacheCount;
    QVector<qint64> _times;
};

FPSText::FPSText(QQuickItem *parent): QQuickPaintedItem(parent), _currentFPS(0), _cacheCount(0)
{
    _times.clear();
    setFlag(QQuickItem::ItemHasContents);
}

FPSText::~FPSText()
{
}

void FPSText::recalculateFPS()
{
    qint64 currentTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
    _times.push_back(currentTime);

    while (_times[0] < currentTime - 1000) {
        _times.pop_front();
    }

    int currentCount = _times.length();
    _currentFPS = (currentCount + _cacheCount) / 2;
    qDebug() << _currentFPS;

    if (currentCount != _cacheCount) fpsChanged(_currentFPS);

    _cacheCount = currentCount;
}

int FPSText::fps()const
{
    return _currentFPS;
}

void FPSText::paint(QPainter *painter)
{
    recalculateFPS();
    //qDebug() << __FUNCTION__;
    QBrush brush(Qt::yellow);

    painter->setBrush(brush);
    painter->setPen(Qt::NoPen);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height(), 0, 0);
    update();
}

qml:

FPSText{
        id: fps_text
        x:0
        y: 0;
        width: 200
        height: 100
        Text {
                anchors.centerIn: parent
                text: fps_text.fps.toFixed(2)
            }
    }

You can get any other implementation in Internet with a quick search.

like image 30
Miguel Angel Avatar answered Oct 11 '22 12:10

Miguel Angel


QML FPS Counter, without affecting performance.

Project of QNanoPainter and others in qt-labs are using the refresh of an animation of a QML Item to create an FPS counter. It's so easy to being done, attached a project that uses this technique ( modified from QNanoPainter FPS counter ).

FpsItem code:

import QtQuick 2.0
import QtQuick.Window 2.2

Rectangle {
    id: root
    property int frameCounter: 0
    property int frameCounterAvg: 0
    property int counter: 0
    property int fps: 0
    property int fpsAvg: 0

    readonly property real dp: Screen.pixelDensity * 25.4/160

    color: "black"
    width:  childrenRect.width + 10*dp;
    height: childrenRect.height + 10*dp;

    Image {
        id: spinnerImage
        anchors.verticalCenter: parent.verticalCenter
        x: 4 * dp
        width: 36 * dp
        height: width
        source: "images/spinner.png"
        NumberAnimation on rotation {
            from:0
            to: 360
            duration: 800
            loops: Animation.Infinite
        }
        onRotationChanged: frameCounter++;
    }

    Text {
        anchors.left: spinnerImage.right
        anchors.leftMargin: 8 * dp
        anchors.verticalCenter: spinnerImage.verticalCenter
        color: "#c0c0c0"
        font.pixelSize: 18 * dp
        text: "Ø " + root.fpsAvg + " | " + root.fps + " fps"
    }

    Timer {
        interval: 2000
        repeat: true
        running: true
        onTriggered: {
            frameCounterAvg += frameCounter;
            root.fps = frameCounter/2;
            counter++;
            frameCounter = 0;
            if (counter >= 3) {
                root.fpsAvg = frameCounterAvg/(2*counter)
                frameCounterAvg = 0;
                counter = 0;
            }
        }
    }
}

Using it as:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    FpsItem {
        id: fpsItem
        anchors.centerIn: parent
    }

}
like image 7
forlayo Avatar answered Oct 11 '22 12:10

forlayo