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