aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/SkShadowUtils.cpp
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-05-15 10:44:22 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-15 16:01:43 +0000
commit78c8f30d6167b4bf40937c6a8814cd448e2228a6 (patch)
treed1ccb54f60f7eef479fab4cb4344d6fcab4ebc7c /src/utils/SkShadowUtils.cpp
parente334c596546c7ec79f2b0e55b3a1c2839a94f352 (diff)
Add filled occluders to shadow_utils GM, take 2
Classifies fully visible opaque shadows differently than transparent to avoid cache collisions. Change-Id: Iba5aab2b2cbe08f70205c343e86fe92b0cab7497 Reviewed-on: https://skia-review.googlesource.com/16858 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/utils/SkShadowUtils.cpp')
-rw-r--r--src/utils/SkShadowUtils.cpp40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 355fb2df75..d84c330d07 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -181,10 +181,12 @@ struct SpotVerticesFactory {
enum class OccluderType {
// The umbra cannot be dropped out because the occluder is not opaque.
kTransparent,
+ // The occluder is opaque and the umbra is fully visible
+ kOpaqueFullUmbra,
// The umbra can be dropped where it is occluded.
- kOpaque,
+ kOpaquePartialUmbra,
// It is known that the entire umbra is occluded.
- kOpaqueCoversUmbra
+ kOpaqueNoUmbra
};
SkVector fOffset;
@@ -200,12 +202,13 @@ struct SpotVerticesFactory {
}
switch (fOccluderType) {
case OccluderType::kTransparent:
- case OccluderType::kOpaqueCoversUmbra:
+ case OccluderType::kOpaqueFullUmbra:
+ case OccluderType::kOpaqueNoUmbra:
// 'this' and 'that' will either both have no umbra removed or both have all the
// umbra removed.
*translate = that.fOffset - fOffset;
return true;
- case OccluderType::kOpaque:
+ case OccluderType::kOpaquePartialUmbra:
// In this case we partially remove the umbra differently for 'this' and 'that'
// if the offsets don't match.
if (fOffset == that.fOffset) {
@@ -642,7 +645,8 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
SkScalar radius = lightRadius * zRatio;
- // Compute the translation for the spot shadow.
+ // Compute the scale and translation for the spot shadow.
+ SkScalar scale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
viewMatrix.mapPoints(&center, 1);
factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
@@ -652,17 +656,18 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
factory.fLightRadius = lightRadius;
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()) {
+ if (transparent) {
factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent;
- } else if (factory.fOffset.length() < radius) {
+ } else if (SkTAbs(factory.fOffset.fX) > 0.5f*devBounds.width() ||
+ SkTAbs(factory.fOffset.fY) > 0.5f*devBounds.height()) {
+ // if the translation of the shadow is big enough we're going to end up
+ // filling the entire umbra, so we can treat these as all the same
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaqueFullUmbra;
+ } else if (factory.fOffset.length()*scale + scale < radius) {
// if we don't translate more than the blur distance, can assume umbra is covered
- factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra;
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaqueNoUmbra;
} else {
- factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaque;
+ factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaquePartialUmbra;
}
#ifdef DEBUG_SHADOW_CHECKS
@@ -670,11 +675,14 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi
case SpotVerticesFactory::OccluderType::kTransparent:
color = 0xFFD2B48C; // tan for transparent
break;
- case SpotVerticesFactory::OccluderType::kOpaque:
+ case SpotVerticesFactory::OccluderType::kOpaqueFullUmbra:
+ color = 0xFF614126; // brown for umBra
+ break;
+ case SpotVerticesFactory::OccluderType::kOpaquePartialUmbra:
color = 0xFFFFA500; // orange for opaque
break;
- case SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra:
- color = SK_ColorYELLOW; // corn yellow for covered
+ case SpotVerticesFactory::OccluderType::kOpaqueNoUmbra:
+ color = 0xFFE5E500; // corn yellow for covered
break;
}
#endif