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