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