source: trunk/tools/qttracereplay/main.cpp@ 814

Last change on this file since 814 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the tools applications of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43#include <QtDebug>
44
45#include <private/qpaintengineex_p.h>
46#include <private/qpaintbuffer_p.h>
47
48class ReplayWidget : public QWidget
49{
50 Q_OBJECT
51public:
52 ReplayWidget(const QString &filename);
53
54 void paintEvent(QPaintEvent *event);
55 void resizeEvent(QResizeEvent *event);
56
57public slots:
58 void updateRect();
59
60public:
61 QList<QRegion> updates;
62 QPaintBuffer buffer;
63
64 int currentFrame;
65 int currentIteration;
66 QTime timer;
67
68 QList<uint> visibleUpdates;
69 QList<uint> iterationTimes;
70 QString filename;
71};
72
73void ReplayWidget::updateRect()
74{
75 if (!visibleUpdates.isEmpty())
76 update(updates.at(visibleUpdates.at(currentFrame)));
77}
78
79void ReplayWidget::paintEvent(QPaintEvent *)
80{
81 QPainter p(this);
82
83// p.setClipRegion(frames.at(currentFrame).updateRegion);
84
85 buffer.draw(&p, visibleUpdates.at(currentFrame));
86
87 ++currentFrame;
88 if (currentFrame >= visibleUpdates.size()) {
89 currentFrame = 0;
90 ++currentIteration;
91
92 if (currentIteration == 3)
93 timer.start();
94 else if (currentIteration > 3) {
95 iterationTimes << timer.elapsed();
96 timer.restart();
97
98 if (iterationTimes.size() >= 3) {
99 qreal mean = 0;
100 qreal stddev = 0;
101 uint min = INT_MAX;
102
103 for (int i = 0; i < iterationTimes.size(); ++i) {
104 mean += iterationTimes.at(i);
105 min = qMin(min, iterationTimes.at(i));
106 }
107
108 mean /= qreal(iterationTimes.size());
109
110 for (int i = 0; i < iterationTimes.size(); ++i) {
111 qreal delta = iterationTimes.at(i) - mean;
112 stddev += delta * delta;
113 }
114
115 stddev = qSqrt(stddev / iterationTimes.size());
116
117 qSort(iterationTimes.begin(), iterationTimes.end());
118 uint median = iterationTimes.at(iterationTimes.size() / 2);
119
120 stddev = 100 * stddev / mean;
121
122 if (iterationTimes.size() >= 10 || stddev < 4) {
123 printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename),
124 iterationTimes.size(), visibleUpdates.size(), min, median, stddev, 1000. * visibleUpdates.size() / min);
125 deleteLater();
126 return;
127 }
128 }
129 }
130 }
131
132 QTimer::singleShot(0, this, SLOT(updateRect()));
133}
134
135void ReplayWidget::resizeEvent(QResizeEvent *event)
136{
137 visibleUpdates.clear();
138
139 QRect bounds = rect();
140 for (int i = 0; i < updates.size(); ++i) {
141 if (updates.at(i).intersects(bounds))
142 visibleUpdates << i;
143 }
144
145 if (visibleUpdates.size() != updates.size())
146 printf("Warning: skipped %d frames due to limited resolution\n", updates.size() - visibleUpdates.size());
147
148}
149
150ReplayWidget::ReplayWidget(const QString &filename_)
151 : currentFrame(0)
152 , currentIteration(0)
153 , filename(filename_)
154{
155 setWindowTitle(filename);
156 QFile file(filename);
157
158 if (!file.open(QIODevice::ReadOnly)) {
159 printf("Failed to load input file '%s'\n", qPrintable(filename_));
160 return;
161 }
162
163 QDataStream in(&file);
164
165 char *data;
166 uint size;
167 in.readBytes(data, size);
168 bool isTraceFile = size == 7 && qstrncmp(data, "qttrace", 7) == 0;
169 delete [] data;
170 if (!isTraceFile) {
171 printf("File '%s' is not a trace file\n", qPrintable(filename_));
172 return;
173 }
174
175 in >> buffer >> updates;
176 printf("Read paint buffer with %d frames\n", buffer.numFrames());
177
178 resize(buffer.boundingRect().size().toSize());
179
180 setAutoFillBackground(false);
181 setAttribute(Qt::WA_NoSystemBackground);
182
183 QTimer::singleShot(10, this, SLOT(updateRect()));
184}
185
186int main(int argc, char **argv)
187{
188 QApplication app(argc, argv);
189
190 if (argc <= 1 || qstrcmp(argv[1], "-h") == 0 || qstrcmp(argv[1], "--help") == 0) {
191 printf("Replays a tracefile generated with '-graphicssystem trace'\n");
192 printf("Usage:\n > %s [traceFile]\n", argv[0]);
193 return 1;
194 }
195
196 QFile file(argv[1]);
197 if (!file.exists()) {
198 printf("%s does not exist\n", argv[1]);
199 return 1;
200 }
201
202 ReplayWidget *widget = new ReplayWidget(argv[1]);
203
204 if (!widget->updates.isEmpty()) {
205 widget->show();
206 return app.exec();
207 }
208
209}
210#include "main.moc"
Note: See TracBrowser for help on using the repository browser.