blob: 5d4869210b08d8d883946ffa3b6a399e967c4544 [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.
37 * kPreWarmLoopsPerCanvasPreDraw_State: Before we begin timing, Benchmarks have a hook to
38 * access the canvas. Then we prewarm before the autotune
39 * loops step.
40 * kPreWarmLoops_State: We prewarm the gpu before auto tuning to enter a steady
41 * work state
42 * kTuneLoops_State: Then we tune the loops of the benchmark to ensure we
43 * are doing a measurable amount of work
44 * kPreWarmTimingPerCanvasPreDraw_State: Because reset the context after tuning loops to ensure
45 * coherent state, we need to give the benchmark
46 * another hook
47 * kPreWarmTiming_State: We prewarm the gpu again to enter a steady state
48 * kTiming_State: Finally we time the benchmark. When finished timing
49 * if we have enough samples then we'll start the next
50 * benchmark in the kPreWarmLoopsPerCanvasPreDraw_State.
51 * otherwise, we enter the
52 * kPreWarmTimingPerCanvasPreDraw_State for another sample
53 * In either case we reset the context.
54 */
55 enum State {
56 kPreWarmLoopsPerCanvasPreDraw_State,
57 kPreWarmLoops_State,
58 kTuneLoops_State,
59 kPreWarmTimingPerCanvasPreDraw_State,
60 kPreWarmTiming_State,
61 kTiming_State,
62 };
63 void setTitle();
64 bool setupBackend();
65 void setupRenderTarget();
66 void printStats();
67 bool advanceRecordIfNecessary(SkCanvas*);
68 inline void renderFrame(SkCanvas*);
69 inline void nextState(State);
70 void perCanvasPreDraw(SkCanvas*, State);
71 void preWarm(State nextState);
72 void scaleLoops(double elapsedMs);
73 inline void tuneLoops();
74 inline void timing(SkCanvas*);
75 inline double elapsed();
76 void resetTimingState();
77 void postDraw(SkCanvas*);
78 void recordMeasurement();
79
80 struct Record {
81 SkTArray<double> fMeasurements;
82 };
83
84 int fCurrentSample;
85 int fCurrentFrame;
86 int fLoops;
87 SkTArray<Record> fRecords;
88 WallTimer fTimer;
89 State fState;
90 SkAutoTDelete<VisualBenchmarkStream> fBenchmarkStream;
91 SkAutoTUnref<Benchmark> fBenchmark;
92
93 // support framework
94 SkAutoTUnref<VisualBench> fOwner;
95 SkAutoTDelete<ResultsWriter> fResults;
96
97 typedef VisualModule INHERITED;
98};
99
100#endif