Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
graphitestart.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
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"
15#include "include/core/SkPath.h"
20#include "tools/DecodeUtils.h"
21#include "tools/GpuToolUtils.h"
22#include "tools/Resources.h"
23#include "tools/ToolUtils.h"
24
25namespace {
26
27sk_sp<SkShader> create_gradient_shader(SkRect r,
28 const std::array<SkColor, 3>& colors,
29 const std::array<float, 3>& offsets) {
30 SkPoint pts[2] = { {r.fLeft, r.fTop}, {r.fRight, r.fTop} };
31
32 return SkGradientShader::MakeLinear(pts, colors.data(), offsets.data(), std::size(colors),
34}
35
36sk_sp<SkShader> create_image_shader(SkCanvas* destCanvas, SkTileMode tmX, SkTileMode tmY) {
38
39 {
41 bitmap.allocPixels(ii);
42 bitmap.eraseColor(SK_ColorWHITE);
43
44 SkCanvas tmpCanvas(bitmap);
45
46 SkColor colors[3][3] = {
50 };
51
52 for (int y = 0; y < 3; ++y) {
53 for (int x = 0; x < 3; ++x) {
55 paint.setColor(colors[y][x]);
56 tmpCanvas.drawRect(SkRect::MakeXYWH(x*21, y*21, 22, 22), paint);
57 }
58 }
59
60 bitmap.setAlphaType(kOpaque_SkAlphaType);
61 bitmap.setImmutable();
62 }
63
65 img = ToolUtils::MakeTextureImage(destCanvas, std::move(img));
66 if (img) {
67 return img->makeShader(tmX, tmY, SkSamplingOptions());
68 } else {
69 return nullptr;
70 }
71}
72
73sk_sp<SkShader> create_blend_shader(SkCanvas* destCanvas, SkBlendMode bm) {
74 constexpr SkColor4f kTransYellow = {1.0f, 1.0f, 0.0f, 0.5f};
75
76 sk_sp<SkShader> dst = SkShaders::Color(kTransYellow, nullptr);
77 return SkShaders::Blend(bm,
78 std::move(dst),
79 create_image_shader(destCanvas,
81}
82
83sk_sp<SkColorFilter> create_grayscale_colorfilter() {
84 float matrix[20] = {};
85 matrix[0] = matrix[5] = matrix[10] = 0.2126f;
86 matrix[1] = matrix[6] = matrix[11] = 0.7152f;
87 matrix[2] = matrix[7] = matrix[12] = 0.0722f;
88 matrix[18] = 1.0f;
89 return SkColorFilters::Matrix(matrix);
90}
91
92void draw_image_shader_tile(SkCanvas* canvas, SkRect clipRect) {
93 SkPaint p;
94 p.setShader(create_image_shader(canvas, SkTileMode::kClamp, SkTileMode::kRepeat));
95
97 path.moveTo(1, 1);
98 path.lineTo(32, 127);
99 path.lineTo(96, 127);
100 path.lineTo(127, 1);
101 path.lineTo(63, 32);
102 path.close();
103
104 canvas->save();
105 canvas->clipRect(clipRect);
106 canvas->scale(0.5f, 0.5f);
107 canvas->drawPath(path, p);
108
109 canvas->save();
110 canvas->concat(SkMatrix::RotateDeg(90, {64, 64}));
111 canvas->translate(128, 0);
112 canvas->drawPath(path, p);
113 canvas->restore();
114 canvas->restore();
115}
116
117void draw_gradient_tile(SkCanvas* canvas, SkRect clipRect) {
118 SkRect r{1, 1, 127, 127};
119 SkPaint p;
120 p.setShader(create_gradient_shader(r,
122 { 0.0f, 0.75f, 1.0f }));
123
124 canvas->save();
125 canvas->clipRect(clipRect);
126 canvas->translate(128, 0);
127 canvas->scale(0.5f, 0.5f);
128 canvas->drawRect(r, p);
129
130 canvas->save();
131 canvas->concat(SkMatrix::RotateDeg(90, {64, 64}));
132 canvas->translate(128, 0);
133 canvas->drawRect(r, p);
134 canvas->restore();
135 canvas->restore();
136}
137
138void draw_colorfilter_swatches(SkCanvas* canvas, SkRect clipRect) {
139 static constexpr int kNumTilesPerSide = 3;
140
141 SkSize tileSize = { clipRect.width() / kNumTilesPerSide, clipRect.height() / kNumTilesPerSide };
142
143 // Quantize to four colors
144 uint8_t table1[256];
145 for (int i = 0; i < 256; ++i) {
146 table1[i] = (i/64) * 85;
147 }
148
149 // table2 is a band-pass filter for 85-170.
150 // table3 re-expands that range to 0..255
151 uint8_t table2[256], table3[256];
152 for (int i = 0; i < 256; ++i) {
153 if (i >= 85 && i <= 170) {
154 table2[i] = i;
155 table3[i] = ((i - 85) / 85.0f) * 255.0f;
156 } else {
157 table2[i] = 0;
158 table3[i] = 0;
159 }
160 }
161
162 constexpr SkColor SK_ColorGREY = SkColorSetARGB(0xFF, 0x80, 0x80, 0x80);
163
164 sk_sp<SkColorFilter> colorFilters[kNumTilesPerSide*kNumTilesPerSide];
165 static const std::array<SkColor, 3> kGradientColors[kNumTilesPerSide*kNumTilesPerSide] = {
166 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
167 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
168 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
169 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
170 { 0x00000000, 0x80000000, 0xFF000000 }, // the Gaussian CF uses alpha only
171 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
172 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
173 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
174 { SK_ColorBLACK, SK_ColorGREY, SK_ColorWHITE },
175 };
176
177 colorFilters[0] = SkColorFilters::Lighting(SK_ColorLTGRAY, 0xFF440000);
178 colorFilters[1] = SkColorFilters::Table(table1);
179 colorFilters[2] = SkColorFilters::Compose(SkColorFilters::TableARGB(nullptr, table3,
180 table3, table3),
181 SkColorFilters::TableARGB(nullptr, table2,
182 table2, table2));
184 colorFilters[4] = SkColorFilterPriv::MakeGaussian();
185
186 colorFilters[5] = SkColorFilters::LinearToSRGBGamma();
187 colorFilters[6] = SkColorFilters::SRGBToLinearGamma();
188
189 SkPaint p;
190
191 canvas->save();
192 canvas->clipRect(clipRect);
193 canvas->translate(clipRect.fLeft, clipRect.fTop);
194
195 for (int y = 0; y < kNumTilesPerSide; ++y) {
196 for (int x = 0; x < kNumTilesPerSide; ++x) {
197 SkRect r = SkRect::MakeXYWH(x * tileSize.width(), y * tileSize.height(),
198 tileSize.width(), tileSize.height()).makeInset(1.0f,
199 1.0f);
200 int colorFilterIndex = x*kNumTilesPerSide+y;
201 p.setShader(create_gradient_shader(r,
202 kGradientColors[colorFilterIndex],
203 { 0.0f, 0.5f, 1.0f }));
204 p.setColorFilter(colorFilters[colorFilterIndex]);
205 canvas->drawRect(r, p);
206 }
207 }
208
209 canvas->restore();
210}
211
212void draw_blend_mode_swatches(SkCanvas* canvas, SkRect clipRect) {
213 static const int kTileHeight = 16;
214 static const int kTileWidth = 16;
215 static const SkColor4f kOpaqueWhite { 1.0f, 1.0f, 1.0f, 1.0f };
216 static const SkColor4f kTransBluish { 0.0f, 0.5f, 1.0f, 0.5f };
217 static const SkColor4f kTransWhite { 1.0f, 1.0f, 1.0f, 0.75f };
218
219 SkPaint dstPaint;
220 dstPaint.setColor(kOpaqueWhite);
222 dstPaint.setAntiAlias(false);
223
224 SkPaint srcPaint;
225 srcPaint.setColor(kTransBluish);
226 srcPaint.setAntiAlias(false);
227
229
230 // For the first pass we draw: transparent bluish on top of opaque white
231 // For the second pass we draw: transparent white on top of transparent bluish
232 for (int passes = 0; passes < 2; ++passes) {
233 for (int i = 0; i <= (int)SkBlendMode::kLastCoeffMode; ++i) {
234 if (r.fLeft+kTileWidth > clipRect.fRight) {
235 r.offsetTo(clipRect.fLeft, r.fTop+kTileHeight);
236 }
237
238 canvas->drawRect(r.makeInset(1.0f, 1.0f), dstPaint);
239 srcPaint.setBlendMode(static_cast<SkBlendMode>(i));
240 canvas->drawRect(r.makeInset(2.0f, 2.0f), srcPaint);
241
242 r.offset(kTileWidth, 0.0f);
243 }
244
245 r.offsetTo(clipRect.fLeft, r.fTop+kTileHeight);
246 srcPaint.setColor(kTransWhite);
247 dstPaint.setColor(kTransBluish);
248 }
249}
250
251} // anonymous namespace
252
253namespace skiagm {
254
255// This is just for bootstrapping Graphite.
256class GraphiteStartGM : public GM {
257public:
258 GraphiteStartGM() = default;
259
260protected:
261 static constexpr int kTileWidth = 128;
262 static constexpr int kTileHeight = 128;
263 static constexpr int kWidth = 3 * kTileWidth;
264 static constexpr int kHeight = 3 * kTileHeight;
265 static constexpr int kClipInset = 4;
266
267 void onOnceBeforeDraw() override {
269 ToolUtils::GetResourceAsBitmap("images/color_wheel.gif", &fBitmap);
270 }
271
272 SkString getName() const override { return SkString("graphitestart"); }
273
274 SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
275
276 void onDraw(SkCanvas* canvas) override {
277
279
280 canvas->save();
281 canvas->clipRRect(SkRRect::MakeRectXY(clipRect, 32.f, 32.f), true);
282
283 // Upper-left corner
284 draw_image_shader_tile(canvas, SkRect::MakeXYWH(0, 0, kTileWidth, kTileHeight));
285
286 // Upper-middle tile
287 draw_gradient_tile(canvas, SkRect::MakeXYWH(kTileWidth, 0, kTileWidth, kTileHeight));
288
289 // Upper-right corner
290 draw_colorfilter_swatches(canvas, SkRect::MakeXYWH(2*kTileWidth, 0,
292
293 // Middle-left tile
294 {
295 SkPaint p;
296 p.setColor(SK_ColorRED);
297
299 canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
300 }
301
302 // Middle-middle tile
303 {
304 SkPaint p;
305 p.setShader(create_blend_shader(canvas, SkBlendMode::kModulate));
306
308 canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
309 }
310
311 // Middle-right tile
312 {
313 sk_sp<SkImage> image(ToolUtils::GetResourceAsImage("images/mandrill_128.png"));
314 sk_sp<SkShader> shader;
315
316 if (image) {
318 shader = shader->makeWithColorFilter(create_grayscale_colorfilter());
319 }
320
321 SkPaint p;
322 p.setShader(std::move(shader));
323
325 canvas->drawRect(r.makeInset(1.0f, 1.0f), p);
326 }
327
328 canvas->restore();
329
330 // Bottom-left corner
331#if defined(SK_GRAPHITE)
332 // TODO: failing serialize test on Linux, not sure what's going on
333 canvas->writePixels(fBitmap, 0, 2*kTileHeight);
334#endif
335
336 // Bottom-middle tile
337 draw_blend_mode_swatches(canvas, SkRect::MakeXYWH(kTileWidth, 2*kTileHeight,
339
340 // Bottom-right corner
341 {
344
345 SkPaint circlePaint;
346 circlePaint.setColor(SK_ColorBLUE);
347 circlePaint.setBlendMode(SkBlendMode::kSrc);
348
349 canvas->clipRect(kTile);
350 canvas->drawRect(kTile.makeInset(10, 20), circlePaint);
351
352 SkPaint restorePaint;
353 restorePaint.setBlendMode(SkBlendMode::kPlus);
354
355 canvas->saveLayer(nullptr, &restorePaint);
356 circlePaint.setColor(SK_ColorRED);
357 circlePaint.setBlendMode(SkBlendMode::kSrc);
358
359 canvas->drawRect(kTile.makeInset(15, 25), circlePaint);
360 canvas->restore();
361 }
362 }
363
364private:
365 SkBitmap fBitmap;
366};
367
368//////////////////////////////////////////////////////////////////////////////
369
370DEF_GM(return new GraphiteStartGM;)
371
372} // namespace skiagm
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
SkBlendMode
Definition SkBlendMode.h:38
@ kPlus
r = min(s + d, 1)
@ kModulate
r = s*d
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kLastCoeffMode
last porter duff blend mode
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
constexpr SkColor SK_ColorYELLOW
Definition SkColor.h:139
constexpr SkColor SK_ColorLTGRAY
Definition SkColor.h:118
constexpr SkColor SK_ColorMAGENTA
Definition SkColor.h:147
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorCYAN
Definition SkColor.h:143
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
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
constexpr SkColor SK_ColorDKGRAY
Definition SkColor.h:108
SkTileMode
Definition SkTileMode.h:13
Type::kYUV Type::kRGBA() int(0.7 *637)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition SkCanvas.cpp:500
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)
bool writePixels(const SkImageInfo &info, const void *pixels, size_t rowBytes, int x, int y)
Definition SkCanvas.cpp:403
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
void clipRRect(const SkRRect &rrect, SkClipOp op, bool doAntiAlias)
static sk_sp< SkColorFilter > MakeGaussian()
static sk_sp< SkColorFilter > Compose(const sk_sp< SkColorFilter > &outer, sk_sp< SkColorFilter > inner)
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static sk_sp< SkColorFilter > Table(const uint8_t table[256])
static sk_sp< SkColorFilter > Matrix(const SkColorMatrix &)
static sk_sp< SkColorFilter > Lighting(SkColor mul, SkColor add)
static sk_sp< SkColorFilter > SRGBToLinearGamma()
static sk_sp< SkColorFilter > LinearToSRGBGamma()
static sk_sp< SkColorFilter > TableARGB(const uint8_t tableA[256], const uint8_t tableR[256], const uint8_t tableG[256], const uint8_t tableB[256])
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 RotateDeg(SkScalar deg)
Definition SkMatrix.h:104
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
void setBlendMode(SkBlendMode mode)
Definition SkPaint.cpp:151
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
void setBGColor(SkColor)
Definition gm.cpp:159
void onDraw(SkCanvas *canvas) override
static constexpr int kTileWidth
static constexpr int kWidth
SkISize getISize() override
static constexpr int kClipInset
static constexpr int kHeight
SkString getName() const override
static constexpr int kTileHeight
void onOnceBeforeDraw() override
const Paint & paint
static constexpr SkScalar kTileHeight
static constexpr SkScalar kTileWidth
sk_sp< SkImage > image
Definition examples.cpp:29
#define DEF_GM(CODE)
Definition gm.h:40
double y
double x
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
PODArray< SkColor > colors
Definition SkRecords.h:276
sk_sp< SkImage > MakeTextureImage(SkCanvas *canvas, sk_sp< SkImage > orig)
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition DecodeUtils.h:25
bool GetResourceAsBitmap(const char *resource, SkBitmap *dst)
Definition DecodeUtils.h:21
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
dst
Definition cp.py:12
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)
void offsetTo(float newX, float newY)
Definition SkRect.h:1043
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
SkRect makeInset(float dx, float dy) const
Definition SkRect.h:987
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void offset(float dx, float dy)
Definition SkRect.h:1016
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15
SkScalar width() const
Definition SkSize.h:76
SkScalar height() const
Definition SkSize.h:77