• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 #include "bench/Benchmark.h"
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkPaint.h"
10 #include "include/core/SkString.h"
11 #include "include/core/SkVertices.h"
12 #include "include/effects/SkGradientShader.h"
13 #include "src/utils/SkPatchUtils.h"
14 
15 /**
16  * This bench measures the rendering time of the call SkCanvas::drawPatch with different types of
17  * input patches (regular case, with loops, a square, with a big difference between "parallel"
18  * sides). This bench also tests the different combination of optional parameters for the function
19  * (passing texture coordinates and colors, only textures coordinates, only colors or none).
20  * Finally, it applies a scale to test if the size affects the rendering time.
21  */
22 
23 class PatchBench : public Benchmark {
24 
25 public:
26 
27     enum VertexMode {
28         kNone_VertexMode,
29         kColors_VertexMode,
30         kTexCoords_VertexMode,
31         kBoth_VertexMode
32     };
33 
PatchBench(SkPoint scale,VertexMode vertexMode)34     PatchBench(SkPoint scale, VertexMode vertexMode)
35     : fScale(scale)
36     , fVertexMode(vertexMode) { }
37 
38     // to add name of specific class override this method
appendName(SkString * name)39     virtual void appendName(SkString* name) {
40         name->append("normal");
41     }
42 
43     // to make other type of patches override this method
setCubics()44     virtual void setCubics() {
45         const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
46             //top points
47             {100,100},{150,50},{250,150}, {300,100},
48             //right points
49             {350, 150},{250,200},
50             //bottom points
51             {300,300},{250,250},{150,350},{100,300},
52             //left points
53             {50,250},{150,50}
54         };
55         memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
56     }
57 
setColors()58     virtual void setColors() {
59         const SkColor colors[SkPatchUtils::kNumCorners] = {
60             SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
61         };
62         memcpy(fColors, colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
63     }
64 
setTexCoords()65     virtual void setTexCoords() {
66         const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
67             {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f,1.0f}, {0.0f, 1.0f}
68         };
69         memcpy(fTexCoords, texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
70     }
71 
72     // override this method to change the shader
createShader()73     virtual sk_sp<SkShader> createShader() {
74         const SkColor colors[] = {
75             SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
76             SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
77         };
78         const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } };
79 
80         return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
81                                             SkTileMode::kMirror);
82     }
83 
84 protected:
onGetName()85     const char* onGetName() override {
86         SkString vertexMode;
87         switch (fVertexMode) {
88             case kNone_VertexMode:
89                 vertexMode.set("meshlines");
90                 break;
91             case kColors_VertexMode:
92                 vertexMode.set("colors");
93                 break;
94             case kTexCoords_VertexMode:
95                 vertexMode.set("texs");
96                 break;
97             case kBoth_VertexMode:
98                 vertexMode.set("colors_texs");
99                 break;
100             default:
101                 break;
102         }
103         SkString type;
104         this->appendName(&type);
105         fName.printf("patch_%s_%s_%fx%f", type.c_str(), vertexMode.c_str(),
106                     fScale.x(), fScale.y());
107         return fName.c_str();
108     }
109 
onDelayedSetup()110     void onDelayedSetup() override {
111         this->setCubics();
112         this->setColors();
113         this->setTexCoords();
114         this->setupPaint(&fPaint);
115         switch (fVertexMode) {
116             case kTexCoords_VertexMode:
117             case kBoth_VertexMode:
118                 fPaint.setShader(this->createShader());
119                 break;
120             default:
121                 fPaint.setShader(nullptr);
122                 break;
123         }
124     }
125 
onDraw(int loops,SkCanvas * canvas)126     void onDraw(int loops, SkCanvas* canvas) override {
127         canvas->scale(fScale.x(), fScale.y());
128         for (int i = 0; i < loops; i++) {
129             switch (fVertexMode) {
130                 case kNone_VertexMode:
131                     canvas->drawPatch(fCubics, nullptr, nullptr, fPaint);
132                     break;
133                 case kColors_VertexMode:
134                     canvas->drawPatch(fCubics, fColors, nullptr, fPaint);
135                     break;
136                 case kTexCoords_VertexMode:
137                     canvas->drawPatch(fCubics, nullptr, fTexCoords, fPaint);
138                     break;
139                 case kBoth_VertexMode:
140                     canvas->drawPatch(fCubics, fColors, fTexCoords, fPaint);
141                     break;
142                 default:
143                     break;
144             }
145         }
146     }
147 
148     SkPaint     fPaint;
149     SkString    fName;
150     SkVector    fScale;
151     SkPoint     fCubics[12];
152     SkPoint     fTexCoords[4];
153     SkColor     fColors[4];
154     VertexMode  fVertexMode;
155 
156     using INHERITED = Benchmark;
157 };
158 
159 class SquarePatchBench : public PatchBench {
160 public:
SquarePatchBench(SkPoint scale,VertexMode vertexMode)161     SquarePatchBench(SkPoint scale, VertexMode vertexMode)
162     : INHERITED(scale, vertexMode) { }
163 
appendName(SkString * name)164     void appendName(SkString* name) override {
165         name->append("square");
166     }
167 
setCubics()168     void setCubics() override {
169         const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
170             //top points
171             {100,100},{150,100},{250,100}, {300,100},
172             //right points
173             {300, 150},{300,250},
174             //bottom points
175             {300,300},{250,300},{150,300},{100,300},
176             //left points
177             {100,250},{100,150}
178         };
179         memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
180     }
181 private:
182     using INHERITED = PatchBench;
183 };
184 
185 class LODDiffPatchBench : public PatchBench {
186 public:
LODDiffPatchBench(SkPoint scale,VertexMode vertexMode)187     LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
188     : INHERITED(scale, vertexMode) { }
189 
appendName(SkString * name)190     void appendName(SkString* name) override {
191         name->append("LOD_Diff");
192     }
193 
setCubics()194     void setCubics() override {
195         const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
196             //top points
197             {100,175},{150,100},{250,100}, {300,0},
198             //right points
199             {300, 150},{300,250},
200             //bottom points
201             {300,400},{250,300},{150,300},{100,225},
202             //left points
203             {100,215},{100,185}
204         };
205         memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
206     }
207 private:
208     using INHERITED = PatchBench;
209 };
210 
211 class LoopPatchBench : public PatchBench {
212 public:
LoopPatchBench(SkPoint scale,VertexMode vertexMode)213     LoopPatchBench(SkPoint scale, VertexMode vertexMode)
214     : INHERITED(scale, vertexMode) { }
215 
appendName(SkString * name)216     void appendName(SkString* name) override {
217         name->append("loop");
218     }
219 
setCubics()220     void setCubics() override {
221         const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
222             //top points
223             {100,100},{300,200},{100,200}, {300,100},
224             //right points
225             {380, 400},{380,0},
226             //bottom points
227             {300,300},{250,250},{30,200},{100,300},
228             //left points
229             {140,325},{150,150}
230         };
231         memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
232     }
233 private:
234     using INHERITED = PatchBench;
235 };
236 
237 ///////////////////////////////////////////////////////////////////////////////
238 
239 DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kNone_VertexMode); )
240 DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kColors_VertexMode); )
241 DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kTexCoords_VertexMode); )
242 DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kBoth_VertexMode); )
243 DEF_BENCH( return new PatchBench(SkVector::Make(1.f, 1.0f), PatchBench::kNone_VertexMode); )
244 DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kColors_VertexMode); )
245 DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kTexCoords_VertexMode); )
246 DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kBoth_VertexMode); )
247 DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kNone_VertexMode); )
248 DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kColors_VertexMode); )
249 DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kTexCoords_VertexMode); )
250 DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kBoth_VertexMode); )
251 
252 DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
253                                        PatchBench::kNone_VertexMode); )
254 DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
255                                        PatchBench::kColors_VertexMode); )
256 DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
257                                        PatchBench::kTexCoords_VertexMode); )
258 DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
259                                        PatchBench::kBoth_VertexMode); )
260 DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.f, 1.0f),
261                                        PatchBench::kNone_VertexMode); )
262 DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
263                                        PatchBench::kColors_VertexMode); )
264 DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
265                                        PatchBench::kTexCoords_VertexMode); )
266 DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
267                                        PatchBench::kBoth_VertexMode); )
268 DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
269                                        PatchBench::kNone_VertexMode); )
270 DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
271                                        PatchBench::kColors_VertexMode); )
272 DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
273                                        PatchBench::kTexCoords_VertexMode); )
274 DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
275                                        PatchBench::kBoth_VertexMode); )
276 
277 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
278                                        PatchBench::kNone_VertexMode); )
279 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
280                                        PatchBench::kColors_VertexMode); )
281 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
282                                        PatchBench::kTexCoords_VertexMode); )
283 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
284                                        PatchBench::kBoth_VertexMode); )
285 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.f, 1.0f),
286                                        PatchBench::kNone_VertexMode); )
287 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
288                                        PatchBench::kColors_VertexMode); )
289 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
290                                        PatchBench::kTexCoords_VertexMode); )
291 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
292                                        PatchBench::kBoth_VertexMode); )
293 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
294                                        PatchBench::kNone_VertexMode); )
295 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
296                                        PatchBench::kColors_VertexMode); )
297 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
298                                        PatchBench::kTexCoords_VertexMode); )
299 DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
300                                        PatchBench::kBoth_VertexMode); )
301 
302 DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
303                                         PatchBench::kNone_VertexMode); )
304 DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
305                                         PatchBench::kColors_VertexMode); )
306 DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
307                                         PatchBench::kTexCoords_VertexMode); )
308 DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
309                                         PatchBench::kBoth_VertexMode); )
310 DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.f, 1.0f),
311                                         PatchBench::kNone_VertexMode); )
312 DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
313                                         PatchBench::kColors_VertexMode); )
314 DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
315                                         PatchBench::kTexCoords_VertexMode); )
316 DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
317                                         PatchBench::kBoth_VertexMode); )
318 DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
319                                         PatchBench::kNone_VertexMode); )
320 DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
321                                         PatchBench::kColors_VertexMode); )
322 DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
323                                         PatchBench::kTexCoords_VertexMode); )
324 DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
325                                         PatchBench::kBoth_VertexMode); )
326 
327 //////////////////////////////////////////////
328 #include "src/utils/SkPatchUtils.h"
329 
330 class PatchUtilsBench : public Benchmark {
331     SkString    fName;
332     const bool  fLinearInterp;
333 public:
PatchUtilsBench(bool linearInterp)334     PatchUtilsBench(bool linearInterp) : fLinearInterp(linearInterp) {
335         fName.printf("patchutils_%s", linearInterp ? "linear" : "legacy");
336     }
337 
onGetName()338     const char* onGetName() override { return fName.c_str(); }
339 
isSuitableFor(Backend backend)340     bool isSuitableFor(Backend backend) override {
341         return backend == kNonRendering_Backend;
342     }
343 
onDraw(int loops,SkCanvas *)344     void onDraw(int loops, SkCanvas*) override {
345         const SkColor colors[] = { 0xFF000000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 };
346         const SkPoint pts[] = {
347             { 0, 0 }, { 10, 0 }, { 20, 0 }, { 30, 0 },
348             { 30,10}, { 30,20 }, { 30,30 }, { 20,30 },
349             { 10,30}, { 0, 30 }, { 0, 20 }, { 0, 10 },
350         };
351         const SkPoint tex[] = {
352             { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 },
353         };
354 
355         auto cs = fLinearInterp ? SkColorSpace::MakeSRGBLinear() : nullptr;
356         for (int i = 0; i < 100*loops; ++i) {
357             SkPatchUtils::MakeVertices(pts, colors, tex, 20, 20, cs.get());
358         }
359     }
360 };
361 DEF_BENCH( return new PatchUtilsBench(false); )
362 DEF_BENCH( return new PatchUtilsBench(true); )
363