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.cpp

Issue 1216973002: Move visualbench to its own folder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 5 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
« no previous file with comments | « tools/VisualBench.h ('k') | tools/VisualBench/VisualBench.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "VisualBench.h"
10
11 #include "ProcStats.h"
12 #include "SkApplication.h"
13 #include "SkCanvas.h"
14 #include "SkCommandLineFlags.h"
15 #include "SkCommonFlags.h"
16 #include "SkForceLinking.h"
17 #include "SkGraphics.h"
18 #include "SkGr.h"
19 #include "SkImageDecoder.h"
20 #include "SkOSFile.h"
21 #include "SkStream.h"
22 #include "Stats.h"
23 #include "gl/GrGLInterface.h"
24
25 __SK_FORCE_IMAGE_DECODER_LINKING;
26
27 // Between samples we reset context
28 // Between frames we swap buffers
29 // Between flushes we call flush on GrContext
30
31 DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allow s to lag.");
32 DEFINE_int32(samples, 10, "Number of times to time each skp.");
33 DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample.");
34 DEFINE_double(flushMs, 20, "Target flush time in millseconds.");
35 DEFINE_double(loopMs, 5, "Target loop time in millseconds.");
36 DEFINE_int32(msaa, 0, "Number of msaa samples.");
37 DEFINE_bool2(fullscreen, f, true, "Run fullscreen.");
38
39 static SkString humanize(double ms) {
40 if (FLAGS_verbose) {
41 return SkStringPrintf("%llu", (uint64_t)(ms*1e6));
42 }
43 return HumanizeMs(ms);
44 }
45
46 #define HUMANIZE(time) humanize(time).c_str()
47
48 VisualBench::VisualBench(void* hwnd, int argc, char** argv)
49 : INHERITED(hwnd)
50 , fCurrentPictureIdx(-1)
51 , fCurrentSample(0)
52 , fCurrentFrame(0)
53 , fFlushes(1)
54 , fLoops(1)
55 , fState(kPreWarmLoops_State) {
56 SkCommandLineFlags::Parse(argc, argv);
57
58 // read all the skp file names.
59 for (int i = 0; i < FLAGS_skps.count(); i++) {
60 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
61 fRecords.push_back().fFilename = FLAGS_skps[i];
62 } else {
63 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
64 SkString path;
65 while (it.next(&path)) {
66 fRecords.push_back().fFilename = SkOSPath::Join(FLAGS_skps[i], p ath.c_str());;
67 }
68 }
69 }
70
71 if (fRecords.empty()) {
72 SkDebugf("no valid skps found\n");
73 }
74
75 this->setTitle();
76 this->setupBackend();
77
78 // Print header
79 SkDebugf("curr/maxrss\tloops\tflushes\tmin\tmedian\tmean\tmax\tstddev\tbench \n");
80 }
81
82 VisualBench::~VisualBench() {
83 INHERITED::detach();
84 }
85
86 void VisualBench::setTitle() {
87 SkString title("VisualBench");
88 INHERITED::setTitle(title.c_str());
89 }
90
91 SkSurface* VisualBench::createSurface() {
92 SkSurfaceProps props(INHERITED::getSurfaceProps());
93 return SkSurface::NewRenderTargetDirect(fRenderTarget, &props);
94 }
95
96 bool VisualBench::setupBackend() {
97 this->setColorType(kRGBA_8888_SkColorType);
98 this->setVisibleP(true);
99 this->setClipToBounds(false);
100
101 if (FLAGS_fullscreen) {
102 if (!this->makeFullscreen()) {
103 SkDebugf("Could not go fullscreen!");
104 }
105 }
106 if (!this->attach(kNativeGL_BackEndType, FLAGS_msaa, &fAttachmentInfo)) {
107 SkDebugf("Not possible to create backend.\n");
108 INHERITED::detach();
109 return false;
110 }
111
112 this->setVsync(false);
113 this->resetContext();
114 return true;
115 }
116
117 void VisualBench::resetContext() {
118 fInterface.reset(GrGLCreateNativeInterface());
119 SkASSERT(fInterface);
120
121 // setup contexts
122 fContext.reset(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fInter face.get()));
123 SkASSERT(fContext);
124
125 // setup rendertargets
126 this->setupRenderTarget();
127 }
128
129 void VisualBench::setupRenderTarget() {
130 if (fContext) {
131 fRenderTarget.reset(this->renderTarget(fAttachmentInfo, fInterface, fCon text));
132 }
133 }
134
135 inline void VisualBench::renderFrame(SkCanvas* canvas) {
136 for (int flush = 0; flush < fFlushes; flush++) {
137 for (int loop = 0; loop < fLoops; loop++) {
138 canvas->drawPicture(fPicture);
139 }
140 canvas->flush();
141 }
142 INHERITED::present();
143 }
144
145 void VisualBench::printStats() {
146 const SkTArray<double>& measurements = fRecords[fCurrentPictureIdx].fMeasure ments;
147 SkString shortName = SkOSPath::Basename(fRecords[fCurrentPictureIdx].fFilena me.c_str());
148 if (FLAGS_verbose) {
149 for (int i = 0; i < measurements.count(); i++) {
150 SkDebugf("%s ", HUMANIZE(measurements[i]));
151 }
152 SkDebugf("%s\n", shortName.c_str());
153 } else {
154 SkASSERT(measurements.count());
155 Stats stats(measurements);
156 const double stdDevPercent = 100 * sqrt(stats.var) / stats.mean;
157 SkDebugf("%4d/%-4dMB\t%d\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n",
158 sk_tools::getCurrResidentSetSizeMB(),
159 sk_tools::getMaxResidentSetSizeMB(),
160 fLoops,
161 fFlushes,
162 HUMANIZE(stats.min),
163 HUMANIZE(stats.median),
164 HUMANIZE(stats.mean),
165 HUMANIZE(stats.max),
166 stdDevPercent,
167 shortName.c_str());
168 }
169 }
170
171 bool VisualBench::advanceRecordIfNecessary() {
172 if (fPicture) {
173 return true;
174 }
175 ++fCurrentPictureIdx;
176 while (true) {
177 if (fCurrentPictureIdx >= fRecords.count()) {
178 return false;
179 }
180 if (this->loadPicture()) {
181 return true;
182 }
183 fRecords.removeShuffle(fCurrentPictureIdx);
184 }
185 }
186
187 bool VisualBench::loadPicture() {
188 const char* fileName = fRecords[fCurrentPictureIdx].fFilename.c_str();
189 SkFILEStream stream(fileName);
190 if (stream.isValid()) {
191 fPicture.reset(SkPicture::CreateFromStream(&stream));
192 if (SkToBool(fPicture)) {
193 return true;
194 }
195 }
196 SkDebugf("couldn't load picture at \"%s\"\n", fileName);
197 return false;
198 }
199
200 void VisualBench::preWarm(State nextState) {
201 if (fCurrentFrame >= FLAGS_gpuFrameLag) {
202 // we currently time across all frames to make sure we capture all GPU w ork
203 fState = nextState;
204 fCurrentFrame = 0;
205 fTimer.start();
206 } else {
207 fCurrentFrame++;
208 }
209 }
210
211 void VisualBench::draw(SkCanvas* canvas) {
212 if (!this->advanceRecordIfNecessary()) {
213 this->closeWindow();
214 return;
215 }
216 this->renderFrame(canvas);
217 switch (fState) {
218 case kPreWarmLoops_State: {
219 this->preWarm(kTuneLoops_State);
220 break;
221 }
222 case kTuneLoops_State: {
223 if (1 << 30 == fLoops) {
224 // We're about to wrap. Something's wrong with the bench.
225 SkDebugf("InnerLoops wrapped\n");
226 fLoops = 0;
227 } else {
228 fTimer.end();
229 double elapsed = fTimer.fWall;
230 if (elapsed > FLAGS_loopMs) {
231 fState = kPreWarmTiming_State;
232
233 // Scale back the number of loops
234 fLoops = (int)ceil(fLoops * FLAGS_loopMs / elapsed);
235 fFlushes = (int)ceil(FLAGS_flushMs / elapsed);
236 } else {
237 fState = kPreWarmLoops_State;
238 fLoops *= 2;
239 }
240
241 fCurrentFrame = 0;
242 fTimer = WallTimer();
243 this->resetContext();
244 }
245 break;
246 }
247 case kPreWarmTiming_State: {
248 this->preWarm(kTiming_State);
249 break;
250 }
251 case kTiming_State: {
252 if (fCurrentFrame >= FLAGS_frames) {
253 fTimer.end();
254 fRecords[fCurrentPictureIdx].fMeasurements.push_back(
255 fTimer.fWall / (FLAGS_frames * fLoops * fFlushes));
256 if (fCurrentSample++ >= FLAGS_samples) {
257 fState = kPreWarmLoops_State;
258 this->printStats();
259 fPicture.reset(NULL);
260 fCurrentSample = 0;
261 fFlushes = 1;
262 fLoops = 1;
263 } else {
264 fState = kPreWarmTiming_State;
265 }
266 fTimer = WallTimer();
267 this->resetContext();
268 fCurrentFrame = 0;
269 } else {
270 fCurrentFrame++;
271 }
272 break;
273 }
274 }
275
276 // Invalidate the window to force a redraw. Poor man's animation mechanism.
277 this->inval(NULL);
278 }
279
280 void VisualBench::onSizeChange() {
281 this->setupRenderTarget();
282 }
283
284 bool VisualBench::onHandleChar(SkUnichar unichar) {
285 return true;
286 }
287
288 // Externally declared entry points
289 void application_init() {
290 SkGraphics::Init();
291 SkEvent::Init();
292 }
293
294 void application_term() {
295 SkEvent::Term();
296 SkGraphics::Term();
297 }
298
299 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) {
300 return new VisualBench(hwnd, argc, argv);
301 }
302
OLDNEW
« no previous file with comments | « tools/VisualBench.h ('k') | tools/VisualBench/VisualBench.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698