| /* | 
 |  * Copyright 2017 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "bench/Benchmark.h" | 
 | #include "include/core/SkCanvas.h" | 
 | #include "include/core/SkPath.h" | 
 | #include "include/pathops/SkPathOps.h" | 
 |  | 
 | class ClipStrategyBench : public Benchmark { | 
 | public: | 
 |     enum class Mode { | 
 |         kClipPath, | 
 |         kMask, | 
 |     }; | 
 |  | 
 |     ClipStrategyBench(Mode mode, size_t count) | 
 |         : fMode(mode) | 
 |         , fCount(count) | 
 |         , fName("clip_strategy_"){ | 
 |  | 
 |         if (fMode == Mode::kClipPath) { | 
 |             fName.append("path_"); | 
 |             this->forEachClipCircle([&](float x, float y, float r) { | 
 |                 fClipPath.addCircle(x, y, r); | 
 |             }); | 
 |         } else { | 
 |             fName.append("mask_"); | 
 |         } | 
 |         fName.appendf("%zu", count); | 
 |     } | 
 |  | 
 |     ~ClipStrategyBench() override = default; | 
 |  | 
 | protected: | 
 |     const char* onGetName() override { | 
 |         return fName.c_str(); | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas* canvas) override { | 
 |         SkPaint p, srcIn; | 
 |         p.setAntiAlias(true); | 
 |         srcIn.setBlendMode(SkBlendMode::kSrcIn); | 
 |  | 
 |         for (int i = 0; i < loops; ++i) { | 
 |             SkAutoCanvasRestore acr(canvas, false); | 
 |  | 
 |             if (fMode == Mode::kClipPath) { | 
 |                 canvas->save(); | 
 |                 canvas->clipPath(fClipPath, true); | 
 |             } else { | 
 |                 canvas->saveLayer(nullptr, nullptr); | 
 |                 this->forEachClipCircle([&](float x, float y, float r) { | 
 |                     canvas->drawCircle(x, y, r, p); | 
 |                 }); | 
 |                 canvas->saveLayer(nullptr, &srcIn); | 
 |             } | 
 |             canvas->drawColor(SK_ColorGREEN); | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     template <typename Func> | 
 |     void forEachClipCircle(Func&& func) { | 
 |         auto q = static_cast<float>(this->getSize().x()) / (fCount + 1); | 
 |         for (size_t i = 1; i <= fCount; ++i) { | 
 |             auto x = q * i; | 
 |             func(x, x, q / 2); | 
 |         } | 
 |     } | 
 |  | 
 |     Mode     fMode; | 
 |     size_t   fCount; | 
 |     SkString fName; | 
 |     SkPath   fClipPath; | 
 |  | 
 |     typedef Benchmark INHERITED; | 
 | }; | 
 |  | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 1  );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 5  );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 10 );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 100);) | 
 |  | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 1  );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 5  );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 10 );) | 
 | DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 100);) |