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 8 #include "Benchmark.h" 9 #include "SkRandom.h" 10 #include "SkSize.h" 11 #include "SkTDArray.h" 12 13 #include "GrRectanizer_pow2.h" 14 #include "GrRectanizer_skyline.h" 15 16 /** 17 * This bench exercises Ganesh' GrRectanizer classes. It exercises the following 18 * rectanizers: 19 * Pow2 Rectanizer 20 * Skyline Rectanizer 21 * in the following cases: 22 * random rects (e.g., pull-save-layers forward use case) 23 * random power of two rects 24 * small constant sized power of 2 rects (e.g., glyph cache use case) 25 */ 26 class RectanizerBench : public Benchmark { 27 public: 28 static const int kWidth = 1024; 29 static const int kHeight = 1024; 30 31 enum RectanizerType { 32 kPow2_RectanizerType, 33 kSkyline_RectanizerType, 34 }; 35 36 enum RectType { 37 kRand_RectType, 38 kRandPow2_RectType, 39 kSmallPow2_RectType 40 }; 41 RectanizerBench(RectanizerType rectanizerType,RectType rectType)42 RectanizerBench(RectanizerType rectanizerType, RectType rectType) 43 : fName("rectanizer_") 44 , fRectanizerType(rectanizerType) 45 , fRectType(rectType) { 46 47 if (kPow2_RectanizerType == fRectanizerType) { 48 fName.append("pow2_"); 49 } else { 50 SkASSERT(kSkyline_RectanizerType == fRectanizerType); 51 fName.append("skyline_"); 52 } 53 54 if (kRand_RectType == fRectType) { 55 fName.append("rand"); 56 } else if (kRandPow2_RectType == fRectType) { 57 fName.append("rand2"); 58 } else { 59 SkASSERT(kSmallPow2_RectType == fRectType); 60 fName.append("sm2"); 61 } 62 } 63 64 protected: isSuitableFor(Backend backend)65 bool isSuitableFor(Backend backend) override { 66 return kNonRendering_Backend == backend; 67 } 68 onGetName()69 const char* onGetName() override { 70 return fName.c_str(); 71 } 72 onDelayedSetup()73 void onDelayedSetup() override { 74 SkASSERT(nullptr == fRectanizer.get()); 75 76 if (kPow2_RectanizerType == fRectanizerType) { 77 fRectanizer.reset(new GrRectanizerPow2(kWidth, kHeight)); 78 } else { 79 SkASSERT(kSkyline_RectanizerType == fRectanizerType); 80 fRectanizer.reset(new GrRectanizerSkyline(kWidth, kHeight)); 81 } 82 } 83 onDraw(int loops,SkCanvas * canvas)84 void onDraw(int loops, SkCanvas* canvas) override { 85 SkRandom rand; 86 SkIPoint16 loc; 87 SkISize size; 88 89 for (int i = 0; i < loops; ++i) { 90 if (kRand_RectType == fRectType) { 91 size = SkISize::Make(rand.nextRangeU(1, kWidth / 2), 92 rand.nextRangeU(1, kHeight / 2)); 93 } else if (kRandPow2_RectType == fRectType) { 94 size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)), 95 GrNextPow2(rand.nextRangeU(1, kHeight / 2))); 96 } else { 97 SkASSERT(kSmallPow2_RectType == fRectType); 98 size = SkISize::Make(128, 128); 99 } 100 101 if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) { 102 // insert failed so clear out the rectanizer and give the 103 // current rect another try 104 fRectanizer->reset(); 105 i--; 106 } 107 } 108 109 fRectanizer->reset(); 110 } 111 112 private: 113 SkString fName; 114 RectanizerType fRectanizerType; 115 RectType fRectType; 116 std::unique_ptr<GrRectanizer> fRectanizer; 117 118 typedef Benchmark INHERITED; 119 }; 120 121 ////////////////////////////////////////////////////////////////////////////// 122 123 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 124 RectanizerBench::kRand_RectType);) 125 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 126 RectanizerBench::kRandPow2_RectType);) 127 DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 128 RectanizerBench::kSmallPow2_RectType);) 129 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 130 RectanizerBench::kRand_RectType);) 131 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 132 RectanizerBench::kRandPow2_RectType);) 133 DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 134 RectanizerBench::kSmallPow2_RectType);) 135