Flutter Engine
The Flutter Engine
composeshader.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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"
19#include "include/core/SkRect.h"
23#include "include/core/SkSize.h"
29#include "src/base/SkTLazy.h"
30#include "tools/GpuToolUtils.h"
31#include "tools/ToolUtils.h"
32
33#include <utility>
34
36 SkPoint pts[2];
37 SkColor colors[2];
38
39 pts[0].set(0, 0);
40 pts[1].set(SkIntToScalar(100), 0);
43 auto shaderA = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
44
45 pts[0].set(0, 0);
46 pts[1].set(0, SkIntToScalar(100));
48 colors[1] = SkColorSetARGB(0x80, 0, 0, 0);
49 auto shaderB = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
50
51 return SkShaders::Blend(mode, std::move(shaderA), std::move(shaderB));
52}
53
55protected:
56 void onOnceBeforeDraw() override {
58 }
59
60 SkString getName() const override { return SkString("composeshader"); }
61
62 SkISize getISize() override { return SkISize::Make(120, 120); }
63
64 void onDraw(SkCanvas* canvas) override {
66 paint.setColor(SK_ColorGREEN);
67 canvas->drawRect(SkRect::MakeWH(100, 100), paint);
68 paint.setShader(fShader);
69 canvas->drawRect(SkRect::MakeWH(100, 100), paint);
70 }
71
72protected:
74
75private:
76 typedef GM INHERITED ;
77};
78DEF_GM( return new ComposeShaderGM; )
79
81public:
83
84protected:
85 SkString getName() const override { return SkString("composeshader_alpha"); }
86
87 SkISize getISize() override { return SkISize::Make(750, 220); }
88
89 void onDraw(SkCanvas* canvas) override {
90 sk_sp<SkShader> shaders[] = {
93 };
94
96 paint.setColor(SK_ColorGREEN);
97
98 const SkRect r = SkRect::MakeXYWH(5, 5, 100, 100);
99
100 for (size_t y = 0; y < std::size(shaders); ++y) {
101 canvas->save();
102 for (int alpha = 0xFF; alpha > 0; alpha -= 0x28) {
103 paint.setAlphaf(1.0f);
104 paint.setShader(nullptr);
105 canvas->drawRect(r, paint);
106
107 paint.setAlpha(alpha);
108 paint.setShader(shaders[y]);
109 canvas->drawRect(r, paint);
110
111 canvas->translate(r.width() + 5, 0);
112 }
113 canvas->restore();
114 canvas->translate(0, r.height() + 5);
115 }
116 }
117
118private:
119 typedef GM INHERITED ;
120};
121DEF_GM( return new ComposeShaderAlphaGM; )
122
123// creates a square bitmap with red background and a green circle in the center
124static void draw_color_bm(SkBitmap* bm, int length) {
126 paint.setColor(SK_ColorGREEN);
127
130
131 SkCanvas canvas(*bm);
133 paint);
134}
135
136// creates a square alpha8 bitmap with transparent background and an opaque circle in the center
137static void draw_alpha8_bm(SkBitmap* bm, int length) {
138 SkPaint circlePaint;
139 circlePaint.setColor(SK_ColorBLACK);
140
143
144 SkCanvas canvas(*bm);
146 circlePaint);
147}
148
149// creates a linear gradient shader
151 SkPoint pts[2];
152 SkColor colors[2];
153 pts[0].set(0, 0);
154 pts[1].set(SkIntToScalar(length), 0);
155 colors[0] = SK_ColorBLUE;
156 colors[1] = SkColorSetARGB(0, 0, 0, 0xFF);
158}
159
160
162public:
163 ComposeShaderBitmapGM(bool use_lm) : fUseLocalMatrix(use_lm) {}
164
165protected:
166 SkString getName() const override {
167 return SkStringPrintf("composeshader_bitmap%s", fUseLocalMatrix ? "_lm" : "");
168 }
169
170 SkISize getISize() override {
171 return SkISize::Make(7 * (squareLength + 5), 2 * (squareLength + 5));
172 }
173
174 void onDraw(SkCanvas* canvas) override {
175 if (!fInitialized) {
176 draw_color_bm(&fColorBitmap, squareLength);
177 sk_sp<SkImage> img = SkImages::RasterFromBitmap(fColorBitmap);
178 img = ToolUtils::MakeTextureImage(canvas, std::move(img));
179 if (img) {
180 fColorBitmapShader = img->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
182 }
183 draw_alpha8_bm(&fAlpha8Bitmap, squareLength);
184 img = SkImages::RasterFromBitmap(fAlpha8Bitmap);
185 img = ToolUtils::MakeTextureImage(canvas, std::move(img));
186 if (img) {
187 fAlpha8BitmapShader = fAlpha8Bitmap.makeShader(SkTileMode::kRepeat,
190 SkMatrix::I());
191 }
192 fLinearGradientShader = make_linear_gradient_shader(squareLength);
193 fInitialized = true;
194 }
195
197
198 SkMatrix lm = SkMatrix::Translate(0, squareLength * 0.5f);
199
200 sk_sp<SkShader> shaders[] = {
201 // gradient should appear over color bitmap
202 SkShaders::Blend(mode, fLinearGradientShader, fColorBitmapShader),
203 // gradient should appear over alpha8 bitmap colorized by the paint color
204 SkShaders::Blend(mode, fLinearGradientShader, fAlpha8BitmapShader),
205 };
206 if (fUseLocalMatrix) {
207 for (unsigned i = 0; i < std::size(shaders); ++i) {
208 shaders[i] = shaders[i] ? shaders[i]->makeWithLocalMatrix(lm) : nullptr;
209 }
210 }
211
213 paint.setColor(SK_ColorYELLOW);
214
215 const SkRect r = SkRect::MakeIWH(squareLength, squareLength);
216
217 for (size_t y = 0; y < std::size(shaders); ++y) {
218 canvas->save();
219 for (int alpha = 0xFF; alpha > 0; alpha -= 0x28) {
220 paint.setAlpha(alpha);
221 paint.setShader(shaders[y]);
222 canvas->drawRect(r, paint);
223
224 canvas->translate(r.width() + 5, 0);
225 }
226 canvas->restore();
227 canvas->translate(0, r.height() + 5);
228 }
229 }
230
231private:
232 /** This determines the length and width of the bitmaps used in the ComposeShaders. Values
233 * above 20 may cause an SkASSERT to fail in SkSmallAllocator. However, larger values will
234 * work in a release build. You can change this parameter and then compile a release build
235 * to have this GM draw larger bitmaps for easier visual inspection.
236 */
237 inline static constexpr int squareLength = 20;
238
239 const bool fUseLocalMatrix;
240
241 bool fInitialized = false;
242 SkBitmap fColorBitmap;
243 SkBitmap fAlpha8Bitmap;
244 sk_sp<SkShader> fColorBitmapShader;
245 sk_sp<SkShader> fAlpha8BitmapShader;
246 sk_sp<SkShader> fLinearGradientShader;
247
248 using INHERITED = GM;
249};
250DEF_GM( return new ComposeShaderBitmapGM(false); )
251DEF_GM( return new ComposeShaderBitmapGM(true); )
252
253DEF_SIMPLE_GM(composeshader_bitmap2, canvas, 200, 200) {
254 int width = 255;
255 int height = 255;
256 SkTDArray<uint8_t> dst8Storage;
257 dst8Storage.resize(width * height);
258 SkTDArray<uint32_t> dst32Storage;
259 dst32Storage.resize(width * height * sizeof(int32_t));
260 for (int y = 0; y < height; ++y) {
261 for (int x = 0; x < width; ++x) {
262 dst8Storage[y * width + x] = (y + x) / 2;
263 dst32Storage[y * width + x] = SkPackARGB32(0xFF, x, y, 0);
264 }
265 }
267 paint.setAntiAlias(true);
268 paint.setColor(SK_ColorBLUE);
270 canvas->drawRect(r, paint);
271 SkBitmap skBitmap, skMask;
273 SkColorType::kN32_SkColorType, kPremul_SkAlphaType);
274 skBitmap.installPixels(imageInfo, dst32Storage.begin(), width * sizeof(int32_t),
275 nullptr, nullptr);
276 imageInfo = SkImageInfo::Make(width, height,
278 skMask.installPixels(imageInfo, dst8Storage.begin(), width, nullptr, nullptr);
279 sk_sp<SkImage> skSrc = skBitmap.asImage();
280 sk_sp<SkImage> skMaskImage = skMask.asImage();
281 paint.setShader(
283 skMaskImage->makeShader(SkSamplingOptions()),
284 skSrc->makeShader(SkSamplingOptions())));
285 canvas->drawRect(r, paint);
286}
287
288///////////////////////////////////////////////////////////////////////////////////////////////////
289
291 const SkPoint pts[] = { { 0, 0 }, { 0, size } };
292 const SkColor colors[] = { 0xFF0000FF, 0x000000FF };
294}
295
297 const SkPoint pts[] = { { 0, 0 }, { size, 0 } };
298 const SkColor colors[] = { SK_ColorRED, 0x00FF0000 };
300}
301
302const SkScalar gCellSize = 100;
303
305 SkBlendMode mode, SkAlpha alpha) {
307 SkPaint p;
308 p.setAlpha(alpha);
309
310 SkAutoCanvasRestore acr(canvas, false);
311 canvas->saveLayer(&r, &p);
312 p.setAlpha(0xFF);
313
314 p.setShader(dst);
315 p.setBlendMode(SkBlendMode::kSrc);
316 canvas->drawRect(r, p);
317
318 p.setShader(src);
319 p.setBlendMode(mode);
320 canvas->drawRect(r, p);
321}
322
324 SkBlendMode mode, SkAlpha alpha) {
325 SkPaint p;
326 p.setAlpha(alpha);
327 p.setShader(SkShaders::Blend(mode, dst, src));
329}
330
333 SkAutoCanvasRestore acr(canvas, true);
334
335 const SkScalar gap = 4;
336 SkRect r = SkRect::MakeWH(2 * gCellSize + gap, 2 * gCellSize + gap);
337 r.outset(gap + 1.5f, gap + 1.5f);
338 SkPaint p;
339 p.setStyle(SkPaint::kStroke_Style);
340 canvas->drawRect(r, p); // border
341
342 SkAlpha alpha = 0xFF;
343 for (int y = 0; y < 2; ++y) {
344 draw_cell(canvas, src, dst, mode, alpha);
345 canvas->save();
346 canvas->translate(gCellSize + gap, 0);
347 draw_composed(canvas, src, dst, mode, alpha);
348 canvas->restore();
349
350 canvas->translate(0, gCellSize + gap);
351 alpha = 0x80;
352 }
353}
354
355DEF_SIMPLE_GM(composeshader_grid, canvas, 882, 882) {
358
359 const SkScalar margin = 15;
360 const SkScalar dx = 2*gCellSize + margin;
361 const SkScalar dy = 2*gCellSize + margin;
362
363 canvas->translate(margin, margin);
364 canvas->save();
365 for (int m = 0; m < 16; ++m) {
366 SkBlendMode mode = static_cast<SkBlendMode>(m);
367 draw_pair(canvas, src, dst, mode);
368 if ((m % 4) == 3) {
369 canvas->restore();
370 canvas->translate(0, dy);
371 canvas->save();
372 } else {
373 canvas->translate(dx, 0);
374 }
375 }
376 canvas->restore();
377}
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
SkBlendMode
Definition: SkBlendMode.h:38
@ kDstIn
r = d * sa
@ kSrcOver
r = s + (1-sa)*d
@ kDstOver
r = d + (1-da)*s
@ kSrcIn
r = s * da
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColorPriv.h:106
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
uint32_t SkColor
Definition: SkColor.h:37
uint8_t SkAlpha
Definition: SkColor.h:26
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
#define SkIntToScalar(x)
Definition: SkScalar.h:57
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkString getName() const override
void onDraw(SkCanvas *canvas) override
SkISize getISize() override
ComposeShaderBitmapGM(bool use_lm)
SkString getName() const override
void onDraw(SkCanvas *canvas) override
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
SkISize getISize() override
void onOnceBeforeDraw() override
sk_sp< SkShader > fShader
SkString getName() const override
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
sk_sp< SkImage > asImage() const
Definition: SkBitmap.cpp:645
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
Definition: SkBitmap.cpp:323
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
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
void setColor(SkColor color)
Definition: SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
sk_sp< SkShader > makeWithLocalMatrix(const SkMatrix &) const
Definition: SkShader.cpp:26
T * begin()
Definition: SkTDArray.h:150
void resize(int count)
Definition: SkTDArray.h:183
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
const Paint & paint
Definition: color_source.cc:38
static void draw_cell(SkCanvas *canvas, sk_sp< SkShader > src, sk_sp< SkShader > dst, SkBlendMode mode, SkAlpha alpha)
static sk_sp< SkShader > make_linear_gradient_shader(int length)
static void draw_color_bm(SkBitmap *bm, int length)
static sk_sp< SkShader > make_dst_shader(SkScalar size)
static void draw_composed(SkCanvas *canvas, sk_sp< SkShader > src, sk_sp< SkShader > dst, SkBlendMode mode, SkAlpha alpha)
DEF_SIMPLE_GM(composeshader_bitmap2, canvas, 200, 200)
static sk_sp< SkShader > make_src_shader(SkScalar size)
static void draw_alpha8_bm(SkBitmap *bm, int length)
static void draw_pair(SkCanvas *canvas, sk_sp< SkShader > src, sk_sp< SkShader > dst, SkBlendMode mode)
static sk_sp< SkShader > make_shader(SkBlendMode mode)
const SkScalar gCellSize
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
size_t length
double y
double x
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
PODArray< SkColor > colors
Definition: SkRecords.h:276
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
SK_API sk_sp< SkShader > Blend(SkBlendMode mode, sk_sp< SkShader > dst, sk_sp< SkShader > src)
sk_sp< SkImage > MakeTextureImage(SkCanvas *canvas, sk_sp< SkImage > orig)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
SkSamplingOptions(SkFilterMode::kLinear))
int32_t height
int32_t width
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static SkImageInfo MakeA8(int width, int height)
void set(float x, float y)
Definition: SkPoint_impl.h:200
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
void outset(float dx, float dy)
Definition: SkRect.h:1077
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609