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// A benchmark designed to isolate the constant overheads of picture recording.
9// We record an empty picture and a picture with one draw op to force memory allocation.
10
11#include "Benchmark.h"
12#include "SkCanvas.h"
13#include "SkLiteDL.h"
14#include "SkLiteRecorder.h"
15#include "SkPictureRecorder.h"
16
17template <int kDraws, bool kLite>
18struct PictureOverheadBench : public Benchmark {
19    PictureOverheadBench() {
20        fName.appendf("picture_overhead_%d%s", kDraws, kLite ? "_lite" : "");
21    }
22    const char* onGetName() override { return fName.c_str(); }
23    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
24
25    void onDraw(int loops, SkCanvas*) override {
26        SkLiteRecorder lite;
27        SkPictureRecorder rec;
28
29        SkIRect iBounds = {0,0, 2000,3000};
30        SkRect bounds = SkRect::Make(iBounds);
31
32        for (int i = 0; i < loops; i++) {
33            SkLiteDL liteDL;
34            SkCanvas* canvas;
35            if (kLite) {
36                lite.reset(&liteDL, iBounds);
37                canvas = &lite;
38            } else {
39                rec.beginRecording(bounds);
40                canvas = rec.getRecordingCanvas();
41            }
42
43            for (int i = 0; i < kDraws; i++) {
44                canvas->drawRect({10,10, 1000, 1000}, SkPaint{});
45            }
46
47            if (!kLite) {
48                (void)rec.finishRecordingAsPicture();
49            }
50        }
51    }
52
53    SkString fName;
54};
55
56DEF_BENCH(return (new PictureOverheadBench<0, false>);)
57DEF_BENCH(return (new PictureOverheadBench<1, false>);)
58DEF_BENCH(return (new PictureOverheadBench<2, false>);)
59DEF_BENCH(return (new PictureOverheadBench<10,false>);)
60DEF_BENCH(return (new PictureOverheadBench<0,  true>);)
61DEF_BENCH(return (new PictureOverheadBench<1,  true>);)
62DEF_BENCH(return (new PictureOverheadBench<2,  true>);)
63DEF_BENCH(return (new PictureOverheadBench<10, true>);)
64
65///////////////////////////////////////////////////////////////////////////////////////////////////
66
67class ClipOverheadRecordingBench : public Benchmark {
68    SkString fName;
69    const bool fDoLite;
70
71public:
72    ClipOverheadRecordingBench(bool doLite) : fDoLite(doLite) {
73        fName.printf("clip_overhead_recording_%s", doLite ? "lite" : "std");
74    }
75
76protected:
77    const char* onGetName() override { return fName.c_str(); }
78    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
79
80    void onDraw(int loops, SkCanvas*) override {
81        SkLiteRecorder lite;
82        SkPictureRecorder rec;
83
84        SkIRect iBounds = {0,0, 2000,3000};
85        SkRect bounds = SkRect::Make(iBounds);
86
87        for (int i = 0; i < loops; i++) {
88            SkLiteDL liteDL;
89            SkCanvas* canvas;
90            if (fDoLite) {
91                lite.reset(&liteDL, iBounds);
92                canvas = &lite;
93            } else {
94                rec.beginRecording(bounds);
95                canvas = rec.getRecordingCanvas();
96            }
97
98            SkPaint paint;
99            SkRRect rrect;
100            rrect.setOval({0, 0, 1000, 1000});
101            for (int i = 0; i < 1000; i++) {
102                canvas->save();
103                canvas->translate(10, 10);
104                canvas->clipRect({10,10, 1000, 1000});
105                canvas->drawRRect(rrect, paint);
106                canvas->restore();
107            }
108
109            if (!fDoLite) {
110                (void)rec.finishRecordingAsPicture();
111            }
112        }
113    }
114};
115DEF_BENCH( return new ClipOverheadRecordingBench(true); )
116DEF_BENCH( return new ClipOverheadRecordingBench(false); )
117