62 |
63 |
63 int currentFrame; |
64 int currentFrame; |
64 int currentIteration; |
65 int currentIteration; |
65 QTime timer; |
66 QTime timer; |
66 |
67 |
|
68 QList<uint> visibleUpdates; |
67 QList<uint> iterationTimes; |
69 QList<uint> iterationTimes; |
68 QString filename; |
70 QString filename; |
69 }; |
71 }; |
70 |
72 |
71 void ReplayWidget::updateRect() |
73 void ReplayWidget::updateRect() |
72 { |
74 { |
73 if (!updates.isEmpty()) |
75 if (!visibleUpdates.isEmpty()) |
74 update(updates.at(currentFrame)); |
76 update(updates.at(visibleUpdates.at(currentFrame))); |
75 } |
77 } |
76 |
78 |
77 void ReplayWidget::paintEvent(QPaintEvent *) |
79 void ReplayWidget::paintEvent(QPaintEvent *) |
78 { |
80 { |
79 QPainter p(this); |
81 QPainter p(this); |
80 |
82 |
81 // p.setClipRegion(frames.at(currentFrame).updateRegion); |
83 // p.setClipRegion(frames.at(currentFrame).updateRegion); |
82 |
84 |
83 buffer.draw(&p, currentFrame); |
85 buffer.draw(&p, visibleUpdates.at(currentFrame)); |
84 |
86 |
85 ++currentFrame; |
87 ++currentFrame; |
86 if (currentFrame >= buffer.numFrames()) { |
88 if (currentFrame >= visibleUpdates.size()) { |
87 currentFrame = 0; |
89 currentFrame = 0; |
88 ++currentIteration; |
90 ++currentIteration; |
89 |
91 |
90 if (currentIteration == 3) |
92 if (currentIteration == 3) |
91 timer.start(); |
93 timer.start(); |
117 |
119 |
118 stddev = 100 * stddev / mean; |
120 stddev = 100 * stddev / mean; |
119 |
121 |
120 if (iterationTimes.size() >= 10 || stddev < 4) { |
122 if (iterationTimes.size() >= 10 || stddev < 4) { |
121 printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename), |
123 printf("%s, iterations: %d, frames: %d, min(ms): %d, median(ms): %d, stddev: %f %%, max(fps): %f\n", qPrintable(filename), |
122 iterationTimes.size(), updates.size(), min, median, stddev, 1000. * updates.size() / min); |
124 iterationTimes.size(), visibleUpdates.size(), min, median, stddev, 1000. * visibleUpdates.size() / min); |
123 deleteLater(); |
125 deleteLater(); |
124 return; |
126 return; |
125 } |
127 } |
126 } |
128 } |
127 } |
129 } |
128 } |
130 } |
129 |
131 |
130 QTimer::singleShot(0, this, SLOT(updateRect())); |
132 QTimer::singleShot(0, this, SLOT(updateRect())); |
131 } |
133 } |
132 |
134 |
|
135 void 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 |
133 ReplayWidget::ReplayWidget(const QString &filename_) |
150 ReplayWidget::ReplayWidget(const QString &filename_) |
134 : currentFrame(0) |
151 : currentFrame(0) |
135 , currentIteration(0) |
152 , currentIteration(0) |
136 , filename(filename_) |
153 , filename(filename_) |
137 { |
154 { |
138 setWindowTitle(filename); |
155 setWindowTitle(filename); |
139 QFile file(filename); |
156 QFile file(filename); |
140 |
157 |
141 QRect bounds; |
|
142 if (!file.open(QIODevice::ReadOnly)) { |
158 if (!file.open(QIODevice::ReadOnly)) { |
143 printf("Failed to load input file '%s'\n", qPrintable(filename_)); |
159 printf("Failed to load input file '%s'\n", qPrintable(filename_)); |
144 return; |
160 return; |
145 } |
161 } |
146 |
162 |