Flutter Engine
The Flutter Engine
drawquadset.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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"
12#include "include/core/SkFont.h"
16#include "include/core/SkRect.h"
19#include "include/core/SkSize.h"
30#include "src/gpu/ganesh/SkGr.h"
32#include "tools/ToolUtils.h"
34
35#include <utility>
36
37static constexpr SkScalar kTileWidth = 40;
38static constexpr SkScalar kTileHeight = 30;
39
40static constexpr int kRowCount = 4;
41static constexpr int kColCount = 3;
42
43static void draw_text(SkCanvas* canvas, const char* text) {
45 canvas->drawString(text, 0, 0, font, SkPaint());
46}
47
48static void draw_gradient_tiles(SkCanvas* canvas, bool alignGradients) {
49 // Always draw the same gradient
50 static constexpr SkPoint pts[] = { {0.f, 0.f}, {0.25f * kTileWidth, 0.25f * kTileHeight} };
51 static constexpr SkColor colors[] = { SK_ColorBLUE, SK_ColorWHITE };
52
54
55 auto rContext = canvas->recordingContext();
56
57 auto gradient = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kMirror);
59 paint.setShader(gradient);
60
61 for (int i = 0; i < kRowCount; ++i) {
62 for (int j = 0; j < kColCount; ++j) {
64 if (alignGradients) {
65 tile.offset(j * kTileWidth, i * kTileHeight);
66 } else {
67 canvas->save();
68 canvas->translate(j * kTileWidth, i * kTileHeight);
69 }
70
71 unsigned aa = SkCanvas::kNone_QuadAAFlags;
72 if (i == 0) {
74 }
75 if (i == kRowCount - 1) {
77 }
78 if (j == 0) {
80 }
81 if (j == kColCount - 1) {
83 }
84
85 if (sdc) {
86 // Use non-public API to leverage general GrPaint capabilities
87 const SkMatrix& view = canvas->getTotalMatrix();
88 SkSurfaceProps props;
89 GrPaint grPaint;
90 SkPaintToGrPaint(rContext, sdc->colorInfo(), paint, view, props, &grPaint);
91 sdc->fillRectWithEdgeAA(nullptr, std::move(grPaint),
92 static_cast<GrQuadAAFlags>(aa), view, tile);
93 } else {
94 // Fallback to solid color on raster backend since the public API only has color
95 SkColor color = alignGradients ? SK_ColorBLUE
96 : (i * kColCount + j) % 2 == 0 ? SK_ColorBLUE
99 tile, nullptr, static_cast<SkCanvas::QuadAAFlags>(aa), color,
101 }
102
103 if (!alignGradients) {
104 // Pop off the matrix translation when drawing unaligned
105 canvas->restore();
106 }
107 }
108 }
109}
110
111static void draw_color_tiles(SkCanvas* canvas, bool multicolor) {
112 for (int i = 0; i < kRowCount; ++i) {
113 for (int j = 0; j < kColCount; ++j) {
115
117 if (multicolor) {
118 color = {(i + 1.f) / kRowCount, (j + 1.f) / kColCount, .4f, 1.f};
119 } else {
120 color = {.2f, .8f, .3f, 1.f};
121 }
122
123 unsigned aa = SkCanvas::kNone_QuadAAFlags;
124 if (i == 0) {
126 }
127 if (i == kRowCount - 1) {
129 }
130 if (j == 0) {
132 }
133 if (j == kColCount - 1) {
135 }
136
138 tile, nullptr, static_cast<SkCanvas::QuadAAFlags>(aa), color.toSkColor(),
140 }
141 }
142}
143
144static void draw_tile_boundaries(SkCanvas* canvas, const SkMatrix& local) {
145 // Draw grid of red lines at interior tile boundaries.
146 static constexpr SkScalar kLineOutset = 10.f;
148 paint.setAntiAlias(true);
149 paint.setColor(SK_ColorRED);
151 paint.setStrokeWidth(0.f);
152 for (int x = 1; x < kColCount; ++x) {
153 SkPoint pts[] = {{x * kTileWidth, 0}, {x * kTileWidth, kRowCount * kTileHeight}};
154 local.mapPoints(pts, 2);
155 SkVector v = pts[1] - pts[0];
156 v.setLength(v.length() + kLineOutset);
157 canvas->drawLine(pts[1] - v, pts[0] + v, paint);
158 }
159 for (int y = 1; y < kRowCount; ++y) {
160 SkPoint pts[] = {{0, y * kTileHeight}, {kTileWidth * kColCount, y * kTileHeight}};
161 local.mapPoints(pts, 2);
162 SkVector v = pts[1] - pts[0];
163 v.setLength(v.length() + kLineOutset);
164 canvas->drawLine(pts[1] - v, pts[0] + v, paint);
165 }
166}
167
168// Tile renderers (column variation)
169typedef void (*TileRenderer)(SkCanvas*);
171 [](SkCanvas* canvas) { draw_gradient_tiles(canvas, /* aligned */ false); },
172 [](SkCanvas* canvas) { draw_gradient_tiles(canvas, /* aligned */ true); },
173 [](SkCanvas* canvas) { draw_color_tiles(canvas, /* multicolor */ false); },
174 [](SkCanvas* canvas) { draw_color_tiles(canvas, /* multicolor */true); },
175};
176static const char* kTileSetNames[] = { "Local", "Aligned", "Green", "Multicolor" };
177static_assert(std::size(kTileSets) == std::size(kTileSetNames), "Count mismatch");
178
179namespace skiagm {
180
181class DrawQuadSetGM : public GM {
182private:
183 SkString getName() const override { return SkString("draw_quad_set"); }
184 SkISize getISize() override { return SkISize::Make(800, 800); }
185
186 void onDraw(SkCanvas* canvas) override {
187 SkMatrix rowMatrices[5];
188 // Identity
189 rowMatrices[0].setIdentity();
190 // Translate/scale
191 rowMatrices[1].setTranslate(5.5f, 20.25f);
192 rowMatrices[1].postScale(.9f, .7f);
193 // Rotation
194 rowMatrices[2].setRotate(20.0f);
195 rowMatrices[2].preTranslate(15.f, -20.f);
196 // Skew
197 rowMatrices[3].setSkew(.5f, .25f);
198 rowMatrices[3].preTranslate(-30.f, 0.f);
199 // Perspective
200 SkPoint src[4];
202 SkPoint dst[4] = {{0, 0},
203 {kColCount * kTileWidth + 10.f, 15.f},
204 {kColCount * kTileWidth - 28.f, kRowCount * kTileHeight + 40.f},
205 {25.f, kRowCount * kTileHeight - 15.f}};
206 SkAssertResult(rowMatrices[4].setPolyToPoly(src, dst, 4));
207 rowMatrices[4].preTranslate(0.f, +10.f);
208 static const char* matrixNames[] = { "Identity", "T+S", "Rotate", "Skew", "Perspective" };
209 static_assert(std::size(matrixNames) == std::size(rowMatrices), "Count mismatch");
210
211 // Print a column header
212 canvas->save();
213 canvas->translate(110.f, 20.f);
214 for (size_t j = 0; j < std::size(kTileSetNames); ++j) {
215 draw_text(canvas, kTileSetNames[j]);
216 canvas->translate(kColCount * kTileWidth + 30.f, 0.f);
217 }
218 canvas->restore();
219 canvas->translate(0.f, 40.f);
220
221 // Render all tile variations
222 for (size_t i = 0; i < std::size(rowMatrices); ++i) {
223 canvas->save();
224 canvas->translate(10.f, 0.5f * kRowCount * kTileHeight);
225 draw_text(canvas, matrixNames[i]);
226
227 canvas->translate(100.f, -0.5f * kRowCount * kTileHeight);
228 for (size_t j = 0; j < std::size(kTileSets); ++j) {
229 canvas->save();
230 draw_tile_boundaries(canvas, rowMatrices[i]);
231
232 canvas->concat(rowMatrices[i]);
233 kTileSets[j](canvas);
234 // Undo the local transformation
235 canvas->restore();
236 // And advance to the next column
237 canvas->translate(kColCount * kTileWidth + 30.f, 0.f);
238 }
239 // Reset back to the left edge
240 canvas->restore();
241 // And advance to the next row
242 canvas->translate(0.f, kRowCount * kTileHeight + 20.f);
243 }
244 }
245};
246
247DEF_GM(return new DrawQuadSetGM();)
248
249} // namespace skiagm
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
GrQuadAAFlags
Definition: GrTypesPriv.h:247
@ kSrcOver
r = s + (1-sa)*d
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
bool SkPaintToGrPaint(GrRecordingContext *context, const GrColorInfo &dstColorInfo, const SkPaint &skPaint, const SkMatrix &ctm, const SkSurfaceProps &surfaceProps, GrPaint *grPaint)
Definition: SkGr.cpp:553
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
void experimental_DrawEdgeAAQuad(const SkRect &rect, const SkPoint clip[4], QuadAAFlags aaFlags, const SkColor4f &color, SkBlendMode mode)
Definition: SkCanvas.cpp:1845
SkMatrix getTotalMatrix() const
Definition: SkCanvas.cpp:1629
int save()
Definition: SkCanvas.cpp:447
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
void drawString(const char str[], SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
Definition: SkCanvas.h:1803
@ kTop_QuadAAFlag
Definition: SkCanvas.h:1660
@ kRight_QuadAAFlag
Definition: SkCanvas.h:1661
@ kLeft_QuadAAFlag
Definition: SkCanvas.h:1659
@ kBottom_QuadAAFlag
Definition: SkCanvas.h:1662
@ kNone_QuadAAFlags
Definition: SkCanvas.h:1664
Definition: SkFont.h:35
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)
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:360
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:254
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:452
SkMatrix & setIdentity()
Definition: SkMatrix.h:626
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:263
SkMatrix & setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:488
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
DlColor color
void(* TileRenderer)(SkCanvas *)
static void draw_gradient_tiles(SkCanvas *canvas, bool alignGradients)
Definition: drawquadset.cpp:48
static void draw_color_tiles(SkCanvas *canvas, bool multicolor)
static const char * kTileSetNames[]
static TileRenderer kTileSets[]
static constexpr SkScalar kTileHeight
Definition: drawquadset.cpp:38
static constexpr SkScalar kTileWidth
Definition: drawquadset.cpp:37
static constexpr int kRowCount
Definition: drawquadset.cpp:40
static constexpr int kColCount
Definition: drawquadset.cpp:41
static void draw_text(SkCanvas *canvas, const char *text)
Definition: drawquadset.cpp:43
static void draw_tile_boundaries(SkCanvas *canvas, const SkMatrix &local)
float SkScalar
Definition: extension.cpp:12
std::u16string text
double y
double x
PODArray< SkColor > colors
Definition: SkRecords.h:276
sk_sp< SkTypeface > DefaultPortableTypeface()
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
font
Font Metadata and Metrics.
dst
Definition: cp.py:12
SurfaceDrawContext * TopDeviceSurfaceDrawContext(const SkCanvas *canvas)
Definition: GrCanvas.cpp:20
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
bool setLength(float length)
Definition: SkPoint.cpp:30
float length() const
Definition: SkPoint_impl.h:282
void toQuad(SkPoint quad[4]) const
Definition: SkRect.cpp:50
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
void offset(float dx, float dy)
Definition: SkRect.h:1016
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609