Use path outlines to define shadow shapes
Fixes the simplifying assumption that shadow casters were always
rectangular.
Java side APIs + plumbing to pass down correct shapes still need to be added.
Change-Id: Ic4fee90af15679951a44bb5cc6ae454b98c4c194
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 741e953..41f34e5 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -3185,28 +3185,43 @@
}
status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha,
- float width, float height) {
+ const SkPath* casterOutline) {
if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
- // For now, always and scissor
- // TODO: use quickReject
+ // TODO: use quickRejectWithScissor. For now, always force enable scissor.
mCaches.enableScissor();
SkPaint paint;
- paint.setColor(mCaches.propertyShadowStrength << 24);
+ paint.setARGB(mCaches.propertyShadowStrength, 0, 0, 0);
paint.setAntiAlias(true); // want to use AlphaVertex
+ // tessellate caster outline into a 2d polygon
+ Vector<Vertex> casterVertices2d;
+ const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
+ PathTessellator::approximatePathOutlineVertices(*casterOutline,
+ casterRefinementThresholdSquared, casterVertices2d);
+
+ // map 2d caster poly into 3d
+ const int casterVertexCount = casterVertices2d.size();
+ Vector3 casterPolygon[casterVertexCount];
+ for (int i = 0; i < casterVertexCount; i++) {
+ const Vertex& point2d = casterVertices2d[i];
+ casterPolygon[i] = Vector3(point2d.x, point2d.y, 0);
+ casterTransform.mapPoint3d(casterPolygon[i]);
+ }
+
+ // draw caster's shadows
VertexBuffer ambientShadowVertexBuffer;
- ShadowTessellator::tessellateAmbientShadow(width, height, casterTransform,
+ ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
ambientShadowVertexBuffer);
drawVertexBuffer(ambientShadowVertexBuffer, &paint);
VertexBuffer spotShadowVertexBuffer;
Vector3 lightPosScale(mCaches.propertyLightPosXScale,
mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
- ShadowTessellator::tessellateSpotShadow(width, height, lightPosScale,
- *currentTransform(), getWidth(), getHeight(),
- casterTransform, spotShadowVertexBuffer);
+ ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
+ lightPosScale, *currentTransform(), getWidth(), getHeight(),
+ spotShadowVertexBuffer);
drawVertexBuffer(spotShadowVertexBuffer, &paint);