123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- /*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "src/gpu/GrTestUtils.h"
- #include "include/core/SkMatrix.h"
- #include "include/core/SkPath.h"
- #include "include/core/SkRRect.h"
- #include "include/gpu/GrContext.h"
- #include "src/core/SkMakeUnique.h"
- #include "src/core/SkRectPriv.h"
- #include "src/gpu/GrColorSpaceInfo.h"
- #include "src/gpu/GrProcessorUnitTest.h"
- #include "src/gpu/GrStyle.h"
- #include "src/utils/SkDashPathPriv.h"
- #if GR_TEST_UTILS
- static const SkMatrix& test_matrix(SkRandom* random,
- bool includeNonPerspective,
- bool includePerspective) {
- static SkMatrix gMatrices[5];
- static const int kPerspectiveCount = 1;
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- gMatrices[0].reset();
- gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
- gMatrices[2].setRotate(SkIntToScalar(17));
- gMatrices[3].setRotate(SkIntToScalar(185));
- gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
- gMatrices[3].postScale(SkIntToScalar(2), SK_ScalarHalf);
- // Perspective matrices
- gMatrices[4].setRotate(SkIntToScalar(215));
- gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f);
- gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f);
- }
- uint32_t count = static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices));
- if (includeNonPerspective && includePerspective) {
- return gMatrices[random->nextULessThan(count)];
- } else if (!includeNonPerspective) {
- return gMatrices[count - 1 - random->nextULessThan(kPerspectiveCount)];
- } else {
- SkASSERT(includeNonPerspective && !includePerspective);
- return gMatrices[random->nextULessThan(count - kPerspectiveCount)];
- }
- }
- namespace GrTest {
- const SkMatrix& TestMatrix(SkRandom* random) { return test_matrix(random, true, true); }
- const SkMatrix& TestMatrixPreservesRightAngles(SkRandom* random) {
- static SkMatrix gMatrices[5];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- // identity
- gMatrices[0].reset();
- // translation
- gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
- // scale
- gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
- // scale + translation
- gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
- gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
- // orthogonal basis vectors
- gMatrices[4].reset();
- gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
- gMatrices[4].setRotate(47);
- for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
- SkASSERT(gMatrices[i].preservesRightAngles());
- }
- }
- return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
- }
- const SkMatrix& TestMatrixRectStaysRect(SkRandom* random) {
- static SkMatrix gMatrices[6];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- // identity
- gMatrices[0].reset();
- // translation
- gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
- // scale
- gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
- // scale + translation
- gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
- gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
- // reflection
- gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
- // 90 degress rotation
- gMatrices[5].setRotate(90);
- for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
- SkASSERT(gMatrices[i].rectStaysRect());
- }
- }
- return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
- }
- const SkMatrix& TestMatrixInvertible(SkRandom* random) { return test_matrix(random, true, false); }
- const SkMatrix& TestMatrixPerspective(SkRandom* random) { return test_matrix(random, false, true); }
- void TestWrapModes(SkRandom* random, GrSamplerState::WrapMode wrapModes[2]) {
- static const GrSamplerState::WrapMode kWrapModes[] = {
- GrSamplerState::WrapMode::kClamp,
- GrSamplerState::WrapMode::kRepeat,
- GrSamplerState::WrapMode::kMirrorRepeat,
- };
- wrapModes[0] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
- wrapModes[1] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
- }
- const SkRect& TestRect(SkRandom* random) {
- static SkRect gRects[7];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- gRects[0] = SkRect::MakeWH(1.f, 1.f);
- gRects[1] = SkRect::MakeWH(1.0f, 256.0f);
- gRects[2] = SkRect::MakeWH(256.0f, 1.0f);
- gRects[3] = SkRectPriv::MakeLargest();
- gRects[4] = SkRect::MakeLTRB(-65535.0f, -65535.0f, 65535.0f, 65535.0f);
- gRects[5] = SkRect::MakeLTRB(-10.0f, -10.0f, 10.0f, 10.0f);
- }
- return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
- }
- // Just some simple rects for code which expects its input very sanitized
- const SkRect& TestSquare(SkRandom* random) {
- static SkRect gRects[2];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- gRects[0] = SkRect::MakeWH(128.f, 128.f);
- gRects[1] = SkRect::MakeWH(256.0f, 256.0f);
- }
- return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
- }
- const SkRRect& TestRRectSimple(SkRandom* random) {
- static SkRRect gRRect[2];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- SkRect rectangle = SkRect::MakeWH(10.f, 20.f);
- // true round rect with circular corners
- gRRect[0].setRectXY(rectangle, 1.f, 1.f);
- // true round rect with elliptical corners
- gRRect[1].setRectXY(rectangle, 2.0f, 1.0f);
- for (size_t i = 0; i < SK_ARRAY_COUNT(gRRect); i++) {
- SkASSERT(gRRect[i].isSimple());
- }
- }
- return gRRect[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRRect)))];
- }
- const SkPath& TestPath(SkRandom* random) {
- static SkPath gPath[7];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- // line
- gPath[0].moveTo(0.f, 0.f);
- gPath[0].lineTo(10.f, 10.f);
- // quad
- gPath[1].moveTo(0.f, 0.f);
- gPath[1].quadTo(10.f, 10.f, 20.f, 20.f);
- // conic
- gPath[2].moveTo(0.f, 0.f);
- gPath[2].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
- // cubic
- gPath[3].moveTo(0.f, 0.f);
- gPath[3].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
- // all three
- gPath[4].moveTo(0.f, 0.f);
- gPath[4].lineTo(10.f, 10.f);
- gPath[4].quadTo(10.f, 10.f, 20.f, 20.f);
- gPath[4].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
- gPath[4].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
- // convex
- gPath[5].moveTo(0.0f, 0.0f);
- gPath[5].lineTo(10.0f, 0.0f);
- gPath[5].lineTo(10.0f, 10.0f);
- gPath[5].lineTo(0.0f, 10.0f);
- gPath[5].close();
- // concave
- gPath[6].moveTo(0.0f, 0.0f);
- gPath[6].lineTo(5.0f, 5.0f);
- gPath[6].lineTo(10.0f, 0.0f);
- gPath[6].lineTo(10.0f, 10.0f);
- gPath[6].lineTo(0.0f, 10.0f);
- gPath[6].close();
- }
- return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
- }
- const SkPath& TestPathConvex(SkRandom* random) {
- static SkPath gPath[3];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- // narrow rect
- gPath[0].moveTo(-1.5f, -50.0f);
- gPath[0].lineTo(-1.5f, -50.0f);
- gPath[0].lineTo( 1.5f, -50.0f);
- gPath[0].lineTo( 1.5f, 50.0f);
- gPath[0].lineTo(-1.5f, 50.0f);
- // degenerate
- gPath[1].moveTo(-0.025f, -0.025f);
- gPath[1].lineTo(-0.025f, -0.025f);
- gPath[1].lineTo( 0.025f, -0.025f);
- gPath[1].lineTo( 0.025f, 0.025f);
- gPath[1].lineTo(-0.025f, 0.025f);
- // clipped triangle
- gPath[2].moveTo(-10.0f, -50.0f);
- gPath[2].lineTo(-10.0f, -50.0f);
- gPath[2].lineTo( 10.0f, -50.0f);
- gPath[2].lineTo( 50.0f, 31.0f);
- gPath[2].lineTo( 40.0f, 50.0f);
- gPath[2].lineTo(-40.0f, 50.0f);
- gPath[2].lineTo(-50.0f, 31.0f);
- for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
- SkASSERT(SkPath::kConvex_Convexity == gPath[i].getConvexity());
- }
- }
- return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
- }
- static void randomize_stroke_rec(SkStrokeRec* rec, SkRandom* random) {
- bool strokeAndFill = random->nextBool();
- SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
- rec->setStrokeStyle(strokeWidth, strokeAndFill);
- SkPaint::Cap cap = SkPaint::Cap(random->nextULessThan(SkPaint::kCapCount));
- SkPaint::Join join = SkPaint::Join(random->nextULessThan(SkPaint::kJoinCount));
- SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
- rec->setStrokeParams(cap, join, miterLimit);
- }
- SkStrokeRec TestStrokeRec(SkRandom* random) {
- SkStrokeRec::InitStyle style =
- SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
- SkStrokeRec rec(style);
- randomize_stroke_rec(&rec, random);
- return rec;
- }
- void TestStyle(SkRandom* random, GrStyle* style) {
- SkStrokeRec::InitStyle initStyle =
- SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
- SkStrokeRec stroke(initStyle);
- randomize_stroke_rec(&stroke, random);
- sk_sp<SkPathEffect> pe;
- if (random->nextBool()) {
- int cnt = random->nextRangeU(1, 50) * 2;
- std::unique_ptr<SkScalar[]> intervals(new SkScalar[cnt]);
- SkScalar sum = 0;
- for (int i = 0; i < cnt; i++) {
- intervals[i] = random->nextRangeScalar(SkDoubleToScalar(0.01),
- SkDoubleToScalar(10.0));
- sum += intervals[i];
- }
- SkScalar phase = random->nextRangeScalar(0, sum);
- pe = TestDashPathEffect::Make(intervals.get(), cnt, phase);
- }
- *style = GrStyle(stroke, std::move(pe));
- }
- TestDashPathEffect::TestDashPathEffect(const SkScalar* intervals, int count, SkScalar phase) {
- fCount = count;
- fIntervals.reset(count);
- memcpy(fIntervals.get(), intervals, count * sizeof(SkScalar));
- SkDashPath::CalcDashParameters(phase, intervals, count, &fInitialDashLength,
- &fInitialDashIndex, &fIntervalLength, &fPhase);
- }
- bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
- const SkRect* cullRect) const {
- return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
- fInitialDashLength, fInitialDashIndex, fIntervalLength);
- }
- SkPathEffect::DashType TestDashPathEffect::onAsADash(DashInfo* info) const {
- if (info) {
- if (info->fCount >= fCount && info->fIntervals) {
- memcpy(info->fIntervals, fIntervals.get(), fCount * sizeof(SkScalar));
- }
- info->fCount = fCount;
- info->fPhase = fPhase;
- }
- return kDash_DashType;
- }
- sk_sp<SkColorSpace> TestColorSpace(SkRandom* random) {
- static sk_sp<SkColorSpace> gColorSpaces[3];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- // No color space (legacy mode)
- gColorSpaces[0] = nullptr;
- // sRGB or color-spin sRGB
- gColorSpaces[1] = SkColorSpace::MakeSRGB();
- gColorSpaces[2] = SkColorSpace::MakeSRGB()->makeColorSpin();
- }
- return gColorSpaces[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gColorSpaces)))];
- }
- sk_sp<GrColorSpaceXform> TestColorXform(SkRandom* random) {
- // TODO: Add many more kinds of xforms here
- static sk_sp<GrColorSpaceXform> gXforms[3];
- static bool gOnce;
- if (!gOnce) {
- gOnce = true;
- sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
- sk_sp<SkColorSpace> spin = SkColorSpace::MakeSRGB()->makeColorSpin();
- // No gamut change
- gXforms[0] = nullptr;
- gXforms[1] = GrColorSpaceXform::Make(srgb.get(), kPremul_SkAlphaType,
- spin.get(), kPremul_SkAlphaType);
- gXforms[2] = GrColorSpaceXform::Make(spin.get(), kPremul_SkAlphaType,
- srgb.get(), kPremul_SkAlphaType);
- }
- return gXforms[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gXforms)))];
- }
- TestAsFPArgs::TestAsFPArgs(GrProcessorTestData* d)
- : fViewMatrixStorage(TestMatrix(d->fRandom))
- , fColorSpaceInfoStorage(skstd::make_unique<GrColorSpaceInfo>(
- GrColorType::kRGBA_8888, kPremul_SkAlphaType, TestColorSpace(d->fRandom)))
- , fArgs(d->context(), &fViewMatrixStorage, kNone_SkFilterQuality,
- fColorSpaceInfoStorage.get()) {}
- TestAsFPArgs::~TestAsFPArgs() {}
- } // namespace GrTest
- #endif
|