Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
int count
static GrColor GrColorPackRGBA(unsigned r, unsigned g, unsigned b, unsigned a)
Definition GrColor.h:46
uint32_t GrColor
Definition GrColor.h:25
GrColorType
SkColor4f color
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)
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition SkPath.cpp:3546
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)
void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit)
Definition SkStrokeRec.h:65
T * get() const
Definition SkRefCnt.h:303
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
float SkScalar
Definition extension.cpp:12
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)
void CalcDashParameters(SkScalar phase, const SkScalar intervals[], int32_t count, SkScalar *initialDashLength, int32_t *initialDashIndex, SkScalar *intervalLength, SkScalar *adjustedPhase=nullptr)
const myers::Point & get(const myers::Segment &)
const SkMatrix gMatrices[]
SINT Vec< 2 *N, T > join(const Vec< N, T > &lo, const Vec< N, T > &hi)
Definition SkVx.h:242
Definition ref_ptr.h:256
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)