Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
pictureshader.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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 "gm/gm.h"
17#include "include/core/SkRect.h"
21#include "include/core/SkSize.h"
26#include "tools/ToolUtils.h"
28
29static struct {
32} kTileConfigs[] = {
36};
37
39public:
40 PictureShaderGM(SkScalar tileSize, SkScalar sceneSize, bool useLocalMatrixWrapper = false,
41 float alpha = 1)
42 : fTileSize(tileSize)
43 , fSceneSize(sceneSize)
44 , fAlpha(alpha)
45 , fUseLocalMatrixWrapper(useLocalMatrixWrapper)
46 {}
47
48 protected:
49 void onOnceBeforeDraw() override {
50 // Build the picture.
51 SkPictureRecorder recorder;
52 SkCanvas* pictureCanvas = recorder.beginRecording(fTileSize, fTileSize);
53 this->drawTile(pictureCanvas);
54 fPicture = recorder.finishRecordingAsPicture();
55
56 // Build a reference bitmap.
57 fBitmap.allocN32Pixels(SkScalarCeilToInt(fTileSize), SkScalarCeilToInt(fTileSize));
59 SkCanvas bitmapCanvas(fBitmap);
60 this->drawTile(&bitmapCanvas);
61 }
62
63 SkString getName() const override {
64 return SkStringPrintf("pictureshader%s%s",
65 fUseLocalMatrixWrapper ? "_localwrapper" : "",
66 fAlpha < 1 ? "_alpha" : "");
67 }
68
69 SkISize getISize() override { return SkISize::Make(1400, 1450); }
70
71 void onDraw(SkCanvas* canvas) override {
72 this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0);
73 this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0);
74 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1);
75 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2);
76 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0);
77 this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0);
78
79 // One last custom row to exercise negative scaling
80 SkMatrix ctm, localMatrix;
81 ctm.setTranslate(fSceneSize * 2.1f, fSceneSize * 13.8f);
82 ctm.preScale(-1, -1);
83 localMatrix.setScale(2, 2);
84 this->drawScene(canvas, ctm, localMatrix, 0);
85
86 ctm.setTranslate(fSceneSize * 2.4f, fSceneSize * 12.8f);
87 localMatrix.setScale(-1, -1);
88 this->drawScene(canvas, ctm, localMatrix, 0);
89
90 ctm.setTranslate(fSceneSize * 4.8f, fSceneSize * 12.3f);
91 ctm.preScale(2, 2);
92 this->drawScene(canvas, ctm, localMatrix, 0);
93
94 ctm.setTranslate(fSceneSize * 13.8f, fSceneSize * 14.3f);
95 ctm.preScale(-2, -2);
96 localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
97 localMatrix.preRotate(45);
98 localMatrix.preScale(-2, -2);
99 this->drawScene(canvas, ctm, localMatrix, 0);
100 }
101
102private:
103 void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
104 unsigned tileMode) {
105 SkMatrix ctm, localMatrix;
106
107 ctm.setTranslate(pos.x(), pos.y());
108 ctm.preScale(scale, scale);
109 localMatrix.setScale(localScale, localScale);
110 this->drawScene(canvas, ctm, localMatrix, tileMode);
111
112 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
113 ctm.preScale(scale, scale);
114 localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
115 localMatrix.preScale(localScale, localScale);
116 this->drawScene(canvas, ctm, localMatrix, tileMode);
117
118 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
119 ctm.preScale(scale, scale);
120 localMatrix.setRotate(45);
121 localMatrix.preScale(localScale, localScale);
122 this->drawScene(canvas, ctm, localMatrix, tileMode);
123
124 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
125 ctm.preScale(scale, scale);
126 localMatrix.setSkew(1, 0);
127 localMatrix.preScale(localScale, localScale);
128 this->drawScene(canvas, ctm, localMatrix, tileMode);
129
130 ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
131 ctm.preScale(scale, scale);
132 localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
133 localMatrix.preRotate(45);
134 localMatrix.preScale(localScale, localScale);
135 this->drawScene(canvas, ctm, localMatrix, tileMode);
136 }
137
138 void drawTile(SkCanvas* canvas) {
140 paint.setColor(SK_ColorGREEN);
141 paint.setStyle(SkPaint::kFill_Style);
142 paint.setAntiAlias(true);
143
144 canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
145 canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
146 fTileSize / 2, fTileSize / 2), paint);
147
148 paint.setColor(SK_ColorRED);
149 canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
150 fTileSize / 2, fTileSize * 2 / 3, paint);
151 canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
152 fTileSize * 2 / 3, fTileSize / 2, paint);
153 }
154
155 void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix,
156 unsigned tileMode) {
157 SkASSERT(tileMode < std::size(kTileConfigs));
158
160 paint.setStyle(SkPaint::kFill_Style);
161 paint.setColor(SK_ColorLTGRAY);
162
163 canvas->save();
164 canvas->concat(matrix);
165 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
166 canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint);
167
168 paint.setAlphaf(fAlpha);
169
170 auto pictureShader = fPicture->makeShader(kTileConfigs[tileMode].tmx,
171 kTileConfigs[tileMode].tmy,
173 fUseLocalMatrixWrapper ? nullptr : &localMatrix,
174 nullptr);
175 paint.setShader(fUseLocalMatrixWrapper
176 ? pictureShader->makeWithLocalMatrix(localMatrix)
177 : pictureShader);
178 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
179
180 canvas->translate(fSceneSize * 1.1f, 0);
181
182 auto bitmapShader = fBitmap.makeShader(kTileConfigs[tileMode].tmx,
183 kTileConfigs[tileMode].tmy,
185 fUseLocalMatrixWrapper ? nullptr : &localMatrix);
186 paint.setShader(fUseLocalMatrixWrapper
187 ? bitmapShader->makeWithLocalMatrix(localMatrix)
188 : bitmapShader);
189 canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
190
191 canvas->restore();
192 }
193
194 const SkScalar fTileSize;
195 const SkScalar fSceneSize;
196 const float fAlpha;
197 const bool fUseLocalMatrixWrapper;
198
199 sk_sp<SkPicture> fPicture;
200 SkBitmap fBitmap;
201
202 using INHERITED = GM;
203};
204
205DEF_GM(return new PictureShaderGM(50, 100);)
206DEF_GM(return new PictureShaderGM(50, 100, true);)
207DEF_GM(return new PictureShaderGM(50, 100, false, 0.25f);)
208
209DEF_SIMPLE_GM(tiled_picture_shader, canvas, 400, 400) {
210 // https://code.google.com/p/skia/issues/detail?id=3398
211 SkRect tile = SkRect::MakeWH(100, 100);
212
213 SkPictureRecorder recorder;
214 SkCanvas* c = recorder.beginRecording(tile);
215
216 SkRect r = tile;
217 r.inset(4, 4);
218 SkPaint p;
219 p.setColor(ToolUtils::color_to_565(0xFF303F9F)); // dark blue
220 c->drawRect(r, p);
221 p.setColor(ToolUtils::color_to_565(0xFFC5CAE9)); // light blue
222 p.setStrokeWidth(10);
223 c->drawLine(20, 20, 80, 80, p);
224
225 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
226
227 p.setColor(ToolUtils::color_to_565(0xFF8BC34A)); // green
228 canvas->drawPaint(p);
229
230 canvas->clipRect(SkRect::MakeXYWH(0, 0, 400, 350));
231 p.setColor(0xFFB6B6B6); // gray
232 canvas->drawPaint(p);
233
236 canvas->drawPaint(p);
237}
238
239DEF_SIMPLE_GM(pictureshader_persp, canvas, 215, 110) {
240 enum class DrawStrategy {
241 kDirect,
242 kPictureShader,
243 };
244
245 auto drawPicture = [](SkCanvas* canvas, sk_sp<SkPicture> picture, DrawStrategy strategy) {
246 // Only want local upper 50x50 of 'picture' before we apply decal (or clip)
247 SkRect bounds = {0.f, 0.f, 50.f, 50.f};
248 switch(strategy) {
249 case DrawStrategy::kDirect: {
250 canvas->clipRect(bounds, true);
251 canvas->drawPicture(picture);
252 break; }
253 case DrawStrategy::kPictureShader: {
256 SkFilterMode::kLinear, nullptr, &bounds));
257 canvas->drawRect({0.f, 0.f, 50.f, 50.f}, paint);
258 break; }
259 }
260 };
261
262 auto picture = []() {
264 SkASSERT(typeface);
265 SkFont font;
266 font.setTypeface(typeface);
267 font.setHinting(SkFontHinting::kNormal);
268 font.setSize(8.f);
269
271 paint.setColor(SK_ColorGREEN);
272 SkPictureRecorder recorder;
273 SkCanvas* record_canvas = recorder.beginRecording({0, 0, 100, 100});
274 record_canvas->drawTextBlob(SkTextBlob::MakeFromString("Hamburgefons", font),
275 0, 16.f, paint);
276 return recorder.finishRecordingAsPicture();
277 }();
278
279 SkM44 m;
280 m.preScale(2.f, 2.f);
281 SkM44 persp = SkM44::Perspective(0.01f, 10.f, SK_ScalarPI / 3.f);
282 persp.preTranslate(0.f, 5.f, -0.1f);
283 persp.preConcat(SkM44::Rotate({0.f, 1.f, 0.f}, 0.008f));
284 m.postConcat(persp);
285
286 canvas->clear(SK_ColorBLACK);
287 canvas->translate(5.f, 5.f);
288 for (auto strategy : { DrawStrategy::kDirect,
289 DrawStrategy::kPictureShader }) {
290 canvas->save();
291
292 SkPaint outline;
293 outline.setColor(SK_ColorWHITE);
295 outline.setStrokeWidth(1.f);
296 canvas->drawRect({-1, -1, 101, 101}, outline);
297
298 canvas->clipRect({0, 0, 100, 100});
299 canvas->concat(m);
300
301 drawPicture(canvas, picture, strategy);
302 canvas->restore();
303
304 canvas->translate(105.f, 0.f);
305 }
306}
SkPoint pos
#define SkASSERT(cond)
Definition SkAssert.h:116
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
constexpr SkColor SK_ColorTRANSPARENT
Definition SkColor.h:99
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
@ kNormal
glyph outlines modified to improve constrast
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SK_ScalarPI
Definition SkScalar.h:21
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
SkTileMode
Definition SkTileMode.h:13
SkString getName() const override
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
void onOnceBeforeDraw() override
PictureShaderGM(SkScalar tileSize, SkScalar sceneSize, bool useLocalMatrixWrapper=false, float alpha=1)
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkBitmap.cpp:669
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition SkBitmap.cpp:232
void eraseColor(SkColor4f) const
Definition SkBitmap.cpp:442
void drawRect(const SkRect &rect, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void drawPaint(const SkPaint &paint)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
void clear(SkColor color)
Definition SkCanvas.h:1199
int save()
Definition SkCanvas.cpp:451
void concat(const SkMatrix &matrix)
void drawPicture(const SkPicture *picture)
Definition SkCanvas.h:1961
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition SkM44.h:150
static SkM44 Rotate(SkV3 axis, SkScalar radians)
Definition SkM44.h:239
SkM44 & preConcat(const SkM44 &m)
Definition SkM44.h:351
static SkM44 Perspective(float near, float far, float angle)
Definition SkM44.cpp:343
SkM44 & preTranslate(SkScalar x, SkScalar y, SkScalar z=0)
Definition SkM44.cpp:89
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition SkMatrix.cpp:254
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:296
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:452
SkMatrix & preRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:462
SkMatrix & setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:488
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:315
void setStyle(Style style)
Definition SkPaint.cpp:105
void setColor(SkColor color)
Definition SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition SkPaint.h:193
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode, const SkMatrix *localMatrix, const SkRect *tileRect) const
static sk_sp< SkTextBlob > MakeFromString(const char *string, const SkFont &font, SkTextEncoding encoding=SkTextEncoding::kUTF8)
Definition SkTextBlob.h:115
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition gm.cpp:81
const Paint & paint
float SkScalar
Definition extension.cpp:12
#define DEF_GM(CODE)
Definition gm.h:40
#define DEF_SIMPLE_GM(NAME, CANVAS, W, H)
Definition gm.h:50
sk_sp< SkTypeface > DefaultPortableTypeface()
SkColor color_to_565(SkColor color)
SkTileMode tmy
SkTileMode tmx
static struct @267 kTileConfigs[]
const Scalar scale
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkPoint Make(float x, float y)
constexpr float y() const
constexpr float x() const
void inset(float dx, float dy)
Definition SkRect.h:1060
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609