Correctly detect the wrong Z value for the light
b/17221975
Change-Id: I2b46da95ad12ca5260d7fe9514a75558b6b6393b
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index cb20a0b..2178cc7 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -647,7 +647,7 @@
if (lightToPolyZ != 0) {
// If any caster's vertex is almost above the light, we just keep it as 95%
// of the height of the light.
- ratioZ = MathUtils::min(polyVertex.z / lightToPolyZ, CASTER_Z_CAP_RATIO);
+ ratioZ = MathUtils::clamp(polyVertex.z / lightToPolyZ, 0.0f, CASTER_Z_CAP_RATIO);
}
outline.x = polyVertex.x - ratioZ * (lightCenter.x - polyVertex.x);
@@ -669,6 +669,10 @@
void SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter,
float lightSize, const Vector3* poly, int polyLength, const Vector3& polyCentroid,
VertexBuffer& shadowTriangleStrip) {
+ if (CC_UNLIKELY(lightCenter.z <= 0)) {
+ ALOGW("Relative Light Z is not positive. No spot shadow!");
+ return;
+ }
OutlineData outlineData[polyLength];
Vector2 outlineCentroid;
// Calculate the projected outline for each polygon's vertices from the light center.
@@ -787,7 +791,7 @@
// The ratio can be simulated by using the inverse of maximum of ratioVI for
// all (V).
distOutline = (outlineData[i].position - outlineCentroid).length();
- if (distOutline == 0) {
+ if (CC_UNLIKELY(distOutline == 0)) {
// If the outline has 0 area, then there is no spot shadow anyway.
ALOGW("Outline has 0 area, no spot shadow!");
return;
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
index 00448b8..d89859b 100644
--- a/libs/hwui/utils/MathUtils.h
+++ b/libs/hwui/utils/MathUtils.h
@@ -76,6 +76,11 @@
return a < b ? a : b;
}
+ template<typename T>
+ static inline T clamp(T a, T minValue, T maxValue) {
+ return min(max(a, minValue), maxValue);
+ }
+
inline static float lerp(float v1, float v2, float t) {
return v1 + ((v2 - v1) * t);
}