summaryrefslogtreecommitdiffstats
path: root/tools/qttracereplay/main.cpp
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-09-02 12:33:57 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-09-03 12:13:09 (GMT)
commit4feb152405e96125b6be2807d515293e3f25ab1a (patch)
tree52b0be39e7f435db7f7e41ed73a2bc53e01f4c8e /tools/qttracereplay/main.cpp
parentd4a4b01f2f08a9031d692344d0d264de472da25e (diff)
downloadQt-4feb152405e96125b6be2807d515293e3f25ab1a.zip
Qt-4feb152405e96125b6be2807d515293e3f25ab1a.tar.gz
Qt-4feb152405e96125b6be2807d515293e3f25ab1a.tar.bz2
Added trace graphics system for painting performance profiling.
When running an application with graphics system trace everything that gets painted to the window surface is proxied through a QPaintBuffer, which is then both streamed to a trace file and replayed on a raster window surface. The trace file can then be replayed with tools/qttracereplay to measure pure painting performance. Reviewed-by: Gunnar Sletta
Diffstat (limited to 'tools/qttracereplay/main.cpp')
-rw-r--r--tools/qttracereplay/main.cpp198
1 files changed, 198 insertions, 0 deletions
diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp
new file mode 100644
index 0000000..970531b
--- /dev/null
+++ b/tools/qttracereplay/main.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui>
+#include <QtDebug>
+
+#include <private/qpaintengineex_p.h>
+#include <private/qpaintbuffer_p.h>
+
+struct Frame
+{
+ QRegion updateRegion;
+ QPaintBuffer *buffer;
+};
+
+class ReplayWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ ReplayWidget(const QString &filename);
+
+ void paintEvent(QPaintEvent *event);
+
+public slots:
+ void updateRect();
+
+private:
+ QList<Frame> frames;
+ int currentFrame;
+ int currentIteration;
+ QTime timer;
+
+ QList<uint> iterationTimes;
+ QString filename;
+};
+
+void ReplayWidget::updateRect()
+{
+ update(frames.at(currentFrame).updateRegion);
+}
+
+void ReplayWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+
+// p.setClipRegion(frames.at(currentFrame).updateRegion);
+
+ frames.at(currentFrame).buffer->draw(&p);
+
+ ++currentFrame;
+ if (currentFrame >= frames.size()) {
+ currentFrame = 0;
+ ++currentIteration;
+
+ if (currentIteration == 3)
+ timer.start();
+ else if (currentIteration > 3) {
+ iterationTimes << timer.elapsed();
+ timer.restart();
+
+ if (iterationTimes.size() >= 3) {
+ qreal mean = 0;
+ qreal stddev = 0;
+ uint min = INT_MAX;
+
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ mean += iterationTimes.at(i);
+ min = qMin(min, iterationTimes.at(i));
+ }
+
+ mean /= qreal(iterationTimes.size());
+
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ qreal delta = iterationTimes.at(i) - mean;
+ stddev += delta * delta;
+ }
+
+ stddev = qSqrt(stddev / iterationTimes.size());
+
+ qSort(iterationTimes.begin(), iterationTimes.end());
+ qreal median = iterationTimes.at(iterationTimes.size() / 2);
+ if ((iterationTimes.size() % 1) == 1)
+ median = (median + iterationTimes.at(iterationTimes.size() / 2 - 1)) * 0.5;
+
+ stddev = 100 * stddev / mean;
+
+ if (iterationTimes.size() >= 10 || stddev < 4) {
+ printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %f, stddev: %f %%, max(fps): %f\n", qPrintable(filename),
+ iterationTimes.size(), frames.size(), min, median, stddev, 1000. * frames.size() / min);
+ deleteLater();
+ return;
+ }
+ }
+ }
+ }
+
+ QTimer::singleShot(0, this, SLOT(updateRect()));
+}
+
+ReplayWidget::ReplayWidget(const QString &filename_)
+ : currentFrame(0)
+ , currentIteration(0)
+ , filename(filename_)
+{
+ setWindowTitle(filename);
+ QFile file(filename);
+
+ QRect bounds;
+ if (file.open(QIODevice::ReadOnly)) {
+ QDataStream in(&file);
+
+ while (true) {
+ int frameId;
+ in >> frameId;
+
+ if (in.status() != QDataStream::Ok)
+ break;
+
+ qulonglong windowId;
+ QRegion rgn;
+
+ in >> windowId;
+
+ Frame frame;
+ frame.buffer = new QPaintBuffer;
+
+ in >> bounds;
+
+ in >> frame.updateRegion;
+ in >> *frame.buffer;
+
+ frames << frame;
+ }
+ }
+
+ qDebug() << "Read" << frames.size() << "frames";
+
+ resize(bounds.size());
+
+ setAutoFillBackground(false);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ QTimer::singleShot(10, this, SLOT(updateRect()));
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ if (argc <= 1) {
+ printf("Usage: %s filename\n", argv[0]);
+ return 1;
+ }
+
+ ReplayWidget *widget = new ReplayWidget(argv[1]);
+ widget->show();
+
+ return app.exec();
+}
+#include "main.moc"