Home | History | Annotate | Download | only in bench
      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 
     33     PatchBench(SkPoint scale, VertexMode vertexMode)
     34     : fScale(scale)
     35     , fVertexMode(vertexMode) { }
     36 
     37     // to add name of specific class override this method
     38     virtual void appendName(SkString* name) {
     39         name->append("normal");
     40     }
     41 
     42     // to make other type of patches override this method
     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 
     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 
     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
     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:
     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 
    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 
    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:
    160     SquarePatchBench(SkPoint scale, VertexMode vertexMode)
    161     : INHERITED(scale, vertexMode) { }
    162 
    163     void appendName(SkString* name) override {
    164         name->append("square");
    165     }
    166 
    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:
    186     LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
    187     : INHERITED(scale, vertexMode) { }
    188 
    189     void appendName(SkString* name) override {
    190         name->append("LOD_Diff");
    191     }
    192 
    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:
    212     LoopPatchBench(SkPoint scale, VertexMode vertexMode)
    213     : INHERITED(scale, vertexMode) { }
    214 
    215     void appendName(SkString* name) override {
    216         name->append("loop");
    217     }
    218 
    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:
    333     PatchUtilsBench(bool linearInterp) : fLinearInterp(linearInterp) {
    334         fName.printf("patchutils_%s", linearInterp ? "linear" : "legacy");
    335     }
    336 
    337     const char* onGetName() override { return fName.c_str(); }
    338 
    339     bool isSuitableFor(Backend backend) override {
    340         return backend == kNonRendering_Backend;
    341     }
    342 
    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