multiwindow: Replace per window fps timers with unified approach

The FPS is now calculated and output on the command line in a single
place. The animated fps counter has been replaced with a vertical line
which should make it easier to observe tearing issues when vsync is
disabled.

Change-Id: Id356fc1958c048d85aba48edfed59124454038d4
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Tor Arne Vestbø 2016-08-31 18:15:52 +02:00 committed by Tor Arne Vestbø
parent 880beb121e
commit efdecff085

View File

@ -60,7 +60,7 @@ class Window : public QOpenGLWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
Window(int index) : windowNumber(index + 1), y(0), fps(0) { Window(int index) : windowNumber(index + 1), x(0), framesSwapped(0) {
color = QColor::fromHsl((index * 30) % 360, 255, 127).toRgb(); color = QColor::fromHsl((index * 30) % 360, 255, 127).toRgb();
@ -69,7 +69,6 @@ public:
setObjectName(QString("Window %1").arg(windowNumber)); setObjectName(QString("Window %1").arg(windowNumber));
connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped())); connect(this, SIGNAL(frameSwapped()), SLOT(frameSwapped()));
fpsTimer.start();
} }
void paintGL() { void paintGL() {
@ -77,23 +76,14 @@ public:
f->glClearColor(color.redF(), color.greenF(), color.blueF(), 1); f->glClearColor(color.redF(), color.greenF(), color.blueF(), 1);
f->glClear(GL_COLOR_BUFFER_BIT); f->glClear(GL_COLOR_BUFFER_BIT);
QPainter p(this); QPainter painter(this);
p.setPen(Qt::white); painter.drawLine(x, 0, x, height());
p.drawText(QPoint(20, y), QString(QLatin1String("Window %1 (%2 FPS)")).arg(windowNumber).arg(fps)); x = ++x % width();
y += 1;
if (y > height() - 20)
y = 20;
} }
public slots: public slots:
void frameSwapped() { void frameSwapped() {
++framesSwapped; ++framesSwapped;
if (fpsTimer.elapsed() > 1000) {
fps = qRound(framesSwapped * (1000.0 / fpsTimer.elapsed()));
framesSwapped = 0;
fpsTimer.restart();
}
update(); update();
} }
@ -107,14 +97,46 @@ protected:
private: private:
int windowNumber; int windowNumber;
QColor color; QColor color;
int x;
int y;
int framesSwapped; int framesSwapped;
QElapsedTimer fpsTimer; friend void printFps();
int fps;
}; };
static const qreal kFpsInterval = 500;
void printFps()
{
static QElapsedTimer timer;
if (!timer.isValid()) {
timer.start();
return;
}
const qreal frameFactor = (kFpsInterval / timer.elapsed()) * (1000.0 / kFpsInterval);
QDebug output = qDebug().nospace();
qreal averageFps = 0;
const QWindowList windows = QGuiApplication::topLevelWindows();
for (int i = 0; i < windows.size(); ++i) {
Window *w = qobject_cast<Window*>(windows.at(i));
Q_ASSERT(w);
int fps = qRound(w->framesSwapped * frameFactor);
output << (i + 1) << "=" << fps << ", ";
averageFps += fps;
w->framesSwapped = 0;
}
averageFps = qRound(averageFps / windows.size());
qreal msPerFrame = 1000.0 / averageFps;
output << "avg=" << averageFps << ", ms=" << msPerFrame;
timer.restart();
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
@ -177,6 +199,12 @@ int main(int argc, char **argv)
w->showNormal(); w->showNormal();
} }
QTimer fpsTimer;
fpsTimer.setInterval(kFpsInterval);
fpsTimer.setTimerType(Qt::PreciseTimer);
QObject::connect(&fpsTimer, &QTimer::timeout, &printFps);
fpsTimer.start();
int r = app.exec(); int r = app.exec();
qDeleteAll(windows); qDeleteAll(windows);
return r; return r;