aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2018-06-26 14:58:58 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-26 20:28:55 +0000
commit3645bb069d893e8a8be9955485f2b34a19c72994 (patch)
tree0cf22a4c166ec7fe17336c325591e64023954673 /tests
parent9396bc3fc63df48c8e3aaee3e4f46c6ea4539e5f (diff)
Fix some shadow issues.
* Clamp path polygon points to nearest 1/16th of a pixel to help with floating point issues. * Added check for multiple contour paths. * Return empty SkVertices for certain degenerate cases to avoid unnecessary blurs. * Check iteration count in SkOffsetPolygon to avoid infinite loops. * Add new tests to verify these. Bug: skia: Change-Id: Ie6ad48d2504e065dcc822609d369f90c56ef3ad3 Reviewed-on: https://skia-review.googlesource.com/136701 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/ShadowTest.cpp96
1 files changed, 75 insertions, 21 deletions
diff --git a/tests/ShadowTest.cpp b/tests/ShadowTest.cpp
index 90c1d8ffcc..07ff6dfdce 100644
--- a/tests/ShadowTest.cpp
+++ b/tests/ShadowTest.cpp
@@ -13,31 +13,40 @@
#include "SkVertices.h"
#include "Test.h"
-void tessellate_shadow(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm,
- bool expectSuccess) {
-
- auto heightParams = SkPoint3::Make(0, 0, 4);
+enum ExpectVerts {
+ kDont_ExpectVerts,
+ kDo_ExpectVerts
+};
- auto verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, true);
+void check_result(skiatest::Reporter* reporter, sk_sp<SkVertices> verts,
+ ExpectVerts expectVerts, bool expectSuccess) {
if (expectSuccess != SkToBool(verts)) {
ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
expectSuccess ? "succeed" : "fail");
}
- verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, false);
- if (expectSuccess != SkToBool(verts)) {
- ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
- expectSuccess ? "succeed" : "fail");
+ if (SkToBool(verts)) {
+ if (kDont_ExpectVerts == expectVerts && verts->vertexCount()) {
+ ERRORF(reporter, "Expected shadow tessellation to generate no vertices but it did.");
+ } else if (kDo_ExpectVerts == expectVerts && !verts->vertexCount()) {
+ ERRORF(reporter, "Expected shadow tessellation to generate vertices but it didn't.");
+ }
}
+}
+
+void tessellate_shadow(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm,
+ const SkPoint3& heightParams, ExpectVerts expectVerts, bool expectSuccess) {
+
+ auto verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, true);
+ check_result(reporter, verts, expectVerts, expectSuccess);
+
+ verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, false);
+ check_result(reporter, verts, expectVerts, expectSuccess);
+
verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false);
- if (expectSuccess != SkToBool(verts)) {
- ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
- expectSuccess ? "succeed" : "fail");
- }
+ check_result(reporter, verts, expectVerts, expectSuccess);
+
verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false);
- if (expectSuccess != SkToBool(verts)) {
- ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
- expectSuccess ? "succeed" : "fail");
- }
+ check_result(reporter, verts, expectVerts, expectSuccess);
}
DEF_TEST(ShadowUtils, reporter) {
@@ -45,19 +54,64 @@ DEF_TEST(ShadowUtils, reporter) {
SkPath path;
path.cubicTo(100, 50, 20, 100, 0, 0);
- tessellate_shadow(reporter, path, canvas.getTotalMatrix(), true);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDo_ExpectVerts, true);
+ // super high path
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4.0e+37f},
+ kDo_ExpectVerts, true);
// This line segment has no area and no shadow.
path.reset();
path.lineTo(10.f, 10.f);
- tessellate_shadow(reporter, path, canvas.getTotalMatrix(), false);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDont_ExpectVerts, true);
- // A series of colinear line segments
+ // A series of collinear line segments
path.reset();
for (int i = 0; i < 10; ++i) {
path.lineTo((SkScalar)i, (SkScalar)i);
}
- tessellate_shadow(reporter, path, canvas.getTotalMatrix(), false);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 4}, kDont_ExpectVerts, true);
+
+ // ugly degenerate path
+ path.reset();
+ path.moveTo(-134217728, 2.22265153e+21f);
+ path.cubicTo(-2.33326106e+21f, 7.36298265e-41f, 3.72237738e-22f, 5.99502692e-36f,
+ 1.13631943e+22f, 2.0890786e+33f);
+ path.cubicTo(1.03397626e-25f, 5.99502692e-36f, 9.18354962e-41f, 0, 4.6142745e-37f, -213558848);
+ path.lineTo(-134217728, 2.2226515e+21f);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, true);
+
+ // simple concave path (star of David)
+ path.reset();
+ path.moveTo(0.0f, -50.0f);
+ path.lineTo(14.43f, -25.0f);
+ path.lineTo(43.30f, -25.0f);
+ path.lineTo(28.86f, 0.0f);
+ path.lineTo(43.30f, 25.0f);
+ path.lineTo(14.43f, 25.0f);
+ path.lineTo(0.0f, 50.0f);
+ path.lineTo(-14.43f, 25.0f);
+ path.lineTo(-43.30f, 25.0f);
+ path.lineTo(-28.86f, 0.0f);
+ path.lineTo(-43.30f, -25.0f);
+ path.lineTo(-14.43f, -25.0f);
+// uncomment when transparent concave shadows are working
+// tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDo_ExpectVerts, true);
+
+ // complex concave path (bowtie)
+ path.reset();
+ path.moveTo(-50, -50);
+ path.lineTo(-50, 50);
+ path.lineTo(50, -50);
+ path.lineTo(50, 50);
+ path.lineTo(-50, -50);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, false);
+
+ // multiple contour path
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(0, 1);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), {0, 0, 9}, kDont_ExpectVerts, false);
}
void check_xformed_bounds(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm) {