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 
17 template <int kDraws, bool kLite>
18 struct 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 
56 DEF_BENCH(return (new PictureOverheadBench<0, false>);)
57 DEF_BENCH(return (new PictureOverheadBench<1, false>);)
58 DEF_BENCH(return (new PictureOverheadBench<2, false>);)
59 DEF_BENCH(return (new PictureOverheadBench<10,false>);)
60 DEF_BENCH(return (new PictureOverheadBench<0,  true>);)
61 DEF_BENCH(return (new PictureOverheadBench<1,  true>);)
62 DEF_BENCH(return (new PictureOverheadBench<2,  true>);)
63 DEF_BENCH(return (new PictureOverheadBench<10, true>);)
64 
65 ///////////////////////////////////////////////////////////////////////////////////////////////////
66 
67 class ClipOverheadRecordingBench : public Benchmark {
68     SkString fName;
69     const bool fDoLite;
70 
71 public:
72     ClipOverheadRecordingBench(bool doLite) : fDoLite(doLite) {
73         fName.printf("clip_overhead_recording_%s", doLite ? "lite" : "std");
74     }
75 
76 protected:
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 };
115 DEF_BENCH( return new ClipOverheadRecordingBench(true); )
116 DEF_BENCH( return new ClipOverheadRecordingBench(false); )
117