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 #include "gm.h"
8 #include "sk_tool_utils.h"
9 #include "SkColorFilter.h"
10 #include "SkMaskFilter.h"
11 #include "SkPath.h"
12 #include "SkRegion.h"
13 #include "SkShader.h"
14 #include "SkUtils.h"
15
16 // effects
17 #include "SkGradientShader.h"
18 #include "SkBlurDrawLooper.h"
19
makebm(SkBitmap * bm,SkColorType ct,int w,int h)20 static void makebm(SkBitmap* bm, SkColorType ct, int w, int h) {
21 bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType));
22 bm->eraseColor(SK_ColorTRANSPARENT);
23
24 SkCanvas canvas(*bm);
25 SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h)} };
26 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
27 SkScalar pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
28 SkPaint paint;
29
30 paint.setDither(true);
31 paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos,
32 SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
33 canvas.drawPaint(paint);
34 }
35
setup(SkPaint * paint,const SkBitmap & bm,SkFilterQuality filter_level,SkShader::TileMode tmx,SkShader::TileMode tmy)36 static void setup(SkPaint* paint, const SkBitmap& bm, SkFilterQuality filter_level,
37 SkShader::TileMode tmx, SkShader::TileMode tmy) {
38 paint->setShader(SkShader::MakeBitmapShader(bm, tmx, tmy));
39 paint->setFilterQuality(filter_level);
40 }
41
42 constexpr SkColorType gColorTypes[] = {
43 kN32_SkColorType,
44 kRGB_565_SkColorType,
45 };
46
47 class ScaledTilingGM : public skiagm::GM {
48 public:
ScaledTilingGM(bool powerOfTwoSize)49 ScaledTilingGM(bool powerOfTwoSize)
50 : fPowerOfTwoSize(powerOfTwoSize) {
51 }
52
53 SkBitmap fTexture[SK_ARRAY_COUNT(gColorTypes)];
54
55 protected:
56 enum {
57 kPOTSize = 4,
58 kNPOTSize = 3,
59 };
60
onShortName()61 SkString onShortName() override {
62 SkString name("scaled_tilemodes");
63 if (!fPowerOfTwoSize) {
64 name.append("_npot");
65 }
66 return name;
67 }
68
onISize()69 SkISize onISize() override { return SkISize::Make(880, 760); }
70
onOnceBeforeDraw()71 void onOnceBeforeDraw() override {
72 int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
73 for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
74 makebm(&fTexture[i], gColorTypes[i], size, size);
75 }
76 }
77
onDraw(SkCanvas * canvas)78 void onDraw(SkCanvas* canvas) override {
79 float scale = 32.f/kPOTSize;
80
81 int size = fPowerOfTwoSize ? kPOTSize : kNPOTSize;
82
83 SkRect r = { 0, 0, SkIntToScalar(size*2), SkIntToScalar(size*2) };
84
85 const char* gColorTypeNames[] = { "8888" , "565", "4444" };
86
87 constexpr SkFilterQuality gFilterQualitys[] =
88 { kNone_SkFilterQuality,
89 kLow_SkFilterQuality,
90 kMedium_SkFilterQuality,
91 kHigh_SkFilterQuality };
92 const char* gFilterNames[] = { "None", "Low", "Medium", "High" };
93
94 constexpr SkShader::TileMode gModes[] = {
95 SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode };
96 const char* gModeNames[] = { "C", "R", "M" };
97
98 SkScalar y = SkIntToScalar(24);
99 SkScalar x = SkIntToScalar(10)/scale;
100
101 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
102 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
103 SkPaint p;
104 SkString str;
105 p.setAntiAlias(true);
106 sk_tool_utils::set_portable_typeface(&p);
107 str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);
108
109 p.setTextAlign(SkPaint::kCenter_Align);
110 canvas->drawString(str, scale*(x + r.width()/2), y, p);
111
112 x += r.width() * 4 / 3;
113 }
114 }
115
116 y = SkIntToScalar(40) / scale;
117
118 for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
119 for (size_t j = 0; j < SK_ARRAY_COUNT(gFilterQualitys); j++) {
120 x = SkIntToScalar(10)/scale;
121 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
122 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
123 SkPaint paint;
124 #if 1 // Temporary change to regen bitmap before each draw. This may help tracking down an issue
125 // on SGX where resizing NPOT textures to POT textures exhibits a driver bug.
126 if (!fPowerOfTwoSize) {
127 makebm(&fTexture[i], gColorTypes[i], size, size);
128 }
129 #endif
130 setup(&paint, fTexture[i], gFilterQualitys[j], gModes[kx], gModes[ky]);
131 paint.setDither(true);
132
133 canvas->save();
134 canvas->scale(scale,scale);
135 canvas->translate(x, y);
136 canvas->drawRect(r, paint);
137 canvas->restore();
138
139 x += r.width() * 4 / 3;
140 }
141 }
142 {
143 SkPaint p;
144 SkString str;
145 p.setAntiAlias(true);
146 sk_tool_utils::set_portable_typeface(&p);
147 str.printf("%s, %s", gColorTypeNames[i], gFilterNames[j]);
148 canvas->drawString(str, scale*x, scale*(y + r.height() * 2 / 3), p);
149 }
150
151 y += r.height() * 4 / 3;
152 }
153 }
154 }
155
156 private:
157 bool fPowerOfTwoSize;
158 typedef skiagm::GM INHERITED;
159 };
160
161 constexpr int gWidth = 32;
162 constexpr int gHeight = 32;
163
make_bm(SkShader::TileMode tx,SkShader::TileMode ty)164 static sk_sp<SkShader> make_bm(SkShader::TileMode tx, SkShader::TileMode ty) {
165 SkBitmap bm;
166 makebm(&bm, kN32_SkColorType, gWidth, gHeight);
167 return SkShader::MakeBitmapShader(bm, tx, ty);
168 }
169
make_grad(SkShader::TileMode tx,SkShader::TileMode ty)170 static sk_sp<SkShader> make_grad(SkShader::TileMode tx, SkShader::TileMode ty) {
171 SkPoint pts[] = { { 0, 0 }, { SkIntToScalar(gWidth), SkIntToScalar(gHeight)} };
172 SkPoint center = { SkIntToScalar(gWidth)/2, SkIntToScalar(gHeight)/2 };
173 SkScalar rad = SkIntToScalar(gWidth)/2;
174 SkColor colors[] = { 0xFFFF0000, sk_tool_utils::color_to_565(0xFF0044FF) };
175
176 int index = (int)ty;
177 switch (index % 3) {
178 case 0:
179 return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors), tx);
180 case 1:
181 return SkGradientShader::MakeRadial(center, rad, colors, nullptr, SK_ARRAY_COUNT(colors), tx);
182 case 2:
183 return SkGradientShader::MakeSweep(center.fX, center.fY, colors, nullptr, SK_ARRAY_COUNT(colors));
184 }
185
186 return nullptr;
187 }
188
189 typedef sk_sp<SkShader> (*ShaderProc)(SkShader::TileMode, SkShader::TileMode);
190
191 class ScaledTiling2GM : public skiagm::GM {
192 ShaderProc fProc;
193 SkString fName;
194 public:
ScaledTiling2GM(ShaderProc proc,const char name[])195 ScaledTiling2GM(ShaderProc proc, const char name[]) : fProc(proc) {
196 fName.printf("scaled_tilemode_%s", name);
197 }
198
199 protected:
200
onShortName()201 SkString onShortName() override {
202 return fName;
203 }
204
onISize()205 SkISize onISize() override { return SkISize::Make(650, 610); }
206
onDraw(SkCanvas * canvas)207 void onDraw(SkCanvas* canvas) override {
208 canvas->scale(SkIntToScalar(3)/2, SkIntToScalar(3)/2);
209
210 const SkScalar w = SkIntToScalar(gWidth);
211 const SkScalar h = SkIntToScalar(gHeight);
212 SkRect r = { -w, -h, w*2, h*2 };
213
214 constexpr SkShader::TileMode gModes[] = {
215 SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode
216 };
217 const char* gModeNames[] = {
218 "Clamp", "Repeat", "Mirror"
219 };
220
221 SkScalar y = SkIntToScalar(24);
222 SkScalar x = SkIntToScalar(66);
223
224 SkPaint p;
225 p.setAntiAlias(true);
226 sk_tool_utils::set_portable_typeface(&p);
227 p.setTextAlign(SkPaint::kCenter_Align);
228
229 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
230 SkString str(gModeNames[kx]);
231 canvas->drawString(str, x + r.width()/2, y, p);
232 x += r.width() * 4 / 3;
233 }
234
235 y += SkIntToScalar(16) + h;
236 p.setTextAlign(SkPaint::kRight_Align);
237
238 for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
239 x = SkIntToScalar(16) + w;
240
241 SkString str(gModeNames[ky]);
242 canvas->drawString(str, x, y + h/2, p);
243
244 x += SkIntToScalar(50);
245 for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
246 SkPaint paint;
247 paint.setShader(fProc(gModes[kx], gModes[ky]));
248
249 canvas->save();
250 canvas->translate(x, y);
251 canvas->drawRect(r, paint);
252 canvas->restore();
253
254 x += r.width() * 4 / 3;
255 }
256 y += r.height() * 4 / 3;
257 }
258 }
259
260 private:
261 typedef skiagm::GM INHERITED;
262 };
263
264 //////////////////////////////////////////////////////////////////////////////
265
266 DEF_GM( return new ScaledTilingGM(true); )
267 DEF_GM( return new ScaledTilingGM(false); )
268 DEF_GM( return new ScaledTiling2GM(make_bm, "bitmap"); )
269 DEF_GM( return new ScaledTiling2GM(make_grad, "gradient"); )
270