/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkBenchmark.h" #include "SkRandom.h" #include "SkSize.h" #include "SkTDArray.h" #if SK_SUPPORT_GPU #include "GrRectanizer_pow2.h" #include "GrRectanizer_skyline.h" /** * This bench exercises Ganesh' GrRectanizer classes. It exercises the following * rectanizers: * Pow2 Rectanizer * Skyline Rectanizer * in the following cases: * random rects (e.g., pull-save-layers forward use case) * random power of two rects * small constant sized power of 2 rects (e.g., glyph cache use case) */ class RectanizerBench : public SkBenchmark { public: static const int kWidth = 1024; static const int kHeight = 1024; enum RectanizerType { kPow2_RectanizerType, kSkyline_RectanizerType, }; enum RectType { kRand_RectType, kRandPow2_RectType, kSmallPow2_RectType }; RectanizerBench(RectanizerType rectanizerType, RectType rectType) : fName("rectanizer_") , fRectanizerType(rectanizerType) , fRectType(rectType) { if (kPow2_RectanizerType == fRectanizerType) { fName.append("pow2_"); } else { SkASSERT(kSkyline_RectanizerType == fRectanizerType); fName.append("skyline_"); } if (kRand_RectType == fRectType) { fName.append("rand"); } else if (kRandPow2_RectType == fRectType) { fName.append("rand2"); } else { SkASSERT(kSmallPow2_RectType == fRectType); fName.append("sm2"); } } protected: virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { return kNonRendering_Backend == backend; } virtual const char* onGetName() SK_OVERRIDE { return fName.c_str(); } virtual void onPreDraw() SK_OVERRIDE { SkASSERT(NULL == fRectanizer.get()); if (kPow2_RectanizerType == fRectanizerType) { fRectanizer.reset(SkNEW_ARGS(GrRectanizerPow2, (kWidth, kHeight))); } else { SkASSERT(kSkyline_RectanizerType == fRectanizerType); fRectanizer.reset(SkNEW_ARGS(GrRectanizerSkyline, (kWidth, kHeight))); } } virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE { SkRandom rand; SkIPoint16 loc; SkISize size; for (int i = 0; i < loops; ++i) { if (kRand_RectType == fRectType) { size = SkISize::Make(rand.nextRangeU(1, kWidth / 2), rand.nextRangeU(1, kHeight / 2)); } else if (kRandPow2_RectType == fRectType) { size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)), GrNextPow2(rand.nextRangeU(1, kHeight / 2))); } else { SkASSERT(kSmallPow2_RectType == fRectType); size = SkISize::Make(128, 128); } if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) { // insert failed so clear out the rectanizer and give the // current rect another try fRectanizer->reset(); i--; } } fRectanizer->reset(); } private: SkString fName; RectanizerType fRectanizerType; RectType fRectType; SkAutoTDelete fRectanizer; typedef SkBenchmark INHERITED; }; ////////////////////////////////////////////////////////////////////////////// DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, RectanizerBench::kRand_RectType);) DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, RectanizerBench::kRandPow2_RectType);) DEF_BENCH(return new RectanizerBench(RectanizerBench::kPow2_RectanizerType, RectanizerBench::kSmallPow2_RectType);) DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, RectanizerBench::kRand_RectType);) DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, RectanizerBench::kRandPow2_RectType);) DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType, RectanizerBench::kSmallPow2_RectType);) #endif