Flutter Engine
The Flutter Engine
GrTestUtils.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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
9
14#include "src/core/SkRectPriv.h"
20
21#if defined(GR_TEST_UTILS)
22
23static const SkMatrix& test_matrix(SkRandom* random,
24 bool includeNonPerspective,
25 bool includePerspective) {
26 static SkMatrix gMatrices[5];
27 static const int kPerspectiveCount = 1;
28 static bool gOnce;
29 if (!gOnce) {
30 gOnce = true;
31 gMatrices[0].reset();
37
38 // Perspective matrices
40 gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f);
41 gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f);
42 }
43
44 uint32_t count = static_cast<uint32_t>(std::size(gMatrices));
45 if (includeNonPerspective && includePerspective) {
46 return gMatrices[random->nextULessThan(count)];
47 } else if (!includeNonPerspective) {
48 return gMatrices[count - 1 - random->nextULessThan(kPerspectiveCount)];
49 } else {
50 SkASSERT(includeNonPerspective && !includePerspective);
51 return gMatrices[random->nextULessThan(count - kPerspectiveCount)];
52 }
53}
54
55namespace GrTest {
56const SkMatrix& TestMatrix(SkRandom* random) { return test_matrix(random, true, true); }
57
58const SkMatrix& TestMatrixPreservesRightAngles(SkRandom* random) {
59 static SkMatrix gMatrices[5];
60 static bool gOnce;
61 if (!gOnce) {
62 gOnce = true;
63 // identity
64 gMatrices[0].reset();
65 // translation
67 // scale
69 // scale + translation
72 // orthogonal basis vectors
73 gMatrices[4].reset();
75 gMatrices[4].setRotate(47);
76
77 for (size_t i = 0; i < std::size(gMatrices); i++) {
78 SkASSERT(gMatrices[i].preservesRightAngles());
79 }
80 }
81 return gMatrices[random->nextULessThan(static_cast<uint32_t>(std::size(gMatrices)))];
82}
83
84const SkMatrix& TestMatrixRectStaysRect(SkRandom* random) {
85 static SkMatrix gMatrices[6];
86 static bool gOnce;
87 if (!gOnce) {
88 gOnce = true;
89 // identity
90 gMatrices[0].reset();
91 // translation
93 // scale
95 // scale + translation
98 // reflection
100 // 90 degress rotation
101 gMatrices[5].setRotate(90);
102
103 for (size_t i = 0; i < std::size(gMatrices); i++) {
104 SkASSERT(gMatrices[i].rectStaysRect());
105 }
106 }
107 return gMatrices[random->nextULessThan(static_cast<uint32_t>(std::size(gMatrices)))];
108}
109
110const SkMatrix& TestMatrixInvertible(SkRandom* random) { return test_matrix(random, true, false); }
111const SkMatrix& TestMatrixPerspective(SkRandom* random) { return test_matrix(random, false, true); }
112
113void TestWrapModes(SkRandom* random, GrSamplerState::WrapMode wrapModes[2]) {
114 static const GrSamplerState::WrapMode kWrapModes[] = {
118 };
119 wrapModes[0] = kWrapModes[random->nextULessThan(std::size(kWrapModes))];
120 wrapModes[1] = kWrapModes[random->nextULessThan(std::size(kWrapModes))];
121}
122const SkRect& TestRect(SkRandom* random) {
123 static SkRect gRects[7];
124 static bool gOnce;
125 if (!gOnce) {
126 gOnce = true;
127 gRects[0] = SkRect::MakeWH(1.f, 1.f);
128 gRects[1] = SkRect::MakeWH(1.0f, 256.0f);
129 gRects[2] = SkRect::MakeWH(256.0f, 1.0f);
130 gRects[3] = SkRectPriv::MakeLargest();
131 gRects[4] = SkRect::MakeLTRB(-65535.0f, -65535.0f, 65535.0f, 65535.0f);
132 gRects[5] = SkRect::MakeLTRB(-10.0f, -10.0f, 10.0f, 10.0f);
133 }
134 return gRects[random->nextULessThan(static_cast<uint32_t>(std::size(gRects)))];
135}
136
137// Just some simple rects for code which expects its input very sanitized
138const SkRect& TestSquare(SkRandom* random) {
139 static SkRect gRects[2];
140 static bool gOnce;
141 if (!gOnce) {
142 gOnce = true;
143 gRects[0] = SkRect::MakeWH(128.f, 128.f);
144 gRects[1] = SkRect::MakeWH(256.0f, 256.0f);
145 }
146 return gRects[random->nextULessThan(static_cast<uint32_t>(std::size(gRects)))];
147}
148
149const SkRRect& TestRRectSimple(SkRandom* random) {
150 static SkRRect gRRect[2];
151 static bool gOnce;
152 if (!gOnce) {
153 gOnce = true;
154 SkRect rectangle = SkRect::MakeWH(10.f, 20.f);
155 // true round rect with circular corners
156 gRRect[0].setRectXY(rectangle, 1.f, 1.f);
157 // true round rect with elliptical corners
158 gRRect[1].setRectXY(rectangle, 2.0f, 1.0f);
159
160 for (size_t i = 0; i < std::size(gRRect); i++) {
161 SkASSERT(gRRect[i].isSimple());
162 }
163 }
164 return gRRect[random->nextULessThan(static_cast<uint32_t>(std::size(gRRect)))];
165}
166
167const SkPath& TestPath(SkRandom* random) {
168 static SkPath gPath[7];
169 static bool gOnce;
170 if (!gOnce) {
171 gOnce = true;
172 // line
173 gPath[0] = SkPathBuilder().moveTo(0.f, 0.f)
174 .lineTo(10.f, 10.f)
175 .detach();
176 // quad
177 gPath[1] = SkPathBuilder().moveTo(0.f, 0.f)
178 .quadTo(10.f, 10.f, 20.f, 20.f)
179 .detach();
180 // conic
181 gPath[2] = SkPathBuilder().moveTo(0.f, 0.f)
182 .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
183 .detach();
184 // cubic
185 gPath[3] = SkPathBuilder().moveTo(0.f, 0.f)
186 .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
187 .detach();
188 // all three
189 gPath[4] = SkPathBuilder().moveTo(0.f, 0.f)
190 .lineTo(10.f, 10.f)
191 .quadTo(10.f, 10.f, 20.f, 20.f)
192 .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
193 .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
194 .detach();
195 // convex
196 gPath[5] = SkPathBuilder().moveTo(0.0f, 0.0f)
197 .lineTo(10.0f, 0.0f)
198 .lineTo(10.0f, 10.0f)
199 .lineTo(0.0f, 10.0f)
200 .close()
201 .detach();
202 // concave
203 gPath[6] = SkPathBuilder().moveTo(0.0f, 0.0f)
204 .lineTo(5.0f, 5.0f)
205 .lineTo(10.0f, 0.0f)
206 .lineTo(10.0f, 10.0f)
207 .lineTo(0.0f, 10.0f)
208 .close()
209 .detach();
210 }
211
212 return gPath[random->nextULessThan(static_cast<uint32_t>(std::size(gPath)))];
213}
214
215const SkPath& TestPathConvex(SkRandom* random) {
216 static SkPath gPath[3];
217 static bool gOnce;
218 if (!gOnce) {
219 gOnce = true;
220 // narrow rect
221 gPath[0] = SkPath::Polygon({{-1.5f, -50.0f},
222 {-1.5f, -50.0f},
223 { 1.5f, -50.0f},
224 { 1.5f, 50.0f},
225 {-1.5f, 50.0f}}, false);
226 // degenerate
227 gPath[1] = SkPath::Polygon({{-0.025f, -0.025f},
228 {-0.025f, -0.025f},
229 { 0.025f, -0.025f},
230 { 0.025f, 0.025f},
231 {-0.025f, 0.025f}}, false);
232 // clipped triangle
233 gPath[2] = SkPath::Polygon({{-10.0f, -50.0f},
234 {-10.0f, -50.0f},
235 { 10.0f, -50.0f},
236 { 50.0f, 31.0f},
237 { 40.0f, 50.0f},
238 {-40.0f, 50.0f},
239 {-50.0f, 31.0f}}, false);
240
241 for (size_t i = 0; i < std::size(gPath); i++) {
242 SkASSERT(gPath[i].isConvex());
243 }
244 }
245
246 return gPath[random->nextULessThan(static_cast<uint32_t>(std::size(gPath)))];
247}
248
249static void randomize_stroke_rec(SkStrokeRec* rec, SkRandom* random) {
250 bool strokeAndFill = random->nextBool();
251 SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
252 rec->setStrokeStyle(strokeWidth, strokeAndFill);
253
256 SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
257 rec->setStrokeParams(cap, join, miterLimit);
258}
259
260SkStrokeRec TestStrokeRec(SkRandom* random) {
263 SkStrokeRec rec(style);
264 randomize_stroke_rec(&rec, random);
265 return rec;
266}
267
268void TestStyle(SkRandom* random, GrStyle* style) {
269 SkStrokeRec::InitStyle initStyle =
271 SkStrokeRec stroke(initStyle);
272 randomize_stroke_rec(&stroke, random);
274 if (random->nextBool()) {
275 int cnt = random->nextRangeU(1, 50) * 2;
276 std::unique_ptr<SkScalar[]> intervals(new SkScalar[cnt]);
277 SkScalar sum = 0;
278 for (int i = 0; i < cnt; i++) {
279 intervals[i] = random->nextRangeScalar(SkDoubleToScalar(0.01),
280 SkDoubleToScalar(10.0));
281 sum += intervals[i];
282 }
283 SkScalar phase = random->nextRangeScalar(0, sum);
284 pe = TestDashPathEffect::Make(intervals.get(), cnt, phase);
285 }
286 *style = GrStyle(stroke, std::move(pe));
287}
288
289TestDashPathEffect::TestDashPathEffect(const SkScalar* intervals, int count, SkScalar phase) {
290 fCount = count;
291 fIntervals.reset(count);
292 memcpy(fIntervals.get(), intervals, count * sizeof(SkScalar));
293 SkDashPath::CalcDashParameters(phase, intervals, count, &fInitialDashLength,
294 &fInitialDashIndex, &fIntervalLength, &fPhase);
295}
296
297bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
298 const SkRect* cullRect, const SkMatrix&) const {
299 return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
300 fInitialDashLength, fInitialDashIndex, fIntervalLength,
301 fPhase);
302}
303
304SkPathEffect::DashType TestDashPathEffect::onAsADash(DashInfo* info) const {
305 if (info) {
306 if (info->fCount >= fCount && info->fIntervals) {
307 memcpy(info->fIntervals, fIntervals.get(), fCount * sizeof(SkScalar));
308 }
309 info->fCount = fCount;
310 info->fPhase = fPhase;
311 }
312 return kDash_DashType;
313}
314
315sk_sp<SkColorSpace> TestColorSpace(SkRandom* random) {
316 static sk_sp<SkColorSpace> gColorSpaces[3];
317 static bool gOnce;
318 if (!gOnce) {
319 gOnce = true;
320 // No color space (legacy mode)
321 gColorSpaces[0] = nullptr;
322 // sRGB or color-spin sRGB
323 gColorSpaces[1] = SkColorSpace::MakeSRGB();
324 gColorSpaces[2] = SkColorSpace::MakeSRGB()->makeColorSpin();
325 }
326 return gColorSpaces[random->nextULessThan(static_cast<uint32_t>(std::size(gColorSpaces)))];
327}
328
329sk_sp<GrColorSpaceXform> TestColorXform(SkRandom* random) {
330 // TODO: Add many more kinds of xforms here
331 static sk_sp<GrColorSpaceXform> gXforms[3];
332 static bool gOnce;
333 if (!gOnce) {
334 gOnce = true;
337 // No gamut change
338 gXforms[0] = nullptr;
342 srgb.get(), kPremul_SkAlphaType);
343 }
344 return gXforms[random->nextULessThan(static_cast<uint32_t>(std::size(gXforms)))];
345}
346
347TestAsFPArgs::TestAsFPArgs(GrProcessorTestData* d)
348 : fColorInfoStorage(std::make_unique<GrColorInfo>(
349 GrColorType::kRGBA_8888, kPremul_SkAlphaType, TestColorSpace(d->fRandom)))
350 , fArgs(d->context(), fColorInfoStorage.get(), fSurfaceProps, GrFPArgs::Scope::kDefault) {}
351
352TestAsFPArgs::~TestAsFPArgs() {}
353
354GrColor RandomColor(SkRandom* random) {
355 // There are only a few cases of random colors which interest us
356 enum ColorMode {
357 kAllOnes_ColorMode,
358 kAllZeros_ColorMode,
359 kAlphaOne_ColorMode,
360 kRandom_ColorMode,
361 kLast_ColorMode = kRandom_ColorMode
362 };
363
364 ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
366 switch (colorMode) {
367 case kAllOnes_ColorMode:
368 color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
369 break;
370 case kAllZeros_ColorMode:
371 color = GrColorPackRGBA(0, 0, 0, 0);
372 break;
373 case kAlphaOne_ColorMode:
374 color = GrColorPackRGBA(random->nextULessThan(256),
375 random->nextULessThan(256),
376 random->nextULessThan(256),
377 0xFF);
378 break;
379 case kRandom_ColorMode: {
380 uint8_t alpha = random->nextULessThan(256);
381 color = GrColorPackRGBA(random->nextRangeU(0, alpha),
382 random->nextRangeU(0, alpha),
383 random->nextRangeU(0, alpha),
384 alpha);
385 break;
386 }
387 }
388 return color;
389}
390
391uint8_t RandomCoverage(SkRandom* random) {
392 enum CoverageMode {
393 kZero_CoverageMode,
394 kAllOnes_CoverageMode,
395 kRandom_CoverageMode,
396 kLast_CoverageMode = kRandom_CoverageMode
397 };
398
399 CoverageMode colorMode = CoverageMode(random->nextULessThan(kLast_CoverageMode + 1));
401 switch (colorMode) {
402 case kZero_CoverageMode:
403 coverage = 0;
404 break;
405 case kAllOnes_CoverageMode:
406 coverage = 0xff;
407 break;
408 case kRandom_CoverageMode:
409 coverage = random->nextULessThan(256);
410 break;
411 }
412 return coverage;
413}
414
415} // namespace GrTest
416
417#endif
static const int strokeWidth
Definition: BlurTest.cpp:60
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkScalar fIntervals[2]
Definition: DashOp.cpp:190
SkScalar fPhase
Definition: DashOp.cpp:189
int count
Definition: FontMgrTest.cpp:50
static GrColor GrColorPackRGBA(unsigned r, unsigned g, unsigned b, unsigned a)
Definition: GrColor.h:46
uint32_t GrColor
Definition: GrColor.h:25
GrColorType
Definition: GrTypesPriv.h:540
static void test_matrix(skiatest::Reporter *reporter)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define SK_INIT_TO_AVOID_WARNING
Definition: SkMacros.h:58
#define SK_ScalarHalf
Definition: SkScalar.h:19
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
#define SkIntToScalar(x)
Definition: SkScalar.h:57
static sk_sp< GrColorSpaceXform > Make(SkColorSpace *src, SkAlphaType srcAT, SkColorSpace *dst, SkAlphaType dstAT)
static sk_sp< SkColorSpace > MakeSRGB()
sk_sp< SkColorSpace > makeColorSpin() const
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:360
static constexpr int kMPersp1
input y perspective factor
Definition: SkMatrix.h:360
SkMatrix & set(int index, SkScalar value)
Definition: SkMatrix.h:489
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
static constexpr int kMPersp0
input x perspective factor
Definition: SkMatrix.h:359
SkMatrix & reset()
Definition: SkMatrix.cpp:49
static constexpr int kCapCount
Definition: SkPaint.h:343
static constexpr int kJoinCount
Definition: SkPaint.h:368
SkPathBuilder & conicTo(SkPoint pt1, SkPoint pt2, SkScalar w)
SkPathBuilder & close()
SkPathBuilder & lineTo(SkPoint pt)
SkPathBuilder & cubicTo(SkPoint pt1, SkPoint pt2, SkPoint pt3)
SkPathBuilder & moveTo(SkPoint pt)
SkPathBuilder & quadTo(SkPoint pt1, SkPoint pt2)
Definition: SkPath.h:59
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition: SkPath.cpp:3614
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.cpp:52
bool nextBool()
Definition: SkRandom.h:117
SkScalar nextRangeScalar(SkScalar min, SkScalar max)
Definition: SkRandom.h:106
uint32_t nextULessThan(uint32_t count)
Definition: SkRandom.h:93
uint32_t nextRangeU(uint32_t min, uint32_t max)
Definition: SkRandom.h:80
static SkRect MakeLargest()
Definition: SkRectPriv.h:39
void setStrokeStyle(SkScalar width, bool strokeAndFill=false)
Definition: SkStrokeRec.cpp:91
void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit)
Definition: SkStrokeRec.h:65
T * get() const
Definition: SkRefCnt.h:303
DlColor color
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
@ kDefault
bool InternalFilter(SkPath *dst, const SkPath &src, SkStrokeRec *rec, const SkRect *cullRect, const SkScalar aIntervals[], int32_t count, SkScalar initialDashLength, int32_t initialDashIndex, SkScalar intervalLength, SkScalar startPhase, StrokeRecApplication=StrokeRecApplication::kAllow)
Definition: SkDashPath.cpp:309
void CalcDashParameters(SkScalar phase, const SkScalar intervals[], int32_t count, SkScalar *initialDashLength, int32_t *initialDashIndex, SkScalar *intervalLength, SkScalar *adjustedPhase=nullptr)
Definition: SkDashPath.cpp:54
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
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
const myers::Point & get(const myers::Segment &)
const SkMatrix gMatrices[]
Definition: ref_ptr.h:256
static SkString join(const CommandLineFlags::StringArray &)
Definition: skpbench.cpp:741
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646
static sk_sp< SkColorFilter > spin(sk_sp< SkColorFilter > cf)