aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-05-11 17:05:28 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-11 21:38:51 +0000
commita783c3623d3cf8b0d2106f055ae4a21d4f8d23d8 (patch)
tree73a2a9da23cfc534140b76d55df3ff07818dcbae
parentcd9af1bfa8aa0efafabe59da5e7cda0fc9e7eb1f (diff)
Classify spot shadows for general shapes
Add some simple checks so we can tell whether a shadow's umbra is completely covered by the occluder, partially covered, or less than halfway covered. Change-Id: I092281c4933bd0380946eb0fdd458ce04b0d713c Reviewed-on: https://skia-review.googlesource.com/16603 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
-rw-r--r--src/utils/SkShadowUtils.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index caf918e4f2..355fb2df75 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -640,6 +640,9 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
SpotVerticesFactory factory;
SkScalar occluderHeight = zPlaneParams.fZ;
float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
+ SkScalar radius = lightRadius * zRatio;
+
+ // Compute the translation for the spot shadow.
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
viewMatrix.mapPoints(&center, 1);
factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
@@ -647,9 +650,34 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
factory.fOccluderHeight = occluderHeight;
factory.fDevLightPos = devLightPos;
factory.fLightRadius = lightRadius;
- // the only valid choice we have right now
- factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
+ SkRect devBounds;
+ viewMatrix.mapRect(&devBounds, path.getBounds());
+ if (transparent ||
+ // if the translation of the shadow is big enough we're going to end up
+ // filling the entire umbra, so we can treat this as transparent
+ SkTAbs(factory.fOffset.fX) > 0.5f*devBounds.width() ||
+ SkTAbs(factory.fOffset.fY) > 0.5f*devBounds.height()) {
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
+ } else if (factory.fOffset.length() < radius) {
+ // if we don't translate more than the blur distance, can assume umbra is covered
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra;
+ } else {
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaque;
+ }
+#ifdef DEBUG_SHADOW_CHECKS
+ switch (factory.fOccluderType) {
+ case SpotVerticesFactory::OccluderType::kTransparent:
+ color = 0xFFD2B48C; // tan for transparent
+ break;
+ case SpotVerticesFactory::OccluderType::kOpaque:
+ color = 0xFFFFA500; // orange for opaque
+ break;
+ case SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra:
+ color = SK_ColorYELLOW; // corn yellow for covered
+ break;
+ }
+#endif
SkColor renderColor = compute_render_color(color, spotAlpha);
draw_shadow(factory, canvas, shadowedPath, renderColor);
}