GrTestUtils.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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. #include "src/gpu/GrTestUtils.h"
  8. #include "include/core/SkMatrix.h"
  9. #include "include/core/SkPath.h"
  10. #include "include/core/SkRRect.h"
  11. #include "include/gpu/GrContext.h"
  12. #include "src/core/SkMakeUnique.h"
  13. #include "src/core/SkRectPriv.h"
  14. #include "src/gpu/GrColorSpaceInfo.h"
  15. #include "src/gpu/GrProcessorUnitTest.h"
  16. #include "src/gpu/GrStyle.h"
  17. #include "src/utils/SkDashPathPriv.h"
  18. #if GR_TEST_UTILS
  19. static const SkMatrix& test_matrix(SkRandom* random,
  20. bool includeNonPerspective,
  21. bool includePerspective) {
  22. static SkMatrix gMatrices[5];
  23. static const int kPerspectiveCount = 1;
  24. static bool gOnce;
  25. if (!gOnce) {
  26. gOnce = true;
  27. gMatrices[0].reset();
  28. gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
  29. gMatrices[2].setRotate(SkIntToScalar(17));
  30. gMatrices[3].setRotate(SkIntToScalar(185));
  31. gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
  32. gMatrices[3].postScale(SkIntToScalar(2), SK_ScalarHalf);
  33. // Perspective matrices
  34. gMatrices[4].setRotate(SkIntToScalar(215));
  35. gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f);
  36. gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f);
  37. }
  38. uint32_t count = static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices));
  39. if (includeNonPerspective && includePerspective) {
  40. return gMatrices[random->nextULessThan(count)];
  41. } else if (!includeNonPerspective) {
  42. return gMatrices[count - 1 - random->nextULessThan(kPerspectiveCount)];
  43. } else {
  44. SkASSERT(includeNonPerspective && !includePerspective);
  45. return gMatrices[random->nextULessThan(count - kPerspectiveCount)];
  46. }
  47. }
  48. namespace GrTest {
  49. const SkMatrix& TestMatrix(SkRandom* random) { return test_matrix(random, true, true); }
  50. const SkMatrix& TestMatrixPreservesRightAngles(SkRandom* random) {
  51. static SkMatrix gMatrices[5];
  52. static bool gOnce;
  53. if (!gOnce) {
  54. gOnce = true;
  55. // identity
  56. gMatrices[0].reset();
  57. // translation
  58. gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
  59. // scale
  60. gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
  61. // scale + translation
  62. gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
  63. gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
  64. // orthogonal basis vectors
  65. gMatrices[4].reset();
  66. gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
  67. gMatrices[4].setRotate(47);
  68. for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
  69. SkASSERT(gMatrices[i].preservesRightAngles());
  70. }
  71. }
  72. return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
  73. }
  74. const SkMatrix& TestMatrixRectStaysRect(SkRandom* random) {
  75. static SkMatrix gMatrices[6];
  76. static bool gOnce;
  77. if (!gOnce) {
  78. gOnce = true;
  79. // identity
  80. gMatrices[0].reset();
  81. // translation
  82. gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100));
  83. // scale
  84. gMatrices[2].setScale(SkIntToScalar(17), SkIntToScalar(17));
  85. // scale + translation
  86. gMatrices[3].setScale(SkIntToScalar(-17), SkIntToScalar(-17));
  87. gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33));
  88. // reflection
  89. gMatrices[4].setScale(SkIntToScalar(-1), SkIntToScalar(-1));
  90. // 90 degress rotation
  91. gMatrices[5].setRotate(90);
  92. for (size_t i = 0; i < SK_ARRAY_COUNT(gMatrices); i++) {
  93. SkASSERT(gMatrices[i].rectStaysRect());
  94. }
  95. }
  96. return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))];
  97. }
  98. const SkMatrix& TestMatrixInvertible(SkRandom* random) { return test_matrix(random, true, false); }
  99. const SkMatrix& TestMatrixPerspective(SkRandom* random) { return test_matrix(random, false, true); }
  100. void TestWrapModes(SkRandom* random, GrSamplerState::WrapMode wrapModes[2]) {
  101. static const GrSamplerState::WrapMode kWrapModes[] = {
  102. GrSamplerState::WrapMode::kClamp,
  103. GrSamplerState::WrapMode::kRepeat,
  104. GrSamplerState::WrapMode::kMirrorRepeat,
  105. };
  106. wrapModes[0] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
  107. wrapModes[1] = kWrapModes[random->nextULessThan(SK_ARRAY_COUNT(kWrapModes))];
  108. }
  109. const SkRect& TestRect(SkRandom* random) {
  110. static SkRect gRects[7];
  111. static bool gOnce;
  112. if (!gOnce) {
  113. gOnce = true;
  114. gRects[0] = SkRect::MakeWH(1.f, 1.f);
  115. gRects[1] = SkRect::MakeWH(1.0f, 256.0f);
  116. gRects[2] = SkRect::MakeWH(256.0f, 1.0f);
  117. gRects[3] = SkRectPriv::MakeLargest();
  118. gRects[4] = SkRect::MakeLTRB(-65535.0f, -65535.0f, 65535.0f, 65535.0f);
  119. gRects[5] = SkRect::MakeLTRB(-10.0f, -10.0f, 10.0f, 10.0f);
  120. }
  121. return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
  122. }
  123. // Just some simple rects for code which expects its input very sanitized
  124. const SkRect& TestSquare(SkRandom* random) {
  125. static SkRect gRects[2];
  126. static bool gOnce;
  127. if (!gOnce) {
  128. gOnce = true;
  129. gRects[0] = SkRect::MakeWH(128.f, 128.f);
  130. gRects[1] = SkRect::MakeWH(256.0f, 256.0f);
  131. }
  132. return gRects[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRects)))];
  133. }
  134. const SkRRect& TestRRectSimple(SkRandom* random) {
  135. static SkRRect gRRect[2];
  136. static bool gOnce;
  137. if (!gOnce) {
  138. gOnce = true;
  139. SkRect rectangle = SkRect::MakeWH(10.f, 20.f);
  140. // true round rect with circular corners
  141. gRRect[0].setRectXY(rectangle, 1.f, 1.f);
  142. // true round rect with elliptical corners
  143. gRRect[1].setRectXY(rectangle, 2.0f, 1.0f);
  144. for (size_t i = 0; i < SK_ARRAY_COUNT(gRRect); i++) {
  145. SkASSERT(gRRect[i].isSimple());
  146. }
  147. }
  148. return gRRect[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gRRect)))];
  149. }
  150. const SkPath& TestPath(SkRandom* random) {
  151. static SkPath gPath[7];
  152. static bool gOnce;
  153. if (!gOnce) {
  154. gOnce = true;
  155. // line
  156. gPath[0].moveTo(0.f, 0.f);
  157. gPath[0].lineTo(10.f, 10.f);
  158. // quad
  159. gPath[1].moveTo(0.f, 0.f);
  160. gPath[1].quadTo(10.f, 10.f, 20.f, 20.f);
  161. // conic
  162. gPath[2].moveTo(0.f, 0.f);
  163. gPath[2].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
  164. // cubic
  165. gPath[3].moveTo(0.f, 0.f);
  166. gPath[3].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
  167. // all three
  168. gPath[4].moveTo(0.f, 0.f);
  169. gPath[4].lineTo(10.f, 10.f);
  170. gPath[4].quadTo(10.f, 10.f, 20.f, 20.f);
  171. gPath[4].conicTo(10.f, 10.f, 20.f, 20.f, 1.f);
  172. gPath[4].cubicTo(10.f, 10.f, 20.f, 20.f, 30.f, 30.f);
  173. // convex
  174. gPath[5].moveTo(0.0f, 0.0f);
  175. gPath[5].lineTo(10.0f, 0.0f);
  176. gPath[5].lineTo(10.0f, 10.0f);
  177. gPath[5].lineTo(0.0f, 10.0f);
  178. gPath[5].close();
  179. // concave
  180. gPath[6].moveTo(0.0f, 0.0f);
  181. gPath[6].lineTo(5.0f, 5.0f);
  182. gPath[6].lineTo(10.0f, 0.0f);
  183. gPath[6].lineTo(10.0f, 10.0f);
  184. gPath[6].lineTo(0.0f, 10.0f);
  185. gPath[6].close();
  186. }
  187. return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
  188. }
  189. const SkPath& TestPathConvex(SkRandom* random) {
  190. static SkPath gPath[3];
  191. static bool gOnce;
  192. if (!gOnce) {
  193. gOnce = true;
  194. // narrow rect
  195. gPath[0].moveTo(-1.5f, -50.0f);
  196. gPath[0].lineTo(-1.5f, -50.0f);
  197. gPath[0].lineTo( 1.5f, -50.0f);
  198. gPath[0].lineTo( 1.5f, 50.0f);
  199. gPath[0].lineTo(-1.5f, 50.0f);
  200. // degenerate
  201. gPath[1].moveTo(-0.025f, -0.025f);
  202. gPath[1].lineTo(-0.025f, -0.025f);
  203. gPath[1].lineTo( 0.025f, -0.025f);
  204. gPath[1].lineTo( 0.025f, 0.025f);
  205. gPath[1].lineTo(-0.025f, 0.025f);
  206. // clipped triangle
  207. gPath[2].moveTo(-10.0f, -50.0f);
  208. gPath[2].lineTo(-10.0f, -50.0f);
  209. gPath[2].lineTo( 10.0f, -50.0f);
  210. gPath[2].lineTo( 50.0f, 31.0f);
  211. gPath[2].lineTo( 40.0f, 50.0f);
  212. gPath[2].lineTo(-40.0f, 50.0f);
  213. gPath[2].lineTo(-50.0f, 31.0f);
  214. for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
  215. SkASSERT(SkPath::kConvex_Convexity == gPath[i].getConvexity());
  216. }
  217. }
  218. return gPath[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gPath)))];
  219. }
  220. static void randomize_stroke_rec(SkStrokeRec* rec, SkRandom* random) {
  221. bool strokeAndFill = random->nextBool();
  222. SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
  223. rec->setStrokeStyle(strokeWidth, strokeAndFill);
  224. SkPaint::Cap cap = SkPaint::Cap(random->nextULessThan(SkPaint::kCapCount));
  225. SkPaint::Join join = SkPaint::Join(random->nextULessThan(SkPaint::kJoinCount));
  226. SkScalar miterLimit = random->nextRangeScalar(1.f, 5.f);
  227. rec->setStrokeParams(cap, join, miterLimit);
  228. }
  229. SkStrokeRec TestStrokeRec(SkRandom* random) {
  230. SkStrokeRec::InitStyle style =
  231. SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
  232. SkStrokeRec rec(style);
  233. randomize_stroke_rec(&rec, random);
  234. return rec;
  235. }
  236. void TestStyle(SkRandom* random, GrStyle* style) {
  237. SkStrokeRec::InitStyle initStyle =
  238. SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1));
  239. SkStrokeRec stroke(initStyle);
  240. randomize_stroke_rec(&stroke, random);
  241. sk_sp<SkPathEffect> pe;
  242. if (random->nextBool()) {
  243. int cnt = random->nextRangeU(1, 50) * 2;
  244. std::unique_ptr<SkScalar[]> intervals(new SkScalar[cnt]);
  245. SkScalar sum = 0;
  246. for (int i = 0; i < cnt; i++) {
  247. intervals[i] = random->nextRangeScalar(SkDoubleToScalar(0.01),
  248. SkDoubleToScalar(10.0));
  249. sum += intervals[i];
  250. }
  251. SkScalar phase = random->nextRangeScalar(0, sum);
  252. pe = TestDashPathEffect::Make(intervals.get(), cnt, phase);
  253. }
  254. *style = GrStyle(stroke, std::move(pe));
  255. }
  256. TestDashPathEffect::TestDashPathEffect(const SkScalar* intervals, int count, SkScalar phase) {
  257. fCount = count;
  258. fIntervals.reset(count);
  259. memcpy(fIntervals.get(), intervals, count * sizeof(SkScalar));
  260. SkDashPath::CalcDashParameters(phase, intervals, count, &fInitialDashLength,
  261. &fInitialDashIndex, &fIntervalLength, &fPhase);
  262. }
  263. bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
  264. const SkRect* cullRect) const {
  265. return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
  266. fInitialDashLength, fInitialDashIndex, fIntervalLength);
  267. }
  268. SkPathEffect::DashType TestDashPathEffect::onAsADash(DashInfo* info) const {
  269. if (info) {
  270. if (info->fCount >= fCount && info->fIntervals) {
  271. memcpy(info->fIntervals, fIntervals.get(), fCount * sizeof(SkScalar));
  272. }
  273. info->fCount = fCount;
  274. info->fPhase = fPhase;
  275. }
  276. return kDash_DashType;
  277. }
  278. sk_sp<SkColorSpace> TestColorSpace(SkRandom* random) {
  279. static sk_sp<SkColorSpace> gColorSpaces[3];
  280. static bool gOnce;
  281. if (!gOnce) {
  282. gOnce = true;
  283. // No color space (legacy mode)
  284. gColorSpaces[0] = nullptr;
  285. // sRGB or color-spin sRGB
  286. gColorSpaces[1] = SkColorSpace::MakeSRGB();
  287. gColorSpaces[2] = SkColorSpace::MakeSRGB()->makeColorSpin();
  288. }
  289. return gColorSpaces[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gColorSpaces)))];
  290. }
  291. sk_sp<GrColorSpaceXform> TestColorXform(SkRandom* random) {
  292. // TODO: Add many more kinds of xforms here
  293. static sk_sp<GrColorSpaceXform> gXforms[3];
  294. static bool gOnce;
  295. if (!gOnce) {
  296. gOnce = true;
  297. sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
  298. sk_sp<SkColorSpace> spin = SkColorSpace::MakeSRGB()->makeColorSpin();
  299. // No gamut change
  300. gXforms[0] = nullptr;
  301. gXforms[1] = GrColorSpaceXform::Make(srgb.get(), kPremul_SkAlphaType,
  302. spin.get(), kPremul_SkAlphaType);
  303. gXforms[2] = GrColorSpaceXform::Make(spin.get(), kPremul_SkAlphaType,
  304. srgb.get(), kPremul_SkAlphaType);
  305. }
  306. return gXforms[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gXforms)))];
  307. }
  308. TestAsFPArgs::TestAsFPArgs(GrProcessorTestData* d)
  309. : fViewMatrixStorage(TestMatrix(d->fRandom))
  310. , fColorSpaceInfoStorage(skstd::make_unique<GrColorSpaceInfo>(
  311. GrColorType::kRGBA_8888, kPremul_SkAlphaType, TestColorSpace(d->fRandom)))
  312. , fArgs(d->context(), &fViewMatrixStorage, kNone_SkFilterQuality,
  313. fColorSpaceInfoStorage.get()) {}
  314. TestAsFPArgs::~TestAsFPArgs() {}
  315. } // namespace GrTest
  316. #endif