1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci#include "bench/Benchmark.h"
8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h"
9cb93a386Sopenharmony_ci#include "include/core/SkPaint.h"
10cb93a386Sopenharmony_ci#include "include/core/SkPath.h"
11cb93a386Sopenharmony_ci#include "include/utils/SkShadowUtils.h"
12cb93a386Sopenharmony_ci#include "src/core/SkDrawShadowInfo.h"
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciclass ShadowBench : public Benchmark {
15cb93a386Sopenharmony_ci// Draws a set of shadowed rrects filling the canvas, in various modes:
16cb93a386Sopenharmony_ci// * opaque or transparent
17cb93a386Sopenharmony_ci// * use analytic fast path or geometric tessellation
18cb93a386Sopenharmony_cipublic:
19cb93a386Sopenharmony_ci    ShadowBench(bool transparent, bool forceGeometric)
20cb93a386Sopenharmony_ci        : fTransparent(transparent)
21cb93a386Sopenharmony_ci        , fForceGeometric(forceGeometric) {
22cb93a386Sopenharmony_ci        computeName("shadows");
23cb93a386Sopenharmony_ci    }
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ciprotected:
26cb93a386Sopenharmony_ci    enum {
27cb93a386Sopenharmony_ci        kWidth = 640,
28cb93a386Sopenharmony_ci        kHeight = 480,
29cb93a386Sopenharmony_ci        kRRSize = 50,
30cb93a386Sopenharmony_ci        kRRRadius = 6,
31cb93a386Sopenharmony_ci        kRRSpace = 8,
32cb93a386Sopenharmony_ci        kRRStep = kRRSize + kRRSpace,
33cb93a386Sopenharmony_ci        kElevation = 16,
34cb93a386Sopenharmony_ci        kNumRRects = ((kWidth - kRRSpace) / kRRStep)*((kHeight - kRRSpace) / kRRStep)
35cb93a386Sopenharmony_ci    };
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci    void computeName(const char root[]) {
38cb93a386Sopenharmony_ci        static const char kTransChars[2] = {
39cb93a386Sopenharmony_ci            'o', 't'
40cb93a386Sopenharmony_ci        };
41cb93a386Sopenharmony_ci        static const char kGeomChars[2] = {
42cb93a386Sopenharmony_ci            'a', 'g'
43cb93a386Sopenharmony_ci        };
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci        fBaseName.printf("%s_%c_%c", root, kTransChars[fTransparent], kGeomChars[fForceGeometric]);
46cb93a386Sopenharmony_ci    }
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci    void genRRects() {
49cb93a386Sopenharmony_ci        int i = 0;
50cb93a386Sopenharmony_ci        for (int x = kRRSpace; x < kWidth - kRRStep; x += kRRStep) {
51cb93a386Sopenharmony_ci            for (int y = kRRSpace; y < kHeight - kRRStep; y += kRRStep) {
52cb93a386Sopenharmony_ci                SkRect rect = SkRect::MakeXYWH(x, y, kRRSize, kRRSize);
53cb93a386Sopenharmony_ci                fRRects[i].addRRect(SkRRect::MakeRectXY(rect, kRRRadius, kRRRadius));
54cb93a386Sopenharmony_ci                ++i;
55cb93a386Sopenharmony_ci            }
56cb93a386Sopenharmony_ci        }
57cb93a386Sopenharmony_ci        SkASSERT(i == kNumRRects);
58cb93a386Sopenharmony_ci    }
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    const char* onGetName() override { return fBaseName.c_str(); }
61cb93a386Sopenharmony_ci
62cb93a386Sopenharmony_ci    void onDelayedSetup() override {
63cb93a386Sopenharmony_ci        fRec.fZPlaneParams = SkPoint3::Make(0, 0, kElevation);
64cb93a386Sopenharmony_ci        fRec.fLightPos = SkPoint3::Make(270, 0, 600);
65cb93a386Sopenharmony_ci        fRec.fLightRadius = 800;
66cb93a386Sopenharmony_ci        fRec.fAmbientColor = 0x19000000;
67cb93a386Sopenharmony_ci        fRec.fSpotColor = 0x40000000;
68cb93a386Sopenharmony_ci        fRec.fFlags = 0;
69cb93a386Sopenharmony_ci        if (fTransparent) {
70cb93a386Sopenharmony_ci            fRec.fFlags |= SkShadowFlags::kTransparentOccluder_ShadowFlag;
71cb93a386Sopenharmony_ci        }
72cb93a386Sopenharmony_ci        if (fForceGeometric) {
73cb93a386Sopenharmony_ci            fRec.fFlags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
74cb93a386Sopenharmony_ci        }
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci        this->genRRects();
77cb93a386Sopenharmony_ci    }
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
80cb93a386Sopenharmony_ci        SkPaint paint;
81cb93a386Sopenharmony_ci        paint.setColor(SK_ColorWHITE);
82cb93a386Sopenharmony_ci        this->setupPaint(&paint);
83cb93a386Sopenharmony_ci
84cb93a386Sopenharmony_ci        for (int i = 0; i < loops; ++i) {
85cb93a386Sopenharmony_ci            // use the private canvas call so we don't include the time to stuff data in the Rec
86cb93a386Sopenharmony_ci            canvas->private_draw_shadow_rec(fRRects[i % kNumRRects], fRec);
87cb93a386Sopenharmony_ci        }
88cb93a386Sopenharmony_ci    }
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ciprivate:
91cb93a386Sopenharmony_ci    SkString fBaseName;
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    SkPath  fRRects[kNumRRects];
94cb93a386Sopenharmony_ci    SkDrawShadowRec fRec;
95cb93a386Sopenharmony_ci    int    fTransparent;
96cb93a386Sopenharmony_ci    int    fForceGeometric;
97cb93a386Sopenharmony_ci
98cb93a386Sopenharmony_ci    using INHERITED = Benchmark;
99cb93a386Sopenharmony_ci};
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ciDEF_BENCH(return new ShadowBench(false, false);)
102cb93a386Sopenharmony_ciDEF_BENCH(return new ShadowBench(false, true);)
103cb93a386Sopenharmony_ciDEF_BENCH(return new ShadowBench(true, false);)
104cb93a386Sopenharmony_ciDEF_BENCH(return new ShadowBench(true, true);)
105cb93a386Sopenharmony_ci
106