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