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 */ 28class RectanizerBench : public Benchmark { 29public: 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 66protected: 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 onPreDraw() override { 76 SkASSERT(NULL == fRectanizer.get()); 77 78 if (kPow2_RectanizerType == fRectanizerType) { 79 fRectanizer.reset(SkNEW_ARGS(GrRectanizerPow2, (kWidth, kHeight))); 80 } else { 81 SkASSERT(kSkyline_RectanizerType == fRectanizerType); 82 fRectanizer.reset(SkNEW_ARGS(GrRectanizerSkyline, (kWidth, kHeight))); 83 } 84 } 85 86 void onDraw(const 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 114private: 115 SkString fName; 116 RectanizerType fRectanizerType; 117 RectType fRectType; 118 SkAutoTDelete<GrRectanizer> fRectanizer; 119 120 typedef Benchmark INHERITED; 121}; 122 123////////////////////////////////////////////////////////////////////////////// 124 125DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 126 RectanizerBench::kRand_RectType);) 127DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 128 RectanizerBench::kRandPow2_RectType);) 129DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, 130 RectanizerBench::kSmallPow2_RectType);) 131DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 132 RectanizerBench::kRand_RectType);) 133DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 134 RectanizerBench::kRandPow2_RectType);) 135DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, 136 RectanizerBench::kSmallPow2_RectType);) 137 138#endif 139