blob: 1a30875c61b0d52f588eef1e56d138fa39243ed9 [file] [log] [blame]
joshualitt189aef72015-09-08 07:08:11 -07001/*
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#ifndef VisualLightweightBenchModule_DEFINED
10#define VisualLightweightBenchModule_DEFINED
11
12#include "VisualModule.h"
13
14#include "ResultsWriter.h"
15#include "SkPicture.h"
16#include "Timer.h"
17#include "VisualBench.h"
18#include "VisualBenchmarkStream.h"
19
20class SkCanvas;
21
22/*
23 * This module is designed to be a minimal overhead timing module for VisualBench
24 */
25class VisualLightweightBenchModule : public VisualModule {
26public:
27 // TODO get rid of backpointer
28 VisualLightweightBenchModule(VisualBench* owner);
29
30 void draw(SkCanvas* canvas) override;
31
jvanverthf5d1b2d2015-09-15 07:40:56 -070032 bool onHandleChar(SkUnichar c) override;
33
joshualitt189aef72015-09-08 07:08:11 -070034private:
35 /*
36 * The heart of visual bench is an event driven timing loop.
joshualitt7d4b4582015-09-24 08:08:23 -070037 * kWarmup_State: We run a dummy bench to let things settle on startup
joshualitt189aef72015-09-08 07:08:11 -070038 * kPreWarmLoopsPerCanvasPreDraw_State: Before we begin timing, Benchmarks have a hook to
39 * access the canvas. Then we prewarm before the autotune
40 * loops step.
41 * kPreWarmLoops_State: We prewarm the gpu before auto tuning to enter a steady
42 * work state
43 * kTuneLoops_State: Then we tune the loops of the benchmark to ensure we
44 * are doing a measurable amount of work
45 * kPreWarmTimingPerCanvasPreDraw_State: Because reset the context after tuning loops to ensure
46 * coherent state, we need to give the benchmark
47 * another hook
48 * kPreWarmTiming_State: We prewarm the gpu again to enter a steady state
49 * kTiming_State: Finally we time the benchmark. When finished timing
50 * if we have enough samples then we'll start the next
51 * benchmark in the kPreWarmLoopsPerCanvasPreDraw_State.
52 * otherwise, we enter the
53 * kPreWarmTimingPerCanvasPreDraw_State for another sample
54 * In either case we reset the context.
55 */
56 enum State {
joshualitt7d4b4582015-09-24 08:08:23 -070057 kWarmup_State,
joshualitt189aef72015-09-08 07:08:11 -070058 kPreWarmLoopsPerCanvasPreDraw_State,
59 kPreWarmLoops_State,
60 kTuneLoops_State,
61 kPreWarmTimingPerCanvasPreDraw_State,
62 kPreWarmTiming_State,
63 kTiming_State,
64 };
65 void setTitle();
66 bool setupBackend();
67 void setupRenderTarget();
68 void printStats();
69 bool advanceRecordIfNecessary(SkCanvas*);
70 inline void renderFrame(SkCanvas*);
71 inline void nextState(State);
72 void perCanvasPreDraw(SkCanvas*, State);
73 void preWarm(State nextState);
joshualitt189aef72015-09-08 07:08:11 -070074 inline void tuneLoops();
75 inline void timing(SkCanvas*);
76 inline double elapsed();
77 void resetTimingState();
78 void postDraw(SkCanvas*);
79 void recordMeasurement();
joshualitt7d4b4582015-09-24 08:08:23 -070080 void warmup(SkCanvas* canvas);
joshualitt189aef72015-09-08 07:08:11 -070081
82 struct Record {
83 SkTArray<double> fMeasurements;
84 };
85
86 int fCurrentSample;
87 int fCurrentFrame;
88 int fLoops;
89 SkTArray<Record> fRecords;
90 WallTimer fTimer;
91 State fState;
92 SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream;
93 SkAutoTUnref<Benchmark> fBenchmark;
94
95 // support framework
96 SkAutoTUnref<VisualBench> fOwner;
97 SkAutoTDelete<ResultsWriter> fResults;
98
99 typedef VisualModule INHERITED;
100};
101
102#endif