Flutter Engine
The Flutter Engine
vertices.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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/SkSize.h"
27#include "src/base/SkRandom.h"
31#include "tools/DecodeUtils.h"
32#include "tools/Resources.h"
33#include "tools/ToolUtils.h"
34
35#include <initializer_list>
36#include <utility>
37
38static constexpr SkScalar kShaderSize = 40;
40 const SkColor colors[] = {
43 };
44 const SkPoint pts[] = {{kShaderSize / 4, 0}, {3 * kShaderSize / 4, kShaderSize}};
45 const SkMatrix localMatrix = SkMatrix::Scale(shaderScale, shaderScale);
46
50 &localMatrix);
51 // Throw in a couple of local matrix wrappers for good measure.
52 return shaderScale == 1 ? grad
55}
56
59}
60
63}
64
65static constexpr SkScalar kMeshSize = 30;
66
67// start with the center of a 3x3 grid of vertices.
68static constexpr uint16_t kMeshFan[] = {
69 4,
70 0, 1, 2, 5, 8, 7, 6, 3, 0
71};
72
73static const int kMeshIndexCnt = (int)std::size(kMeshFan);
74static const int kMeshVertexCnt = 9;
75
77 SkColor colors[kMeshVertexCnt], SkScalar shaderScale) {
78 pts[0].set(0, 0);
79 pts[1].set(kMeshSize / 2, 3);
80 pts[2].set(kMeshSize, 0);
81 pts[3].set(3, kMeshSize / 2);
82 pts[4].set(kMeshSize / 2, kMeshSize / 2);
83 pts[5].set(kMeshSize - 3, kMeshSize / 2);
84 pts[6].set(0, kMeshSize);
85 pts[7].set(kMeshSize / 2, kMeshSize - 3);
86 pts[8].set(kMeshSize, kMeshSize);
87
88 const auto shaderSize = kShaderSize * shaderScale;
89 texs[0].set(0, 0);
90 texs[1].set(shaderSize / 2, 0);
91 texs[2].set(shaderSize, 0);
92 texs[3].set(0, shaderSize / 2);
93 texs[4].set(shaderSize / 2, shaderSize / 2);
94 texs[5].set(shaderSize, shaderSize / 2);
95 texs[6].set(0, shaderSize);
96 texs[7].set(shaderSize / 2, shaderSize);
97 texs[8].set(shaderSize, shaderSize);
98
99 SkRandom rand;
100 for (size_t i = 0; i < kMeshVertexCnt; ++i) {
101 colors[i] = rand.nextU() | 0xFF000000;
102 }
103}
104
105class VerticesGM : public skiagm::GM {
107 SkPoint fTexs[kMeshVertexCnt];
108 SkColor fColors[kMeshVertexCnt];
109 sk_sp<SkShader> fShader1;
110 sk_sp<SkShader> fShader2;
111 sk_sp<SkColorFilter> fColorFilter;
112 SkScalar fShaderScale;
113
114public:
115 VerticesGM(SkScalar shaderScale) : fShaderScale(shaderScale) {}
116
117protected:
118
119 void onOnceBeforeDraw() override {
120 fill_mesh(fPts, fTexs, fColors, fShaderScale);
121 fShader1 = make_shader1(fShaderScale);
122 fShader2 = make_shader2();
123 fColorFilter = make_color_filter();
124 }
125
126 SkString getName() const override {
127 SkString name("vertices");
128 if (fShaderScale != 1) {
129 name.append("_scaled_shader");
130 }
131 return name;
132 }
133
134 SkISize getISize() override { return SkISize::Make(975, 1175); }
135
136 void onDraw(SkCanvas* canvas) override {
137 const SkBlendMode modes[] = {
167 };
168
170
171 canvas->translate(4, 4);
172 for (auto mode : modes) {
173 canvas->save();
174 for (float alpha : {1.0f, 0.5f}) {
175 for (const auto& cf : {sk_sp<SkColorFilter>(nullptr), fColorFilter}) {
176 for (const auto& shader : {fShader1, fShader2}) {
177 static constexpr struct {
178 bool fHasColors;
179 bool fHasTexs;
180 } kAttrs[] = {{true, false}, {false, true}, {true, true}};
181 for (auto attrs : kAttrs) {
182 paint.setShader(shader);
183 paint.setColorFilter(cf);
184 paint.setAlphaf(alpha);
185
186 const SkColor* colors = attrs.fHasColors ? fColors : nullptr;
187 const SkPoint* texs = attrs.fHasTexs ? fTexs : nullptr;
191 canvas->drawVertices(v, mode, paint);
192 canvas->translate(40, 0);
193 }
194 }
195 }
196 }
197 canvas->restore();
198 canvas->translate(0, 40);
199 }
200 }
201
202private:
203 using INHERITED = skiagm::GM;
204};
205
206/////////////////////////////////////////////////////////////////////////////////////
207
208DEF_GM(return new VerticesGM(1);)
209DEF_GM(return new VerticesGM(1 / kShaderSize);)
210
211static void draw_batching(SkCanvas* canvas) {
212 // Triangle fans can't batch so we convert to regular triangles,
213 static constexpr int kNumTris = kMeshIndexCnt - 2;
217
218 SkPoint* pts = builder.positions();
219 SkPoint* texs = builder.texCoords();
220 SkColor* colors = builder.colors();
221 fill_mesh(pts, texs, colors, 1);
222
223 SkTDArray<SkMatrix> matrices;
224 matrices.append()->reset();
225 matrices.append()->setTranslate(0, 40);
226 matrices.append()
227 ->setRotate(45, kMeshSize / 2, kMeshSize / 2)
228 .postScale(1.2f, .8f, kMeshSize / 2, kMeshSize / 2)
229 .postTranslate(0, 80);
230
231 auto shader = make_shader1(1);
232
233 uint16_t* indices = builder.indices();
234 for (size_t i = 0; i < kNumTris; ++i) {
235 indices[3 * i] = kMeshFan[0];
236 indices[3 * i + 1] = kMeshFan[i + 1];
237 indices[3 * i + 2] = kMeshFan[i + 2];
238
239 }
240
241 canvas->save();
242 canvas->translate(10, 10);
243 for (bool useShader : {false, true}) {
244 for (bool useTex : {false, true}) {
245 for (const auto& m : matrices) {
246 canvas->save();
247 canvas->concat(m);
249 paint.setShader(useShader ? shader : nullptr);
250 paint.setColor(SK_ColorWHITE);
251
252 const SkPoint* t = useTex ? texs : nullptr;
254 pts, t, colors, kNumTris * 3, indices);
256 canvas->restore();
257 }
258 canvas->translate(0, 120);
259 }
260 }
261 canvas->restore();
262}
263
264// This test exists to exercise batching in the gpu backend.
265DEF_SIMPLE_GM(vertices_batching, canvas, 100, 500) {
266 draw_batching(canvas);
267 canvas->translate(50, 0);
268 draw_batching(canvas);
269}
270
271// Test case for skbug.com/10069. We need to draw the vertices twice (with different matrices) to
272// trigger the bug.
273DEF_SIMPLE_GM(vertices_perspective, canvas, 256, 256) {
276
277 SkRect r = SkRect::MakeWH(128, 128);
278
279 SkPoint pos[4];
280 r.toQuad(pos);
282
283 SkMatrix persp;
284 persp.setPerspY(SK_Scalar1 / 100);
285
286 canvas->save();
287 canvas->concat(persp);
288 canvas->drawRect(r, paint);
289 canvas->restore();
290
291 canvas->save();
292 canvas->translate(r.width(), 0);
293 canvas->concat(persp);
294 canvas->drawRect(r, paint);
295 canvas->restore();
296
297 canvas->save();
298 canvas->translate(0, r.height());
299 canvas->concat(persp);
301 canvas->restore();
302
303 canvas->save();
304 canvas->translate(r.width(), r.height());
305 canvas->concat(persp);
307 canvas->restore();
308}
309
310DEF_SIMPLE_GM(skbug_13047, canvas, 200, 200) {
311 auto image = ToolUtils::GetResourceAsImage("images/mandrill_128.png");
312
313 const float w = image->width();
314 const float h = image->height();
315
316 SkPoint verts[] = {{0, 0}, {200, 0}, {200, 200}, {0, 200}};
317 SkPoint texs[] = {{0, 0}, {w, 0}, {w, h}, {0, h}};
318 uint16_t indices[] = {0, 1, 2, 2, 3, 0};
319
320 auto v = SkVertices::MakeCopy(
321 SkVertices::kTriangles_VertexMode, 4, verts, texs, nullptr, 6, indices);
322
323 auto m = SkMatrix::Scale(2, 2); // ignored in CPU ???
325
326 SkPaint p;
327 p.setShader(s);
328
330}
331
332// Makes sure that drawVertices allows for triangles with "collapsed" UVs, where all three vertices
333// have the same texture coordinate. b/40044794
334DEF_SIMPLE_GM_BG(vertices_collapsed, canvas, 50, 50, SK_ColorWHITE) {
335 SkPoint verts[] = {{5, 5}, {45, 5}, {45, 45}, {5, 45}};
336 SkPoint texs[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
337 uint16_t indices[] = {0, 1, 2, 2, 3, 0};
338
340 SkVertices::kTriangles_VertexMode, 4, verts, texs, nullptr, 6, indices);
341
343 surf->getCanvas()->clear(SK_ColorGREEN);
346 paint.setShader(shader);
347
349}
SkPoint fPts[2]
SkPoint pos
SkBlendMode
Definition: SkBlendMode.h:38
@ kSrcOut
r = s * (1-da)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kPlus
r = min(s + d, 1)
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kDstIn
r = d * sa
@ kModulate
r = s*d
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kScreen
r = s + d - s*d
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDstOut
r = d * (1-sa)
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
@ kSrcIn
r = s * da
@ kClear
r = 0
constexpr SkColor SK_ColorYELLOW
Definition: SkColor.h:139
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
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
#define SK_Scalar1
Definition: SkScalar.h:18
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
void clear(SkColor color)
Definition: SkCanvas.h:1199
int save()
Definition: SkCanvas.cpp:447
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
Definition: SkCanvas.cpp:1720
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
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)
int width() const
Definition: SkImage.h:285
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkImage.cpp:179
int height() const
Definition: SkImage.h:291
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
SkMatrix & setPerspY(SkScalar v)
Definition: SkMatrix.h:544
uint32_t nextU()
Definition: SkRandom.h:42
sk_sp< SkShader > makeWithLocalMatrix(const SkMatrix &) const
Definition: SkShader.cpp:26
SkCanvas * getCanvas()
Definition: SkSurface.cpp:82
sk_sp< SkImage > makeImageSnapshot()
Definition: SkSurface.cpp:90
T * append()
Definition: SkTDArray.h:191
@ kHasTexCoords_BuilderFlag
Definition: SkVertices.h:63
@ kHasColors_BuilderFlag
Definition: SkVertices.h:64
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
Definition: SkVertices.cpp:200
@ kTriangleFan_VertexMode
Definition: SkVertices.h:33
@ kTriangles_VertexMode
Definition: SkVertices.h:31
VerticesGM(SkScalar shaderScale)
Definition: vertices.cpp:115
SkISize getISize() override
Definition: vertices.cpp:134
void onOnceBeforeDraw() override
Definition: vertices.cpp:119
void onDraw(SkCanvas *canvas) override
Definition: vertices.cpp:136
SkString getName() const override
Definition: vertices.cpp:126
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
struct MyStruct s
#define DEF_GM(CODE)
Definition: gm.h:40
PODArray< SkRect > texs
Definition: SkRecords.h:333
sk_sp< const SkImage > image
Definition: SkRecords.h:269
PODArray< SkColor > colors
Definition: SkRecords.h:276
SK_API sk_sp< SkShader > Color(SkColor)
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
sk_sp< SkShader > create_checkerboard_shader(SkColor c1, SkColor c2, int size)
Definition: ToolUtils.cpp:150
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
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
SkSamplingOptions(SkFilterMode::kLinear))
SkScalar w
SkScalar h
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo MakeN32Premul(int width, int height)
void toQuad(SkPoint quad[4]) const
Definition: SkRect.cpp:50
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
DEF_SIMPLE_GM(vertices_batching, canvas, 100, 500)
Definition: vertices.cpp:265
static sk_sp< SkShader > make_shader1(SkScalar shaderScale)
Definition: vertices.cpp:39
static sk_sp< SkShader > make_shader2()
Definition: vertices.cpp:57
static const int kMeshIndexCnt
Definition: vertices.cpp:73
DEF_SIMPLE_GM_BG(vertices_collapsed, canvas, 50, 50, SK_ColorWHITE)
Definition: vertices.cpp:334
static void fill_mesh(SkPoint pts[kMeshVertexCnt], SkPoint texs[kMeshVertexCnt], SkColor colors[kMeshVertexCnt], SkScalar shaderScale)
Definition: vertices.cpp:76
static const int kMeshVertexCnt
Definition: vertices.cpp:74
static constexpr SkScalar kShaderSize
Definition: vertices.cpp:38
static constexpr SkScalar kMeshSize
Definition: vertices.cpp:65
static constexpr uint16_t kMeshFan[]
Definition: vertices.cpp:68
static sk_sp< SkColorFilter > make_color_filter()
Definition: vertices.cpp:61
static void draw_batching(SkCanvas *canvas)
Definition: vertices.cpp:211