| /* | 
 |  * 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 "Benchmark.h" | 
 | #include "SkCanvas.h" | 
 | #include "SkDrawShadowInfo.h" | 
 | #include "SkPaint.h" | 
 | #include "SkPath.h" | 
 | #include "SkShadowUtils.h" | 
 |  | 
 | class ShadowBench : public Benchmark { | 
 | // Draws a set of shadowed rrects filling the canvas, in various modes: | 
 | // * opaque or transparent | 
 | // * use analytic fast path or geometric tessellation | 
 | public: | 
 |     ShadowBench(bool transparent, bool forceGeometric) | 
 |         : fTransparent(transparent) | 
 |         , fForceGeometric(forceGeometric) { | 
 |         computeName("shadows"); | 
 |     } | 
 |  | 
 |     bool isVisual() override { return true; } | 
 |  | 
 | protected: | 
 |     enum { | 
 |         kWidth = 640, | 
 |         kHeight = 480, | 
 |         kRRSize = 50, | 
 |         kRRRadius = 6, | 
 |         kRRSpace = 8, | 
 |         kRRStep = kRRSize + kRRSpace, | 
 |         kElevation = 16, | 
 |         kNumRRects = ((kWidth - kRRSpace) / kRRStep)*((kHeight - kRRSpace) / kRRStep) | 
 |     }; | 
 |  | 
 |     void computeName(const char root[]) { | 
 |         static const char kTransChars[2] = { | 
 |             'o', 't' | 
 |         }; | 
 |         static const char kGeomChars[2] = { | 
 |             'a', 'g' | 
 |         }; | 
 |  | 
 |         fBaseName.printf("%s_%c_%c", root, kTransChars[fTransparent], kGeomChars[fForceGeometric]); | 
 |     } | 
 |  | 
 |     void genRRects() { | 
 |         int i = 0; | 
 |         for (int x = kRRSpace; x < kWidth - kRRStep; x += kRRStep) { | 
 |             for (int y = kRRSpace; y < kHeight - kRRStep; y += kRRStep) { | 
 |                 SkRect rect = SkRect::MakeXYWH(x, y, kRRSize, kRRSize); | 
 |                 fRRects[i].addRRect(SkRRect::MakeRectXY(rect, kRRRadius, kRRRadius)); | 
 |                 ++i; | 
 |             } | 
 |         } | 
 |         SkASSERT(i == kNumRRects); | 
 |     } | 
 |  | 
 |     const char* onGetName() override { return fBaseName.c_str(); } | 
 |  | 
 |     void onDelayedSetup() override { | 
 |         fRec.fZPlaneParams = SkPoint3::Make(0, 0, kElevation); | 
 |         fRec.fLightPos = SkPoint3::Make(270, 0, 600); | 
 |         fRec.fLightRadius = 800; | 
 |         fRec.fAmbientColor = 0x19000000; | 
 |         fRec.fSpotColor = 0x40000000; | 
 |         fRec.fFlags = 0; | 
 |         if (fTransparent) { | 
 |             fRec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag; | 
 |         } | 
 |         if (fForceGeometric) { | 
 |             fRec.fFlags |= SkShadowFlags::kGeometricOnly_ShadowFlag; | 
 |         } | 
 |  | 
 |         this->genRRects(); | 
 |     } | 
 |  | 
 |     void onDraw(int loops, SkCanvas* canvas) override { | 
 |         SkPaint paint; | 
 |         paint.setColor(SK_ColorWHITE); | 
 |         this->setupPaint(&paint); | 
 |  | 
 |         for (int i = 0; i < loops; ++i) { | 
 |             // use the private canvas call so we don't include the time to stuff data in the Rec | 
 |             canvas->private_draw_shadow_rec(fRRects[i % kNumRRects], fRec); | 
 |         } | 
 |     } | 
 |  | 
 | private: | 
 |     SkString fBaseName; | 
 |  | 
 |     SkPath  fRRects[kNumRRects]; | 
 |     SkDrawShadowRec fRec; | 
 |     int    fTransparent; | 
 |     int    fForceGeometric; | 
 |  | 
 |     typedef Benchmark INHERITED; | 
 | }; | 
 |  | 
 | DEF_BENCH(return new ShadowBench(false, false);) | 
 | DEF_BENCH(return new ShadowBench(false, true);) | 
 | DEF_BENCH(return new ShadowBench(true, false);) | 
 | DEF_BENCH(return new ShadowBench(true, true);) | 
 |  |