GpuDrawPathTest.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright 2013 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 "include/core/SkTypes.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkCanvas.h"
  10. #include "include/core/SkColor.h"
  11. #include "include/core/SkPaint.h"
  12. #include "include/core/SkPath.h"
  13. #include "include/core/SkRRect.h"
  14. #include "include/core/SkRect.h"
  15. #include "include/core/SkSurface.h"
  16. #include "include/effects/SkDashPathEffect.h"
  17. #include "include/gpu/GrContext.h"
  18. #include "src/gpu/GrPath.h"
  19. #include "src/gpu/geometry/GrShape.h"
  20. #include "tests/Test.h"
  21. #include <initializer_list>
  22. static void test_drawPathEmpty(skiatest::Reporter*, SkCanvas* canvas) {
  23. // Filling an empty path should not crash.
  24. SkPaint paint;
  25. SkRect emptyRect = SkRect::MakeEmpty();
  26. canvas->drawRect(emptyRect, paint);
  27. canvas->drawPath(SkPath(), paint);
  28. canvas->drawOval(emptyRect, paint);
  29. canvas->drawRect(emptyRect, paint);
  30. canvas->drawRRect(SkRRect::MakeRect(emptyRect), paint);
  31. // Stroking an empty path should not crash.
  32. paint.setAntiAlias(true);
  33. paint.setStyle(SkPaint::kStroke_Style);
  34. paint.setColor(SK_ColorGRAY);
  35. paint.setStrokeWidth(SkIntToScalar(20));
  36. paint.setStrokeJoin(SkPaint::kRound_Join);
  37. canvas->drawRect(emptyRect, paint);
  38. canvas->drawPath(SkPath(), paint);
  39. canvas->drawOval(emptyRect, paint);
  40. canvas->drawRect(emptyRect, paint);
  41. canvas->drawRRect(SkRRect::MakeRect(emptyRect), paint);
  42. }
  43. static void fill_and_stroke(SkCanvas* canvas, const SkPath& p1, const SkPath& p2,
  44. sk_sp<SkPathEffect> effect) {
  45. SkPaint paint;
  46. paint.setAntiAlias(true);
  47. paint.setPathEffect(effect);
  48. canvas->drawPath(p1, paint);
  49. canvas->drawPath(p2, paint);
  50. paint.setStyle(SkPaint::kStroke_Style);
  51. canvas->drawPath(p1, paint);
  52. canvas->drawPath(p2, paint);
  53. }
  54. static void test_drawSameRectOvals(skiatest::Reporter*, SkCanvas* canvas) {
  55. // Drawing ovals with similar bounds but different points order should not crash.
  56. SkPath oval1, oval2;
  57. const SkRect rect = SkRect::MakeWH(100, 50);
  58. oval1.addOval(rect, SkPath::kCW_Direction);
  59. oval2.addOval(rect, SkPath::kCCW_Direction);
  60. fill_and_stroke(canvas, oval1, oval2, nullptr);
  61. const SkScalar intervals[] = { 1, 1 };
  62. fill_and_stroke(canvas, oval1, oval2, SkDashPathEffect::Make(intervals, 2, 0));
  63. }
  64. DEF_GPUTEST_FOR_ALL_GL_CONTEXTS(GpuDrawPath, reporter, ctxInfo) {
  65. for (auto& test_func : { &test_drawPathEmpty, &test_drawSameRectOvals }) {
  66. for (auto& sampleCount : {1, 4, 16}) {
  67. SkImageInfo info = SkImageInfo::MakeN32Premul(255, 255);
  68. auto surface(
  69. SkSurface::MakeRenderTarget(ctxInfo.grContext(), SkBudgeted::kNo, info,
  70. sampleCount, nullptr));
  71. if (!surface) {
  72. continue;
  73. }
  74. test_func(reporter, surface->getCanvas());
  75. }
  76. }
  77. }
  78. DEF_GPUTEST(GrPathKeys, reporter, /* options */) {
  79. SkPaint strokePaint;
  80. strokePaint.setStyle(SkPaint::kStroke_Style);
  81. strokePaint.setStrokeWidth(10.f);
  82. GrStyle styles[] = {
  83. GrStyle::SimpleFill(),
  84. GrStyle::SimpleHairline(),
  85. GrStyle(strokePaint)
  86. };
  87. for (const GrStyle& style : styles) {
  88. // Keys should not ignore conic weights.
  89. SkPath path1, path2;
  90. SkPoint p0 = SkPoint::Make(100, 0);
  91. SkPoint p1 = SkPoint::Make(100, 100);
  92. path1.conicTo(p0, p1, .5f);
  93. path2.conicTo(p0, p1, .7f);
  94. GrUniqueKey key1, key2;
  95. // We expect these small paths to be keyed based on their data.
  96. bool isVolatile;
  97. GrPath::ComputeKey(GrShape(path1, GrStyle::SimpleFill()), &key1, &isVolatile);
  98. REPORTER_ASSERT(reporter, !isVolatile);
  99. REPORTER_ASSERT(reporter, key1.isValid());
  100. GrPath::ComputeKey(GrShape(path2, GrStyle::SimpleFill()), &key2, &isVolatile);
  101. REPORTER_ASSERT(reporter, !isVolatile);
  102. REPORTER_ASSERT(reporter, key1.isValid());
  103. REPORTER_ASSERT(reporter, key1 != key2);
  104. {
  105. GrUniqueKey tempKey;
  106. path1.setIsVolatile(true);
  107. GrPath::ComputeKey(GrShape(path1, style), &key1, &isVolatile);
  108. REPORTER_ASSERT(reporter, isVolatile);
  109. REPORTER_ASSERT(reporter, !tempKey.isValid());
  110. }
  111. // Ensure that recreating the GrShape doesn't change the key.
  112. {
  113. GrUniqueKey tempKey;
  114. GrPath::ComputeKey(GrShape(path2, GrStyle::SimpleFill()), &tempKey, &isVolatile);
  115. REPORTER_ASSERT(reporter, key2 == tempKey);
  116. }
  117. // Try a large path that is too big to be keyed off its data.
  118. SkPath path3;
  119. SkPath path4;
  120. for (int i = 0; i < 1000; ++i) {
  121. SkScalar s = SkIntToScalar(i);
  122. path3.conicTo(s, 3.f * s / 4, s + 1.f, s, 0.5f + s / 2000.f);
  123. path4.conicTo(s, 3.f * s / 4, s + 1.f, s, 0.3f + s / 2000.f);
  124. }
  125. GrUniqueKey key3, key4;
  126. // These aren't marked volatile and so should have keys
  127. GrPath::ComputeKey(GrShape(path3, style), &key3, &isVolatile);
  128. REPORTER_ASSERT(reporter, !isVolatile);
  129. REPORTER_ASSERT(reporter, key3.isValid());
  130. GrPath::ComputeKey(GrShape(path4, style), &key4, &isVolatile);
  131. REPORTER_ASSERT(reporter, !isVolatile);
  132. REPORTER_ASSERT(reporter, key4.isValid());
  133. REPORTER_ASSERT(reporter, key3 != key4);
  134. {
  135. GrUniqueKey tempKey;
  136. path3.setIsVolatile(true);
  137. GrPath::ComputeKey(GrShape(path3, style), &key1, &isVolatile);
  138. REPORTER_ASSERT(reporter, isVolatile);
  139. REPORTER_ASSERT(reporter, !tempKey.isValid());
  140. }
  141. }
  142. }