diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2010-03-18 13:38:50 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2010-03-26 09:49:22 (GMT) |
commit | 41e9adb44137c8839d0d7e131802de198b0e7168 (patch) | |
tree | a36f1dda6ceafd1ee87c2acfe698767fb7144e0b /tools | |
parent | 5e2b330aaa0ef964d45f9cb60ea258b33d6e7c4a (diff) | |
download | Qt-41e9adb44137c8839d0d7e131802de198b0e7168.zip Qt-41e9adb44137c8839d0d7e131802de198b0e7168.tar.gz Qt-41e9adb44137c8839d0d7e131802de198b0e7168.tar.bz2 |
Paintbuffer single frame profiling.
Added new --instrumentframe=X argument which gives a detailed run-down
of how many milliseconds each paint command of that frame takes.
Reviewed-by: Gunnar Sletta
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qttracereplay/main.cpp | 99 |
1 files changed, 90 insertions, 9 deletions
diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp index be7906b..101d512 100644 --- a/tools/qttracereplay/main.cpp +++ b/tools/qttracereplay/main.cpp @@ -49,7 +49,7 @@ class ReplayWidget : public QWidget { Q_OBJECT public: - ReplayWidget(const QString &filename, int from, int to, bool single); + ReplayWidget(const QString &filename, int from, int to, bool single, int frame); void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); @@ -66,27 +66,96 @@ public: QTime timer; QList<uint> visibleUpdates; - QList<uint> iterationTimes; + + QVector<uint> iterationTimes; QString filename; int from; int to; bool single; + + int frame; + int currentCommand; }; void ReplayWidget::updateRect() { - if (!visibleUpdates.isEmpty()) + if (frame >= 0 && !updates.isEmpty()) + update(updates.at(frame)); + else if (!visibleUpdates.isEmpty()) update(updates.at(visibleUpdates.at(currentFrame))); } +const int singleFrameRepeatsPerCommand = 100; +const int singleFrameIterations = 4; + void ReplayWidget::paintEvent(QPaintEvent *) { QPainter p(this); + QTimer::singleShot(0, this, SLOT(updateRect())); + // p.setClipRegion(frames.at(currentFrame).updateRegion); + if (frame >= 0) { + int start = buffer.frameStartIndex(frame); + int end = buffer.frameEndIndex(frame); + + iterationTimes.resize(end - start); + + int saveRestoreStackDepth = buffer.processCommands(&p, start, start + currentCommand); + + for (int i = 0; i < saveRestoreStackDepth; ++i) + p.restore(); + + const int repeats = currentIteration >= 3 ? singleFrameRepeatsPerCommand : 1; + + ++currentFrame; + if (currentFrame == repeats) { + currentFrame = 0; + if (currentIteration >= 3) { + iterationTimes[currentCommand - 1] = qMin(iterationTimes[currentCommand - 1], uint(timer.elapsed())); + timer.restart(); + } + + if (currentIteration >= singleFrameIterations + 3) { + printf(" # | ms | description\n"); + printf("------+---------+------------------------------------------------------------\n"); + + qSort(iterationTimes); + + int sum = 0; + for (int i = 0; i < iterationTimes.size(); ++i) { + int delta = iterationTimes.at(i); + if (i > 0) + delta -= iterationTimes.at(i-1); + sum += delta; + qreal deltaF = delta / qreal(repeats); + printf("%.5d | %.5f | %s\n", i, deltaF, qPrintable(buffer.commandDescription(start + i))); + } + printf("Total | %.5f | Total frame time\n", sum / qreal(repeats)); + deleteLater(); + return; + } + + if (start + currentCommand >= end) { + currentCommand = 1; + ++currentIteration; + if (currentIteration == 3) { + timer.start(); + iterationTimes.fill(uint(-1)); + } + if (currentIteration >= 3 && currentIteration < singleFrameIterations + 3) + printf("Profiling iteration %d of %d\n", currentIteration - 2, singleFrameIterations); + } else { + ++currentCommand; + } + } + + return; + } + buffer.draw(&p, visibleUpdates.at(currentFrame)); ++currentFrame; @@ -138,11 +207,9 @@ void ReplayWidget::paintEvent(QPaintEvent *) } } } - - QTimer::singleShot(0, this, SLOT(updateRect())); } -void ReplayWidget::resizeEvent(QResizeEvent *event) +void ReplayWidget::resizeEvent(QResizeEvent *) { visibleUpdates.clear(); @@ -162,13 +229,15 @@ void ReplayWidget::resizeEvent(QResizeEvent *event) } -ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_) +ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_, int frame_) : currentFrame(0) , currentIteration(0) , filename(filename_) , from(from_) , to(to_) , single(single_) + , frame(frame_) + , currentCommand(1) { setWindowTitle(filename); QFile file(filename); @@ -216,7 +285,8 @@ int main(int argc, char **argv) printf("Usage:\n > %s [OPTIONS] [traceFile]\n", argv[0]); printf("OPTIONS\n" " --range=from-to to specify a frame range.\n" - " --singlerun to do only one run (without statistics)\n"); + " --singlerun to do only one run (without statistics)\n" + " --instrumentframe=frame to instrument a single frame\n"); return 1; } @@ -228,6 +298,8 @@ int main(int argc, char **argv) bool single = false; + int frame = -1; + int from = 0; int to = -1; for (int i = 1; i < app.arguments().size() - 1; ++i) { @@ -253,13 +325,22 @@ int main(int argc, char **argv) } } else if (arg == QLatin1String("--singlerun")) { single = true; + } else if (arg.startsWith(QLatin1String("--instrumentframe="))) { + QString rest = arg.mid(18); + bool ok = false; + int frameCandidate = rest.toInt(&ok); + if (ok) { + frame = frameCandidate; + } else { + printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg)); + } } else { printf("Unrecognized argument: %s\n", qPrintable(arg)); return 1; } } - ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single); + ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single, frame); if (!widget->updates.isEmpty()) { widget->show(); |