QML and frame rate
-
like blam said already you need to set the QML_SHOW_FRAMERATE env variable
on linux for example:
export QML_SHOW_FRAMERATE=1
then run qmlviewer
-
In c++ app you can use, don't know how to use it with the qmlviewer.exe
-
How can you display this framerate on a screen, in your QML Rectangle for instance, rather than in the terminal output? And can you use a timer to refresh the value only a certain amount of time by second to not sacrifice the refresh itself?
Thank you,
Bill -
Grep the source code of Qt for QML_SHOW_FRAMERATE and see how it's done there then replicate it yourself as I suspect it may use some private API (but I've not looked so I can't be certain). Once you have calculated the framerate just expose it to QML like any other data by exposing it as a property on a QObject and calling QDeclarativeContext::setContextProperty().
-
I grepped the source code and never found the QML_SHOW_FRAMERATE, is there something really tricky to do to simply get the FPS displayed in a QML application?
Any new help welcome!
Bill -
I realized I don't have all source files apparently, so I did the following:
I finally overloaded the paintEvent method from the QDeclarativeView subclass QApplicationViewer as follows:
@ .h file
void paintEvent(QPaintEvent *event);
Q_INVOKABLE float getCurrentFPS ();
QTime m_time;
int m_frameCount;
float currentFPS;@@ .cpp file
void QmlApplicationViewer::paintEvent(QPaintEvent *event)
{
//do nothing
if (m_frameCount == 0) {
m_time.start();
} else {
currentFPS = m_time.elapsed() / float(m_frameCount);
//qDebug()<< "FPS is %f ms\n" << m_time.elapsed() / float(m_frameCount);
}
m_frameCount++;
//qDebug()<<"Frame n°"<<m_frameCount;QDeclarativeView::paintEvent(event);
}
float QmlApplicationViewer::getCurrentFPS ()
{
return currentFPS;
}
@Then I exposed the viewer itself to the qml in the main.cpp file
@
int main(int argc, char *argv[])
{QScopedPointer<QApplication> app(createApplication(argc, argv)); QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create()); viewer->rootContext()->setContextProperty("myViewer", viewer.data());
@
The qml file can be something like this:
@
import QtQuick 1.0Item {
id: firstApp
width:1024
height:768Image{ id: background x:0 y:0 width:1024 height:768 source: "../../../Resources/BGTest.png" } property string myText: "" Rectangle { x:10 y:40 width: 100 height: 100 color: "white" Text { x:10 y:40 font.pixelSize: 24 text: "FPS: "+myText color: "black" } } Timer { interval: 1000 running: true repeat: true onTriggered: { myText = myViewer.getCurrentFPS() } } SequentialAnimation { running: true loops: Animation.Infinite NumberAnimation { target: background; property: "x"; to: 1024; duration: 2000 } PauseAnimation { duration: 5000 } NumberAnimation { target: background; property: "x"; to: 0; duration: 2000 } }
}
@ -
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 } }
I hope this helps someone :)