Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: tools/VisualBench/VisualInteractiveModule.cpp

Issue 1336043003: Add viewer mode to VisualBench. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix short option again Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 *
7 */
8
9 #include "VisualInteractiveModule.h"
10
11 #include "ProcStats.h"
12 #include "SkApplication.h"
13 #include "SkCanvas.h"
14 #include "SkCommandLineFlags.h"
15 #include "SkForceLinking.h"
16 #include "SkGraphics.h"
17 #include "SkGr.h"
18 #include "SkImageDecoder.h"
19 #include "SkOSFile.h"
20 #include "SkStream.h"
21 #include "Stats.h"
22 #include "gl/GrGLInterface.h"
23
24 __SK_FORCE_IMAGE_DECODER_LINKING;
25
26 static const int kGpuFrameLag = 5;
27 static const int kFrames = 5;
28 static const double kLoopMs = 5;
29
30 VisualInteractiveModule::VisualInteractiveModule(VisualBench* owner)
31 : fCurrentFrame(0)
32 , fLoops(1)
33 , fState(kPreWarmLoops_State)
34 , fCurrentMeasurement(0)
35 , fBenchmark(nullptr)
36 , fOwner(SkRef(owner)) {
37 fBenchmarkStream.reset(new VisualBenchmarkStream);
38
39 memset(fMeasurements, 0, sizeof(fMeasurements));
40 }
41
42 inline void VisualInteractiveModule::renderFrame(SkCanvas* canvas) {
43 fBenchmark->draw(fLoops, canvas);
44 this->drawStats(canvas);
45 canvas->flush();
46 fOwner->present();
47 }
48
49 void VisualInteractiveModule::drawStats(SkCanvas* canvas) {
50 const float kPixelPerMs = 2.0f;
51 const int kDisplayWidth = 130;
52 const int kDisplayHeight = 100;
53 const int kPadding = 10;
54
55 SkISize canvasSize = canvas->getDeviceSize();
56 SkRect rect = SkRect::MakeXYWH(SkIntToScalar(canvasSize.fWidth - kDisplayWid th - kPadding),
57 SkIntToScalar(kPadding),
58 SkIntToScalar(kDisplayWidth), SkIntToScalar(k DisplayHeight));
59 SkPaint paint;
60 canvas->clipRect(rect);
61 paint.setColor(SK_ColorBLACK);
62 canvas->drawRect(rect, paint);
63 // draw the 16ms line
64 paint.setColor(SK_ColorLTGRAY);
65 canvas->drawLine(rect.fLeft, rect.fBottom - 16.f*kPixelPerMs,
joshualitt 2015/09/14 14:07:45 I wonder if we want to make this 1000/60 'exactly.
jvanverth1 2015/09/14 16:21:38 Done.
66 rect.fRight, rect.fBottom - 16.f*kPixelPerMs, paint);
67 paint.setColor(SK_ColorRED);
68 paint.setStyle(SkPaint::kStroke_Style);
69 canvas->drawRect(rect, paint);
70
71 int x = SkScalarTruncToInt(rect.fLeft) + 3;
joshualitt 2015/09/14 14:07:45 Is this some kind of padding?
jvanverth1 2015/09/14 16:21:38 Done.
72 const int xStep = 2;
73 const int startY = SkScalarTruncToInt(rect.fBottom);
74 int i = fCurrentMeasurement;
75 do {
76 int endY = startY - (int)(fMeasurements[i] * kPixelPerMs + 0.5);
joshualitt 2015/09/14 14:07:45 0.5?
jvanverth1 2015/09/14 16:21:38 Added comment
77 canvas->drawLine(SkIntToScalar(x), SkIntToScalar(startY),
78 SkIntToScalar(x), SkIntToScalar(endY), paint);
79 i++;
80 i &= (kMeasurementCount - 1); // fast mod
81 x += xStep;
82 } while (i != fCurrentMeasurement);
83
84 }
85
86 bool VisualInteractiveModule::advanceRecordIfNecessary(SkCanvas* canvas) {
87 if (fBenchmark) {
88 return true;
89 }
90
91 fBenchmark.reset(fBenchmarkStream->next());
92 if (!fBenchmark) {
93 return false;
94 }
95
96 // clear both buffers
97 canvas->clear(0xffffffff);
98 canvas->flush();
99 fOwner->present();
100 canvas->clear(0xffffffff);
joshualitt 2015/09/14 14:07:45 Hmm, might be nice to have a static function on Vi
jvanverth1 2015/09/14 16:21:38 How do I know what the buffer setup is?
101
102 fBenchmark->preDraw();
103
104 return true;
105 }
106
107 void VisualInteractiveModule::draw(SkCanvas* canvas) {
108 if (!this->advanceRecordIfNecessary(canvas)) {
109 SkDebugf("Exiting VisualBench successfully\n");
110 fOwner->closeWindow();
111 return;
112 }
113 this->renderFrame(canvas);
114 switch (fState) {
115 case kPreWarmLoopsPerCanvasPreDraw_State: {
116 this->perCanvasPreDraw(canvas, kPreWarmLoops_State);
117 break;
118 }
119 case kPreWarmLoops_State: {
120 this->preWarm(kTuneLoops_State);
121 break;
122 }
123 case kTuneLoops_State: {
124 this->tuneLoops(canvas);
125 break;
126 }
127 case kPreTiming_State: {
128 fBenchmark->perCanvasPreDraw(canvas);
129 fCurrentFrame = 0;
130 fTimer.start();
131 fState = kTiming_State;
132 // fall to next state
133 }
134 case kTiming_State: {
135 this->timing(canvas);
136 break;
137 }
138 case kAdvance_State: {
139 this->postDraw(canvas);
140 this->nextState(kPreWarmLoopsPerCanvasPreDraw_State);
141 break;
142 }
143 }
144 }
145
146 inline void VisualInteractiveModule::nextState(State nextState) {
147 fState = nextState;
148 }
149
150 void VisualInteractiveModule::perCanvasPreDraw(SkCanvas* canvas, State nextState ) {
151 fBenchmark->perCanvasPreDraw(canvas);
152 fCurrentFrame = 0;
153 this->nextState(nextState);
154 }
155
156 void VisualInteractiveModule::preWarm(State nextState) {
157 if (fCurrentFrame >= kGpuFrameLag) {
158 // we currently time across all frames to make sure we capture all GPU w ork
159 this->nextState(nextState);
160 fCurrentFrame = 0;
161 fTimer.start();
162 } else {
163 fCurrentFrame++;
164 }
165 }
166
167 inline double VisualInteractiveModule::elapsed() {
168 fTimer.end();
169 return fTimer.fWall;
170 }
171
172 void VisualInteractiveModule::resetTimingState() {
173 fCurrentFrame = 0;
174 fTimer = WallTimer();
175 fOwner->reset();
176 }
177
178 void VisualInteractiveModule::scaleLoops(double elapsedMs) {
179 // Scale back the number of loops
180 fLoops = (int)ceil(fLoops * kLoopMs / elapsedMs);
181 }
182
183 inline void VisualInteractiveModule::tuneLoops(SkCanvas* canvas) {
joshualitt 2015/09/14 14:07:45 it'd be nice to figure out how to share this code,
jvanverth1 2015/09/14 16:21:38 Acknowledged.
184 if (1 << 30 == fLoops) {
185 // We're about to wrap. Something's wrong with the bench.
186 SkDebugf("InnerLoops wrapped\n");
187 fLoops = 0;
188 } else {
189 double elapsedMs = this->elapsed();
190 if (elapsedMs > kLoopMs) {
191 this->scaleLoops(elapsedMs);
192 fBenchmark->perCanvasPostDraw(canvas);
193 this->nextState(kPreTiming_State);
194 } else {
195 fLoops *= 2;
196 this->nextState(kPreWarmLoops_State);
197 }
198 this->resetTimingState();
199 }
200 }
201
202 void VisualInteractiveModule::recordMeasurement() {
203 double measurement = this->elapsed() / (kFrames * fLoops);
204 fMeasurements[fCurrentMeasurement++] = measurement;
205 fCurrentMeasurement &= (kMeasurementCount-1); // fast mod
206 SkASSERT(fCurrentMeasurement < kMeasurementCount);
207 }
208
209 void VisualInteractiveModule::postDraw(SkCanvas* canvas) {
210 fBenchmark->perCanvasPostDraw(canvas);
211 fBenchmark.reset(nullptr);
212 fLoops = 1;
213 }
214
215 inline void VisualInteractiveModule::timing(SkCanvas* canvas) {
216 if (fCurrentFrame >= kFrames) {
217 this->recordMeasurement();
218 fTimer.start();
219 fCurrentFrame = 0;
220 } else {
221 fCurrentFrame++;
222 }
223 }
224
225 bool VisualInteractiveModule::onHandleChar(SkUnichar c) {
226 if (' ' == c) {
227 this->nextState(kAdvance_State);
228 }
229
230 return true;
231 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698