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 for (int i = 0; i < 100*loops; ++i) { 355 SkPatchUtils::MakeVertices(pts, colors, tex, 20, 20, fLinearInterp); 356 } 357 } 358 }; 359 DEF_BENCH( return new PatchUtilsBench(false); ) 360 DEF_BENCH( return new PatchUtilsBench(true); ) 361