1/*
2 * Copyright 2013 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#include "Benchmark.h"
8#include "SkBitmapSource.h"
9#include "SkCanvas.h"
10#include "SkDevice.h"
11#include "SkLightingImageFilter.h"
12
13#define FILTER_WIDTH_SMALL  SkIntToScalar(32)
14#define FILTER_HEIGHT_SMALL SkIntToScalar(32)
15#define FILTER_WIDTH_LARGE  SkIntToScalar(256)
16#define FILTER_HEIGHT_LARGE SkIntToScalar(256)
17
18class LightingBaseBench : public Benchmark {
19public:
20    LightingBaseBench(bool small) : fIsSmall(small) { }
21
22protected:
23    void draw(const int loops, SkCanvas* canvas, SkImageFilter* imageFilter) const {
24        SkRect r = fIsSmall ? SkRect::MakeWH(FILTER_WIDTH_SMALL, FILTER_HEIGHT_SMALL) :
25                              SkRect::MakeWH(FILTER_WIDTH_LARGE, FILTER_HEIGHT_LARGE);
26        SkPaint paint;
27        paint.setImageFilter(imageFilter)->unref();
28        for (int i = 0; i < loops; i++) {
29            canvas->drawRect(r, paint);
30        }
31    }
32
33    static SkPoint3 getPointLocation() {
34        static SkPoint3 pointLocation(0, 0, SkIntToScalar(10));
35        return pointLocation;
36    }
37
38    static SkPoint3 getDistantDirection() {
39        static SkScalar azimuthRad = SkDegreesToRadians(SkIntToScalar(225));
40        static SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5));
41        static SkPoint3 distantDirection(SkScalarMul(SkScalarCos(azimuthRad),
42                                                     SkScalarCos(elevationRad)),
43                                         SkScalarMul(SkScalarSin(azimuthRad),
44                                                     SkScalarCos(elevationRad)),
45                                         SkScalarSin(elevationRad));
46        return distantDirection;
47    }
48
49    static SkPoint3 getSpotLocation() {
50        static SkPoint3 spotLocation(SkIntToScalar(-10), SkIntToScalar(-10), SkIntToScalar(20));
51        return spotLocation;
52    }
53
54    static SkPoint3 getSpotTarget() {
55        static SkPoint3 spotTarget(SkIntToScalar(40), SkIntToScalar(40), 0);
56        return spotTarget;
57    }
58
59    static SkScalar getSpotExponent() {
60        static SkScalar spotExponent = SK_Scalar1;
61        return spotExponent;
62    }
63
64    static SkScalar getCutoffAngle() {
65        static SkScalar cutoffAngle = SkIntToScalar(15);
66        return cutoffAngle;
67    }
68
69    static SkScalar getKd() {
70        static SkScalar kd = SkIntToScalar(2);
71        return kd;
72    }
73
74    static SkScalar getKs() {
75        static SkScalar ks = SkIntToScalar(1);
76        return ks;
77    }
78
79    static SkScalar getShininess() {
80        static SkScalar shininess = SkIntToScalar(8);
81        return shininess;
82    }
83
84    static SkScalar getSurfaceScale() {
85        static SkScalar surfaceScale = SkIntToScalar(1);
86        return surfaceScale;
87    }
88
89    static SkColor getWhite() {
90        static SkColor white(0xFFFFFFFF);
91        return white;
92    }
93
94    bool fIsSmall;
95    typedef Benchmark INHERITED;
96};
97
98class LightingPointLitDiffuseBench : public LightingBaseBench {
99public:
100    LightingPointLitDiffuseBench(bool small) : INHERITED(small) {
101    }
102
103protected:
104    virtual const char* onGetName() SK_OVERRIDE {
105        return fIsSmall ? "lightingpointlitdiffuse_small" : "lightingpointlitdiffuse_large";
106    }
107
108    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
109        draw(loops, canvas, SkLightingImageFilter::CreatePointLitDiffuse(getPointLocation(),
110                                                                         getWhite(),
111                                                                         getSurfaceScale(),
112                                                                         getKd()));
113    }
114
115private:
116    typedef LightingBaseBench INHERITED;
117};
118
119class LightingDistantLitDiffuseBench : public LightingBaseBench {
120public:
121    LightingDistantLitDiffuseBench(bool small) : INHERITED(small) {
122    }
123
124protected:
125    virtual const char* onGetName() SK_OVERRIDE {
126        return fIsSmall ? "lightingdistantlitdiffuse_small" : "lightingdistantlitdiffuse_large";
127    }
128
129    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
130        draw(loops, canvas, SkLightingImageFilter::CreateDistantLitDiffuse(getDistantDirection(),
131                                                                           getWhite(),
132                                                                           getSurfaceScale(),
133                                                                           getKd()));
134    }
135
136private:
137    typedef LightingBaseBench INHERITED;
138};
139
140class LightingSpotLitDiffuseBench : public LightingBaseBench {
141public:
142    LightingSpotLitDiffuseBench(bool small) : INHERITED(small) {
143    }
144
145protected:
146    virtual const char* onGetName() SK_OVERRIDE {
147        return fIsSmall ? "lightingspotlitdiffuse_small" : "lightingspotlitdiffuse_large";
148    }
149
150    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
151        draw(loops, canvas, SkLightingImageFilter::CreateSpotLitDiffuse(getSpotLocation(),
152                                                                        getSpotTarget(),
153                                                                        getSpotExponent(),
154                                                                        getCutoffAngle(),
155                                                                        getWhite(),
156                                                                        getSurfaceScale(),
157                                                                        getKd()));
158    }
159
160private:
161    typedef LightingBaseBench INHERITED;
162};
163
164class LightingPointLitSpecularBench : public LightingBaseBench {
165public:
166    LightingPointLitSpecularBench(bool small) : INHERITED(small) {
167    }
168
169protected:
170    virtual const char* onGetName() SK_OVERRIDE {
171        return fIsSmall ? "lightingpointlitspecular_small" : "lightingpointlitspecular_large";
172    }
173
174    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
175        draw(loops, canvas, SkLightingImageFilter::CreatePointLitSpecular(getPointLocation(),
176                                                                          getWhite(),
177                                                                          getSurfaceScale(),
178                                                                          getKs(),
179                                                                          getShininess()));
180    }
181
182private:
183    typedef LightingBaseBench INHERITED;
184};
185
186class LightingDistantLitSpecularBench : public LightingBaseBench {
187public:
188    LightingDistantLitSpecularBench(bool small) : INHERITED(small) {
189    }
190
191protected:
192    virtual const char* onGetName() SK_OVERRIDE {
193        return fIsSmall ? "lightingdistantlitspecular_small" : "lightingdistantlitspecular_large";
194    }
195
196    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
197        draw(loops, canvas, SkLightingImageFilter::CreateDistantLitSpecular(getDistantDirection(),
198                                                                            getWhite(),
199                                                                            getSurfaceScale(),
200                                                                            getKs(),
201                                                                            getShininess()));
202    }
203
204private:
205    typedef LightingBaseBench INHERITED;
206};
207
208class LightingSpotLitSpecularBench : public LightingBaseBench {
209public:
210    LightingSpotLitSpecularBench(bool small) : INHERITED(small) {
211    }
212
213protected:
214    virtual const char* onGetName() SK_OVERRIDE {
215        return fIsSmall ? "lightingspotlitspecular_small" : "lightingspotlitspecular_large";
216    }
217
218    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
219        draw(loops, canvas, SkLightingImageFilter::CreateSpotLitSpecular(getSpotLocation(),
220                                                                         getSpotTarget(),
221                                                                         getSpotExponent(),
222                                                                         getCutoffAngle(),
223                                                                         getWhite(),
224                                                                         getSurfaceScale(),
225                                                                         getKs(),
226                                                                         getShininess()));
227    }
228
229private:
230    typedef LightingBaseBench INHERITED;
231};
232
233///////////////////////////////////////////////////////////////////////////////
234
235DEF_BENCH( return new LightingPointLitDiffuseBench(true); )
236DEF_BENCH( return new LightingPointLitDiffuseBench(false); )
237DEF_BENCH( return new LightingDistantLitDiffuseBench(true); )
238DEF_BENCH( return new LightingDistantLitDiffuseBench(false); )
239DEF_BENCH( return new LightingSpotLitDiffuseBench(true); )
240DEF_BENCH( return new LightingSpotLitDiffuseBench(false); )
241DEF_BENCH( return new LightingPointLitSpecularBench(true); )
242DEF_BENCH( return new LightingPointLitSpecularBench(false); )
243DEF_BENCH( return new LightingDistantLitSpecularBench(true); )
244DEF_BENCH( return new LightingDistantLitSpecularBench(false); )
245DEF_BENCH( return new LightingSpotLitSpecularBench(true); )
246DEF_BENCH( return new LightingSpotLitSpecularBench(false); )
247