Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/gpu/GrTestUtils.cpp
Line
Count
Source (jump to first uncovered line)
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
8
#include "src/gpu/GrTestUtils.h"
9
10
#include "include/core/SkMatrix.h"
11
#include "include/core/SkPathBuilder.h"
12
#include "include/core/SkRRect.h"
13
#include "src/core/SkRectPriv.h"
14
#include "src/gpu/GrColorInfo.h"
15
#include "src/gpu/GrProcessorUnitTest.h"
16
#include "src/gpu/GrStyle.h"
17
#include "src/utils/SkDashPathPriv.h"
18
19
#if GR_TEST_UTILS
20
21
static const SkMatrix& test_matrix(SkRandom* random,
22
                                   bool includeNonPerspective,
23
0
                                   bool includePerspective) {
24
0
    static SkMatrix gMatrices[5];
25
0
    static const int kPerspectiveCount = 1;
26
0
    static bool gOnce;
27
0
    if (!gOnce) {
28
0
        gOnce = true;
29
0
        gMatrices[0].reset();
30
0
        gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
31
0
        gMatrices[2].setRotate(SkIntToScalar(17));
32
0
        gMatrices[3].setRotate(SkIntToScalar(185));
33
0
        gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
34
0
        gMatrices[3].postScale(SkIntToScalar(2), SK_ScalarHalf);
35
36
        // Perspective matrices
37
0
        gMatrices[4].setRotate(SkIntToScalar(215));
38
0
        gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f);
39
0
        gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f);
40
0
    }
41
42
0
    uint32_t count = static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices));
43
0
    if (includeNonPerspective && includePerspective) {
44
0
        return gMatrices[random->nextULessThan(count)];
45
0
    } else if (!includeNonPerspective) {
46
0
        return gMatrices[count - 1 - random->nextULessThan(kPerspectiveCount)];
47
0
    } else {
48
0
        SkASSERT(includeNonPerspective && !includePerspective);
49
0
        return gMatrices[random->nextULessThan(count - kPerspectiveCount)];
50
0
    }
51
0
}
Unexecuted instantiation: GrTestUtils.cpp:test_matrix(SkRandom*, bool, bool)
Unexecuted instantiation: GrTestUtils.cpp:test_matrix(SkRandom*, bool, bool)
52
53
namespace GrTest {
54
0
const SkMatrix& TestMatrix(SkRandom* random) { return test_matrix(random, true, true); }
55
56
0
const SkMatrix& TestMatrixPreservesRightAngles(SkRandom* random) {
57
0
    static SkMatrix gMatrices[5];
58
0
    static bool gOnce;
59
0
    if (!gOnce) {
60
0
        gOnce = true;
61
        // identity
62
0
        gMatrices[0].reset();
63
        // translation
64
0
        gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
65
        // scale
66
0
        gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
67
        // scale + translation
68
0
        gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
69
0
        gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
70
        // orthogonal basis vectors
71
0
        gMatrices[4].reset();
72
0
        gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
73
0
        gMatrices[4].setRotate(47);
74
75
0
        for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
76
0
            SkASSERT(gMatrices[i].preservesRightAngles());
77
0
        }
78
0
    }
79
0
    return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
80
0
}
Unexecuted instantiation: GrTest::TestMatrixPreservesRightAngles(SkRandom*)
Unexecuted instantiation: GrTest::TestMatrixPreservesRightAngles(SkRandom*)
81
82
0
const SkMatrix& TestMatrixRectStaysRect(SkRandom* random) {
83
0
    static SkMatrix gMatrices[6];
84
0
    static bool gOnce;
85
0
    if (!gOnce) {
86
0
        gOnce = true;
87
        // identity
88
0
        gMatrices[0].reset();
89
        // translation
90
0
        gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
91
        // scale
92
0
        gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
93
        // scale + translation
94
0
        gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
95
0
        gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
96
        // reflection
97
0
        gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
98
        // 90 degress rotation
99
0
        gMatrices[5].setRotate(90);
100
101
0
        for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
102
0
            SkASSERT(gMatrices[i].rectStaysRect());
103
0
        }
104
0
    }
105
0
    return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
106
0
}
Unexecuted instantiation: GrTest::TestMatrixRectStaysRect(SkRandom*)
Unexecuted instantiation: GrTest::TestMatrixRectStaysRect(SkRandom*)
107
108
0
const SkMatrix& TestMatrixInvertible(SkRandom* random) { return test_matrix(random, true, false); }
109
0
const SkMatrix& TestMatrixPerspective(SkRandom* random) { return test_matrix(random, false, true); }
110
111
0
void TestWrapModes(SkRandom* random, GrSamplerState::WrapMode wrapModes[2]) {
112
0
    static const GrSamplerState::WrapMode kWrapModes[] = {
113
0
            GrSamplerState::WrapMode::kClamp,
114
0
            GrSamplerState::WrapMode::kRepeat,
115
0
            GrSamplerState::WrapMode::kMirrorRepeat,
116
0
    };
117
0
    wrapModes[0] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
118
0
    wrapModes[1] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
119
0
}
120
0
const SkRect& TestRect(SkRandom* random) {
121
0
    static SkRect gRects[7];
122
0
    static bool gOnce;
123
0
    if (!gOnce) {
124
0
        gOnce = true;
125
0
        gRects[0] = SkRect::MakeWH(1.f, 1.f);
126
0
        gRects[1] = SkRect::MakeWH(1.0f, 256.0f);
127
0
        gRects[2] = SkRect::MakeWH(256.0f, 1.0f);
128
0
        gRects[3] = SkRectPriv::MakeLargest();
129
0
        gRects[4] = SkRect::MakeLTRB(-65535.0f, -65535.0f, 65535.0f, 65535.0f);
130
0
        gRects[5] = SkRect::MakeLTRB(-10.0f, -10.0f, 10.0f, 10.0f);
131
0
    }
132
0
    return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
133
0
}
134
135
// Just some simple rects for code which expects its input very sanitized
136
0
const SkRect& TestSquare(SkRandom* random) {
137
0
    static SkRect gRects[2];
138
0
    static bool gOnce;
139
0
    if (!gOnce) {
140
0
        gOnce = true;
141
0
        gRects[0] = SkRect::MakeWH(128.f, 128.f);
142
0
        gRects[1] = SkRect::MakeWH(256.0f, 256.0f);
143
0
    }
144
0
    return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
145
0
}
146
147
0
const SkRRect& TestRRectSimple(SkRandom* random) {
148
0
    static SkRRect gRRect[2];
149
0
    static bool gOnce;
150
0
    if (!gOnce) {
151
0
        gOnce = true;
152
0
        SkRect rectangle = SkRect::MakeWH(10.f, 20.f);
153
        // true round rect with circular corners
154
0
        gRRect[0].setRectXY(rectangle, 1.f, 1.f);
155
        // true round rect with elliptical corners
156
0
        gRRect[1].setRectXY(rectangle, 2.0f, 1.0f);
157
158
0
        for (size_t i = 0; i < SK_ARRAY_COUNT(gRRect); i++) {
159
0
            SkASSERT(gRRect[i].isSimple());
160
0
        }
161
0
    }
162
0
    return gRRect[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRRect)))];
163
0
}
Unexecuted instantiation: GrTest::TestRRectSimple(SkRandom*)
Unexecuted instantiation: GrTest::TestRRectSimple(SkRandom*)
164
165
0
const SkPath& TestPath(SkRandom* random) {
166
0
    static SkPath gPath[7];
167
0
    static bool gOnce;
168
0
    if (!gOnce) {
169
0
        gOnce = true;
170
        // line
171
0
        gPath[0] = SkPathBuilder().moveTo(0.f, 0.f)
172
0
                                  .lineTo(10.f, 10.f)
173
0
                                  .detach();
174
        // quad
175
0
        gPath[1] = SkPathBuilder().moveTo(0.f, 0.f)
176
0
                                  .quadTo(10.f, 10.f, 20.f, 20.f)
177
0
                                  .detach();
178
        // conic
179
0
        gPath[2] = SkPathBuilder().moveTo(0.f, 0.f)
180
0
                                  .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
181
0
                                  .detach();
182
        // cubic
183
0
        gPath[3] = SkPathBuilder().moveTo(0.f, 0.f)
184
0
                                  .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
185
0
                                  .detach();
186
        // all three
187
0
        gPath[4] = SkPathBuilder().moveTo(0.f, 0.f)
188
0
                                  .lineTo(10.f, 10.f)
189
0
                                  .quadTo(10.f, 10.f, 20.f, 20.f)
190
0
                                  .conicTo(10.f, 10.f, 20.f, 20.f, 1.f)
191
0
                                  .cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f)
192
0
                                  .detach();
193
        // convex
194
0
        gPath[5] = SkPathBuilder().moveTo(0.0f, 0.0f)
195
0
                                  .lineTo(10.0f, 0.0f)
196
0
                                  .lineTo(10.0f, 10.0f)
197
0
                                  .lineTo(0.0f, 10.0f)
198
0
                                  .close()
199
0
                                  .detach();
200
        // concave
201
0
        gPath[6] = SkPathBuilder().moveTo(0.0f, 0.0f)
202
0
                                  .lineTo(5.0f, 5.0f)
203
0
                                  .lineTo(10.0f, 0.0f)
204
0
                                  .lineTo(10.0f, 10.0f)
205
0
                                  .lineTo(0.0f, 10.0f)
206
0
                                  .close()
207
0
                                  .detach();
208
0
    }
209
210
0
    return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
211
0
}
212
213
0
const SkPath& TestPathConvex(SkRandom* random) {
214
0
    static SkPath gPath[3];
215
0
    static bool gOnce;
216
0
    if (!gOnce) {
217
0
        gOnce = true;
218
        // narrow rect
219
0
        gPath[0] = SkPath::Polygon({{-1.5f, -50.0f},
220
0
                                    {-1.5f, -50.0f},
221
0
                                    { 1.5f, -50.0f},
222
0
                                    { 1.5f,  50.0f},
223
0
                                    {-1.5f,  50.0f}}, false);
224
        // degenerate
225
0
        gPath[1] = SkPath::Polygon({{-0.025f, -0.025f},
226
0
                                    {-0.025f, -0.025f},
227
0
                                    { 0.025f, -0.025f},
228
0
                                    { 0.025f,  0.025f},
229
0
                                    {-0.025f,  0.025f}}, false);
230
        // clipped triangle
231
0
        gPath[2] = SkPath::Polygon({{-10.0f, -50.0f},
232
0
                                    {-10.0f, -50.0f},
233
0
                                    { 10.0f, -50.0f},
234
0
                                    { 50.0f,  31.0f},
235
0
                                    { 40.0f,  50.0f},
236
0
                                    {-40.0f,  50.0f},
237
0
                                    {-50.0f,  31.0f}}, false);
238
239
0
        for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
240
0
            SkASSERT(gPath[i].isConvex());
241
0
        }
242
0
    }
243
244
0
    return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
245
0
}
Unexecuted instantiation: GrTest::TestPathConvex(SkRandom*)
Unexecuted instantiation: GrTest::TestPathConvex(SkRandom*)
246
247
0
static void randomize_stroke_rec(SkStrokeRec* rec, SkRandom* random) {
248
0
    bool strokeAndFill = random->nextBool();
249
0
    SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
250
0
    rec->setStrokeStyle(strokeWidth, strokeAndFill);
251
252
0
    SkPaint::Cap cap = SkPaint::Cap(random->nextULessThan(SkPaint::kCapCount));
253
0
    SkPaint::Join join = SkPaint::Join(random->nextULessThan(SkPaint::kJoinCount));
254
0
    SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
255
0
    rec->setStrokeParams(cap, join, miterLimit);
256
0
}
257
258
0
SkStrokeRec TestStrokeRec(SkRandom* random) {
259
0
    SkStrokeRec::InitStyle style =
260
0
            SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
261
0
    SkStrokeRec rec(style);
262
0
    randomize_stroke_rec(&rec, random);
263
0
    return rec;
264
0
}
265
266
0
void TestStyle(SkRandom* random, GrStyle* style) {
267
0
    SkStrokeRec::InitStyle initStyle =
268
0
            SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
269
0
    SkStrokeRec stroke(initStyle);
270
0
    randomize_stroke_rec(&stroke, random);
271
0
    sk_sp<SkPathEffect> pe;
272
0
    if (random->nextBool()) {
273
0
        int cnt = random->nextRangeU(1, 50) * 2;
274
0
        std::unique_ptr<SkScalar[]> intervals(new SkScalar[cnt]);
275
0
        SkScalar sum = 0;
276
0
        for (int i = 0; i < cnt; i++) {
277
0
            intervals[i] = random->nextRangeScalar(SkDoubleToScalar(0.01),
278
0
                                                   SkDoubleToScalar(10.0));
279
0
            sum += intervals[i];
280
0
        }
281
0
        SkScalar phase = random->nextRangeScalar(0, sum);
282
0
        pe = TestDashPathEffect::Make(intervals.get(), cnt, phase);
283
0
    }
284
0
    *style = GrStyle(stroke, std::move(pe));
285
0
}
286
287
0
TestDashPathEffect::TestDashPathEffect(const SkScalar* intervals, int count, SkScalar phase) {
288
0
    fCount = count;
289
0
    fIntervals.reset(count);
290
0
    memcpy(fIntervals.get(), intervals, count * sizeof(SkScalar));
291
0
    SkDashPath::CalcDashParameters(phase, intervals, count, &fInitialDashLength,
292
0
                                   &fInitialDashIndex, &fIntervalLength, &fPhase);
293
0
}
294
295
bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
296
0
                                      const SkRect* cullRect, const SkMatrix&) const {
297
0
    return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
298
0
                                      fInitialDashLength, fInitialDashIndex, fIntervalLength);
299
0
}
300
301
0
SkPathEffect::DashType TestDashPathEffect::onAsADash(DashInfo* info) const {
302
0
    if (info) {
303
0
        if (info->fCount >= fCount && info->fIntervals) {
304
0
            memcpy(info->fIntervals, fIntervals.get(), fCount * sizeof(SkScalar));
305
0
        }
306
0
        info->fCount = fCount;
307
0
        info->fPhase = fPhase;
308
0
    }
309
0
    return kDash_DashType;
310
0
}
311
312
0
sk_sp<SkColorSpace> TestColorSpace(SkRandom* random) {
313
0
    static sk_sp<SkColorSpace> gColorSpaces[3];
314
0
    static bool gOnce;
315
0
    if (!gOnce) {
316
0
        gOnce = true;
317
        // No color space (legacy mode)
318
0
        gColorSpaces[0] = nullptr;
319
        // sRGB or color-spin sRGB
320
0
        gColorSpaces[1] = SkColorSpace::MakeSRGB();
321
0
        gColorSpaces[2] = SkColorSpace::MakeSRGB()->makeColorSpin();
322
0
    }
323
0
    return gColorSpaces[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gColorSpaces)))];
324
0
}
325
326
0
sk_sp<GrColorSpaceXform> TestColorXform(SkRandom* random) {
327
    // TODO: Add many more kinds of xforms here
328
0
    static sk_sp<GrColorSpaceXform> gXforms[3];
329
0
    static bool gOnce;
330
0
    if (!gOnce) {
331
0
        gOnce = true;
332
0
        sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
333
0
        sk_sp<SkColorSpace> spin = SkColorSpace::MakeSRGB()->makeColorSpin();
334
        // No gamut change
335
0
        gXforms[0] = nullptr;
336
0
        gXforms[1] = GrColorSpaceXform::Make(srgb.get(), kPremul_SkAlphaType,
337
0
                                             spin.get(), kPremul_SkAlphaType);
338
0
        gXforms[2] = GrColorSpaceXform::Make(spin.get(), kPremul_SkAlphaType,
339
0
                                             srgb.get(), kPremul_SkAlphaType);
340
0
    }
341
0
    return gXforms[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gXforms)))];
342
0
}
343
344
TestAsFPArgs::TestAsFPArgs(GrProcessorTestData* d)
345
        : fMatrixProvider(TestMatrix(d->fRandom))
346
        , fColorInfoStorage(std::make_unique<GrColorInfo>(
347
                  GrColorType::kRGBA_8888, kPremul_SkAlphaType, TestColorSpace(d->fRandom)))
348
        , fArgs(d->context(),
349
                fMatrixProvider,
350
0
                fColorInfoStorage.get()) {}
351
352
0
TestAsFPArgs::~TestAsFPArgs() {}
353
354
0
GrColor RandomColor(SkRandom* random) {
355
    // There are only a few cases of random colors which interest us
356
0
    enum ColorMode {
357
0
        kAllOnes_ColorMode,
358
0
        kAllZeros_ColorMode,
359
0
        kAlphaOne_ColorMode,
360
0
        kRandom_ColorMode,
361
0
        kLast_ColorMode = kRandom_ColorMode
362
0
    };
363
364
0
    ColorMode colorMode = ColorMode(random->nextULessThan(kLast_ColorMode + 1));
365
0
    GrColor color SK_INIT_TO_AVOID_WARNING;
366
0
    switch (colorMode) {
367
0
        case kAllOnes_ColorMode:
368
0
            color = GrColorPackRGBA(0xFF, 0xFF, 0xFF, 0xFF);
369
0
            break;
370
0
        case kAllZeros_ColorMode:
371
0
            color = GrColorPackRGBA(0, 0, 0, 0);
372
0
            break;
373
0
        case kAlphaOne_ColorMode:
374
0
            color = GrColorPackRGBA(random->nextULessThan(256),
375
0
                                    random->nextULessThan(256),
376
0
                                    random->nextULessThan(256),
377
0
                                    0xFF);
378
0
            break;
379
0
        case kRandom_ColorMode: {
380
0
                uint8_t alpha = random->nextULessThan(256);
381
0
                color = GrColorPackRGBA(random->nextRangeU(0, alpha),
382
0
                                        random->nextRangeU(0, alpha),
383
0
                                        random->nextRangeU(0, alpha),
384
0
                                        alpha);
385
0
            break;
386
0
        }
387
0
    }
388
0
    return color;
389
0
}
390
391
0
uint8_t RandomCoverage(SkRandom* random) {
392
0
    enum CoverageMode {
393
0
        kZero_CoverageMode,
394
0
        kAllOnes_CoverageMode,
395
0
        kRandom_CoverageMode,
396
0
        kLast_CoverageMode = kRandom_CoverageMode
397
0
    };
398
399
0
    CoverageMode colorMode = CoverageMode(random->nextULessThan(kLast_CoverageMode + 1));
400
0
    uint8_t coverage SK_INIT_TO_AVOID_WARNING;
401
0
    switch (colorMode) {
402
0
        case kZero_CoverageMode:
403
0
            coverage = 0;
404
0
            break;
405
0
        case kAllOnes_CoverageMode:
406
0
            coverage = 0xff;
407
0
            break;
408
0
        case kRandom_CoverageMode:
409
0
            coverage = random->nextULessThan(256);
410
0
            break;
411
0
    }
412
0
    return coverage;
413
0
}
414
415
}  // namespace GrTest
416
417
#endif