1 /*
2 * Copyright 2011 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
8 #include "bench/Benchmark.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkPaint.h"
11 #include "include/core/SkShader.h"
12 #include "include/core/SkString.h"
13 #include "include/core/SkVertices.h"
14 #include "include/utils/SkRandom.h"
15 #include "tools/Resources.h"
16
17 // Just want to trigger perspective handling, not dramatically change size
tiny_persp_effect(SkCanvas * canvas)18 static void tiny_persp_effect(SkCanvas* canvas) {
19 SkMatrix m;
20 m.reset();
21 m[7] = 0.000001f;
22 canvas->concat(m);
23 }
24
25 enum VertFlags {
26 kColors_VertFlag = 1 << 0,
27 kTexture_VertFlag = 1 << 1,
28 kPersp_VertFlag = 1 << 2,
29 };
30
31 class VertBench : public Benchmark {
32 SkString fName;
33 enum {
34 W = 64*2,
35 H = 48*2,
36 ROW = 20,
37 COL = 20,
38 PTS = (ROW + 1) * (COL + 1),
39 IDX = ROW * COL * 6,
40 };
41
42 sk_sp<SkShader> fShader;
43 SkPoint fPts[PTS];
44 SkColor fColors[PTS];
45 uint16_t fIdx[IDX];
46 unsigned fFlags;
47
load_2_tris(uint16_t idx[],int x,int y,int rb)48 static void load_2_tris(uint16_t idx[], int x, int y, int rb) {
49 int n = y * rb + x;
50 idx[0] = n; idx[1] = n + 1; idx[2] = rb + n + 1;
51 idx[3] = n; idx[4] = rb + n + 1; idx[5] = n + rb;
52 }
53
onDelayedSetup()54 void onDelayedSetup() override {
55 auto img = GetResourceAsImage("images/mandrill_256.png");
56 if (img) {
57 fShader = img->makeShader();
58 }
59 }
60
61 public:
VertBench(unsigned flags)62 VertBench(unsigned flags) : fFlags(flags) {
63 const SkScalar dx = SkIntToScalar(W) / COL;
64 const SkScalar dy = SkIntToScalar(H) / COL;
65
66 SkPoint* pts = fPts;
67 uint16_t* idx = fIdx;
68
69 SkScalar yy = 0;
70 for (int y = 0; y <= ROW; y++) {
71 SkScalar xx = 0;
72 for (int x = 0; x <= COL; ++x) {
73 pts->set(xx, yy);
74 pts += 1;
75 xx += dx;
76
77 if (x < COL && y < ROW) {
78 load_2_tris(idx, x, y, COL + 1);
79 for (int i = 0; i < 6; i++) {
80 SkASSERT(idx[i] < PTS);
81 }
82 idx += 6;
83 }
84 }
85 yy += dy;
86 }
87 SkASSERT(PTS == pts - fPts);
88 SkASSERT(IDX == idx - fIdx);
89
90 SkRandom rand;
91 for (int i = 0; i < PTS; ++i) {
92 fColors[i] = rand.nextU() | (0xFF << 24);
93 }
94
95 fName.set("verts");
96 if (fFlags & kTexture_VertFlag) {
97 fName.append("_textures");
98 }
99 if (fFlags & kColors_VertFlag) {
100 fName.append("_colors");
101 }
102 if (fFlags & kPersp_VertFlag) {
103 fName.append("_persp");
104 }
105 }
106
107 protected:
onGetName()108 const char* onGetName() override { return fName.c_str(); }
onDraw(int loops,SkCanvas * canvas)109 void onDraw(int loops, SkCanvas* canvas) override {
110 SkPaint paint;
111 this->setupPaint(&paint);
112 paint.setShader(fShader);
113
114 if (fFlags & kPersp_VertFlag) {
115 tiny_persp_effect(canvas);
116 }
117
118 const SkPoint* texs = (fFlags & kTexture_VertFlag) ? fPts : nullptr;
119 const SkColor* cols = (fFlags & kColors_VertFlag) ? fColors : nullptr;
120 auto verts = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, PTS,
121 fPts, texs, cols, IDX, fIdx);
122 for (int i = 0; i < loops; i++) {
123 canvas->drawVertices(verts, SkBlendMode::kModulate, paint);
124 }
125 }
126 private:
127 typedef Benchmark INHERITED;
128 };
129 DEF_BENCH(return new VertBench(kTexture_VertFlag | kPersp_VertFlag);)
130 DEF_BENCH(return new VertBench(kColors_VertFlag | kPersp_VertFlag);)
131 DEF_BENCH(return new VertBench(kTexture_VertFlag);)
132 DEF_BENCH(return new VertBench(kColors_VertFlag);)
133 DEF_BENCH(return new VertBench(kColors_VertFlag | kTexture_VertFlag);)
134
135 /////////////////////////////////////////////////////////////////////////////////////////////////
136
137 #include "include/core/SkRSXform.h"
138 #include "include/utils/SkRandom.h"
139 #include "tools/Resources.h"
140
141 enum AtlasFlags {
142 kColors_Flag = 1 << 0,
143 kRotate_Flag = 1 << 1,
144 kPersp_Flag = 1 << 2,
145 };
146
147 class AtlasBench : public Benchmark {
148 unsigned fFlags;
149 SkString fName;
150 enum {
151 W = 640,
152 H = 480,
153 N = 10*1000,
154 };
155
156 sk_sp<SkImage> fAtlas;
157 SkRSXform fXforms[N];
158 SkRect fRects[N];
159 SkColor fColors[N];
160
161 public:
AtlasBench(unsigned flags)162 AtlasBench(unsigned flags) : fFlags(flags) {
163 fName.printf("drawAtlas");
164 if (flags & kColors_Flag) {
165 fName.append("_colors");
166 }
167 if (flags & kRotate_Flag) {
168 fName.append("_rotated");
169 }
170 if (flags & kPersp_Flag) {
171 fName.append("_persp");
172 }
173 }
~AtlasBench()174 ~AtlasBench() override {}
175
176 protected:
onGetName()177 const char* onGetName() override { return fName.c_str(); }
onDelayedSetup()178 void onDelayedSetup() override {
179 fAtlas = GetResourceAsImage("images/mandrill_256.png");
180 if (fAtlas) {
181 fAtlas = fAtlas->makeRasterImage();
182 }
183
184 const SkScalar imageW = fAtlas->width();
185 const SkScalar imageH = fAtlas->height();
186 SkScalar scos = 1;
187 SkScalar ssin = 0;
188 if (fFlags & kRotate_Flag) {
189 scos = 0.866025403784439f; // sqrt(3)/2
190 ssin = 0.5f;
191 }
192
193 SkRandom rand;
194 for (int i = 0; i < N; ++i) {
195 fRects[i] = SkRect::MakeXYWH(rand.nextF() * (imageW - 8),
196 rand.nextF() * (imageH - 8), 8, 8);
197 fColors[i] = rand.nextU() | 0xFF000000;
198 fXforms[i] = SkRSXform::Make(scos, ssin, rand.nextF() * W, rand.nextF() * H);
199 }
200 }
onDraw(int loops,SkCanvas * canvas)201 void onDraw(int loops, SkCanvas* canvas) override {
202 const SkRect* cullRect = nullptr;
203 const SkPaint* paintPtr = nullptr;
204 const SkColor* colors = nullptr;
205 if (fFlags & kColors_Flag) {
206 colors = fColors;
207 }
208 if (fFlags & kPersp_Flag) {
209 tiny_persp_effect(canvas);
210 }
211 for (int i = 0; i < loops; i++) {
212 canvas->drawAtlas(fAtlas, fXforms, fRects, colors, N, SkBlendMode::kModulate,
213 cullRect, paintPtr);
214 }
215 }
216 private:
217 typedef Benchmark INHERITED;
218 };
219 //DEF_BENCH(return new AtlasBench(0);)
220 //DEF_BENCH(return new AtlasBench(kColors_Flag);)
221 DEF_BENCH(return new AtlasBench(0);)
222 DEF_BENCH(return new AtlasBench(kRotate_Flag);)
223 DEF_BENCH(return new AtlasBench(kPersp_Flag);)
224 DEF_BENCH(return new AtlasBench(kColors_Flag);)
225 DEF_BENCH(return new AtlasBench(kColors_Flag | kRotate_Flag);)
226
227