diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
deleted file mode 100644
index aa96698..0000000
--- a/libs/hwui/AmbientShadow.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Extra vertices for the corner for smoother corner.
- * Only for outer vertices.
- * Note that we use such extra memory to avoid an extra loop.
- */
-// For half circle, we could add EXTRA_VERTEX_PER_PI vertices.
-// Set to 1 if we don't want to have any.
-#define EXTRA_CORNER_VERTEX_PER_PI 12
-
-// For the whole polygon, the sum of all the deltas b/t normals is 2 * M_PI,
-// therefore, the maximum number of extra vertices will be twice bigger.
-#define MAX_EXTRA_CORNER_VERTEX_NUMBER (2 * EXTRA_CORNER_VERTEX_PER_PI)
-
-// For each RADIANS_DIVISOR, we would allocate one more vertex b/t the normals.
-#define CORNER_RADIANS_DIVISOR (M_PI / EXTRA_CORNER_VERTEX_PER_PI)
-
-/**
- * Extra vertices for the Edge for interpolation artifacts.
- * Same value for both inner and outer vertices.
- */
-#define EXTRA_EDGE_VERTEX_PER_PI 50
-
-#define MAX_EXTRA_EDGE_VERTEX_NUMBER (2 * EXTRA_EDGE_VERTEX_PER_PI)
-
-#define EDGE_RADIANS_DIVISOR (M_PI / EXTRA_EDGE_VERTEX_PER_PI)
-
-/**
- * Other constants:
- */
-#define OUTER_ALPHA (0.0f)
-
-// Once the alpha difference is greater than this threshold, we will allocate extra
-// edge vertices.
-// If this is set to negative value, then all the edge will be tessellated.
-#define ALPHA_THRESHOLD (0.1f / 255.0f)
-
-#include "AmbientShadow.h"
-
-#include "ShadowTessellator.h"
-#include "Vertex.h"
-#include "VertexBuffer.h"
-
-#include <utils/Log.h>
-#include <algorithm>
-
-namespace android {
-namespace uirenderer {
-
-/**
- *  Local utility functions.
- */
-inline Vector2 getNormalFromVertices(const Vector3* vertices, int current, int next) {
-    // Convert from Vector3 to Vector2 first.
-    Vector2 currentVertex = {vertices[current].x, vertices[current].y};
-    Vector2 nextVertex = {vertices[next].x, vertices[next].y};
-
-    return ShadowTessellator::calculateNormal(currentVertex, nextVertex);
-}
-
-// The input z value will be converted to be non-negative inside.
-// The output must be ranged from 0 to 1.
-inline float getAlphaFromFactoredZ(float factoredZ) {
-    return 1.0 / (1 + std::max(factoredZ, 0.0f));
-}
-
-inline int getEdgeExtraAndUpdateSpike(Vector2* currentSpike, const Vector3& secondVertex,
-                                      const Vector3& centroid) {
-    Vector2 secondSpike = {secondVertex.x - centroid.x, secondVertex.y - centroid.y};
-    secondSpike.normalize();
-
-    int result = ShadowTessellator::getExtraVertexNumber(secondSpike, *currentSpike,
-                                                         EDGE_RADIANS_DIVISOR);
-    *currentSpike = secondSpike;
-    return result;
-}
-
-// Given the caster's vertex count, compute all the buffers size depending on
-// whether or not the caster is opaque.
-inline void computeBufferSize(int* totalVertexCount, int* totalIndexCount, int* totalUmbraCount,
-                              int casterVertexCount, bool isCasterOpaque) {
-    // Compute the size of the vertex buffer.
-    int outerVertexCount =
-            casterVertexCount * 2 + MAX_EXTRA_CORNER_VERTEX_NUMBER + MAX_EXTRA_EDGE_VERTEX_NUMBER;
-    int innerVertexCount = casterVertexCount + MAX_EXTRA_EDGE_VERTEX_NUMBER;
-    *totalVertexCount = outerVertexCount + innerVertexCount;
-
-    // Compute the size of the index buffer.
-    *totalIndexCount = 2 * outerVertexCount + 2;
-
-    // Compute the size of the umber buffer.
-    // For translucent object, keep track of the umbra(inner) vertex in order to draw
-    // inside. We only need to store the index information.
-    *totalUmbraCount = 0;
-    if (!isCasterOpaque) {
-        // Add the centroid if occluder is translucent.
-        (*totalVertexCount)++;
-        *totalIndexCount += 2 * innerVertexCount + 1;
-        *totalUmbraCount = innerVertexCount;
-    }
-}
-
-inline bool needsExtraForEdge(float firstAlpha, float secondAlpha) {
-    return fabsf(firstAlpha - secondAlpha) > ALPHA_THRESHOLD;
-}
-
-/**
- * Calculate the shadows as a triangle strips while alpha value as the
- * shadow values.
- *
- * @param isCasterOpaque Whether the caster is opaque.
- * @param vertices The shadow caster's polygon, which is represented in a Vector3
- *                  array.
- * @param vertexCount The length of caster's polygon in terms of number of
- *                    vertices.
- * @param centroid3d The centroid of the shadow caster.
- * @param heightFactor The factor showing the higher the object, the lighter the
- *                     shadow.
- * @param geomFactor The factor scaling the geometry expansion along the normal.
- *
- * @param shadowVertexBuffer Return an floating point array of (x, y, a)
- *               triangle strips mode.
- *
- * An simple illustration:
- * For now let's mark the outer vertex as Pi, the inner as Vi, the centroid as C.
- *
- * First project the occluder to the Z=0 surface.
- * Then we got all the inner vertices. And we compute the normal for each edge.
- * According to the normal, we generate outer vertices. E.g: We generate P1 / P4
- * as extra corner vertices to make the corner looks round and smoother.
- *
- * Due to the fact that the alpha is not linear interpolated along the inner
- * edge, when the alpha is different, we may add extra vertices such as P2.1, P2.2,
- * V0.1, V0.2 to avoid the visual artifacts.
- *
- *                                            (P3)
- *          (P2)     (P2.1)     (P2.2)         |     ' (P4)
- *   (P1)'   |        |           |            |   '
- *         ' |        |           |            | '
- * (P0)  ------------------------------------------------(P5)
- *           | (V0)   (V0.1)    (V0.2)         |(V1)
- *           |                                 |
- *           |                                 |
- *           |               (C)               |
- *           |                                 |
- *           |                                 |
- *           |                                 |
- *           |                                 |
- *        (V3)-----------------------------------(V2)
- */
-void AmbientShadow::createAmbientShadow(bool isCasterOpaque, const Vector3* casterVertices,
-                                        int casterVertexCount, const Vector3& centroid3d,
-                                        float heightFactor, float geomFactor,
-                                        VertexBuffer& shadowVertexBuffer) {
-    shadowVertexBuffer.setMeshFeatureFlags(VertexBuffer::kAlpha | VertexBuffer::kIndices);
-
-    // In order to computer the outer vertices in one loop, we need pre-compute
-    // the normal by the vertex (n - 1) to vertex 0, and the spike and alpha value
-    // for vertex 0.
-    Vector2 previousNormal = getNormalFromVertices(casterVertices, casterVertexCount - 1, 0);
-    Vector2 currentSpike = {casterVertices[0].x - centroid3d.x, casterVertices[0].y - centroid3d.y};
-    currentSpike.normalize();
-    float currentAlpha = getAlphaFromFactoredZ(casterVertices[0].z * heightFactor);
-
-    // Preparing all the output data.
-    int totalVertexCount, totalIndexCount, totalUmbraCount;
-    computeBufferSize(&totalVertexCount, &totalIndexCount, &totalUmbraCount, casterVertexCount,
-                      isCasterOpaque);
-    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(totalVertexCount);
-    int vertexBufferIndex = 0;
-    uint16_t* indexBuffer = shadowVertexBuffer.allocIndices<uint16_t>(totalIndexCount);
-    int indexBufferIndex = 0;
-    uint16_t umbraVertices[totalUmbraCount];
-    int umbraIndex = 0;
-
-    for (int i = 0; i < casterVertexCount; i++) {
-        // Corner: first figure out the extra vertices we need for the corner.
-        const Vector3& innerVertex = casterVertices[i];
-        Vector2 currentNormal =
-                getNormalFromVertices(casterVertices, i, (i + 1) % casterVertexCount);
-
-        int extraVerticesNumber = ShadowTessellator::getExtraVertexNumber(
-                currentNormal, previousNormal, CORNER_RADIANS_DIVISOR);
-
-        float expansionDist = innerVertex.z * heightFactor * geomFactor;
-        const int cornerSlicesNumber = extraVerticesNumber + 1;  // Minimal as 1.
-#if DEBUG_SHADOW
-        ALOGD("cornerSlicesNumber is %d", cornerSlicesNumber);
-#endif
-
-        // Corner: fill the corner Vertex Buffer(VB) and Index Buffer(IB).
-        // We fill the inner vertex first, such that we can fill the index buffer
-        // inside the loop.
-        int currentInnerVertexIndex = vertexBufferIndex;
-        if (!isCasterOpaque) {
-            umbraVertices[umbraIndex++] = vertexBufferIndex;
-        }
-        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], casterVertices[i].x,
-                         casterVertices[i].y, currentAlpha);
-
-        const Vector3& innerStart = casterVertices[i];
-
-        // outerStart is the first outer vertex for this inner vertex.
-        // outerLast is the last outer vertex for this inner vertex.
-        Vector2 outerStart = {0, 0};
-        Vector2 outerLast = {0, 0};
-        // This will create vertices from [0, cornerSlicesNumber] inclusively,
-        // which means minimally 2 vertices even without the extra ones.
-        for (int j = 0; j <= cornerSlicesNumber; j++) {
-            Vector2 averageNormal = previousNormal * (cornerSlicesNumber - j) + currentNormal * j;
-            averageNormal /= cornerSlicesNumber;
-            averageNormal.normalize();
-            Vector2 outerVertex;
-            outerVertex.x = innerVertex.x + averageNormal.x * expansionDist;
-            outerVertex.y = innerVertex.y + averageNormal.y * expansionDist;
-
-            indexBuffer[indexBufferIndex++] = vertexBufferIndex;
-            indexBuffer[indexBufferIndex++] = currentInnerVertexIndex;
-            AlphaVertex::set(&shadowVertices[vertexBufferIndex++], outerVertex.x, outerVertex.y,
-                             OUTER_ALPHA);
-
-            if (j == 0) {
-                outerStart = outerVertex;
-            } else if (j == cornerSlicesNumber) {
-                outerLast = outerVertex;
-            }
-        }
-        previousNormal = currentNormal;
-
-        // Edge: first figure out the extra vertices needed for the edge.
-        const Vector3& innerNext = casterVertices[(i + 1) % casterVertexCount];
-        float nextAlpha = getAlphaFromFactoredZ(innerNext.z * heightFactor);
-        if (needsExtraForEdge(currentAlpha, nextAlpha)) {
-            // TODO: See if we can / should cache this outer vertex across the loop.
-            Vector2 outerNext;
-            float expansionDist = innerNext.z * heightFactor * geomFactor;
-            outerNext.x = innerNext.x + currentNormal.x * expansionDist;
-            outerNext.y = innerNext.y + currentNormal.y * expansionDist;
-
-            // Compute the angle and see how many extra points we need.
-            int extraVerticesNumber =
-                    getEdgeExtraAndUpdateSpike(&currentSpike, innerNext, centroid3d);
-#if DEBUG_SHADOW
-            ALOGD("extraVerticesNumber %d for edge %d", extraVerticesNumber, i);
-#endif
-            // Edge: fill the edge's VB and IB.
-            // This will create vertices pair from [1, extraVerticesNumber - 1].
-            // If there is no extra vertices created here, the edge will be drawn
-            // as just 2 triangles.
-            for (int k = 1; k < extraVerticesNumber; k++) {
-                int startWeight = extraVerticesNumber - k;
-                Vector2 currentOuter =
-                        (outerLast * startWeight + outerNext * k) / extraVerticesNumber;
-                indexBuffer[indexBufferIndex++] = vertexBufferIndex;
-                AlphaVertex::set(&shadowVertices[vertexBufferIndex++], currentOuter.x,
-                                 currentOuter.y, OUTER_ALPHA);
-
-                if (!isCasterOpaque) {
-                    umbraVertices[umbraIndex++] = vertexBufferIndex;
-                }
-                Vector3 currentInner =
-                        (innerStart * startWeight + innerNext * k) / extraVerticesNumber;
-                indexBuffer[indexBufferIndex++] = vertexBufferIndex;
-                AlphaVertex::set(&shadowVertices[vertexBufferIndex++], currentInner.x,
-                                 currentInner.y,
-                                 getAlphaFromFactoredZ(currentInner.z * heightFactor));
-            }
-        }
-        currentAlpha = nextAlpha;
-    }
-
-    indexBuffer[indexBufferIndex++] = 1;
-    indexBuffer[indexBufferIndex++] = 0;
-
-    if (!isCasterOpaque) {
-        // Add the centroid as the last one in the vertex buffer.
-        float centroidOpacity = getAlphaFromFactoredZ(centroid3d.z * heightFactor);
-        int centroidIndex = vertexBufferIndex;
-        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], centroid3d.x, centroid3d.y,
-                         centroidOpacity);
-
-        for (int i = 0; i < umbraIndex; i++) {
-            // Note that umbraVertices[0] is always 0.
-            // So the start and the end of the umbra are using the "0".
-            // And penumbra ended with 0, so a degenerated triangle is formed b/t
-            // the umbra and penumbra.
-            indexBuffer[indexBufferIndex++] = umbraVertices[i];
-            indexBuffer[indexBufferIndex++] = centroidIndex;
-        }
-        indexBuffer[indexBufferIndex++] = 0;
-    }
-
-    // At the end, update the real index and vertex buffer size.
-    shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
-    shadowVertexBuffer.updateIndexCount(indexBufferIndex);
-    shadowVertexBuffer.computeBounds<AlphaVertex>();
-
-    ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Ambient Vertex Buffer");
-    ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Ambient Index Buffer");
-    ShadowTessellator::checkOverflow(umbraIndex, totalUmbraCount, "Ambient Umbra Buffer");
-
-#if DEBUG_SHADOW
-    for (int i = 0; i < vertexBufferIndex; i++) {
-        ALOGD("vertexBuffer i %d, (%f, %f %f)", i, shadowVertices[i].x, shadowVertices[i].y,
-              shadowVertices[i].alpha);
-    }
-    for (int i = 0; i < indexBufferIndex; i++) {
-        ALOGD("indexBuffer i %d, indexBuffer[i] %d", i, indexBuffer[i]);
-    }
-#endif
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
deleted file mode 100644
index cb1d915..0000000
--- a/libs/hwui/AmbientShadow.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_AMBIENT_SHADOW_H
-#define ANDROID_HWUI_AMBIENT_SHADOW_H
-
-#include "Debug.h"
-#include "Vector.h"
-
-namespace android {
-namespace uirenderer {
-
-class VertexBuffer;
-
-/**
- * AmbientShadow is used to calculate the ambient shadow value around a polygon.
- */
-class AmbientShadow {
-public:
-    static void createAmbientShadow(bool isCasterOpaque, const Vector3* poly, int polyLength,
-                                    const Vector3& centroid3d, float heightFactor, float geomFactor,
-                                    VertexBuffer& shadowVertexBuffer);
-};  // AmbientShadow
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_AMBIENT_SHADOW_H
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 1ad40ec..6de3a38 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -197,7 +197,6 @@
         "utils/StringUtils.cpp",
         "utils/TestWindowContext.cpp",
         "utils/VectorDrawableUtils.cpp",
-        "AmbientShadow.cpp",
         "AnimationContext.cpp",
         "Animator.cpp",
         "AnimatorManager.cpp",
@@ -238,12 +237,10 @@
         "RenderNode.cpp",
         "RenderProperties.cpp",
         "ResourceCache.cpp",
-        "ShadowTessellator.cpp",
         "SkiaCanvas.cpp",
         "SkiaCanvasProxy.cpp",
         "SkiaShader.cpp",
         "Snapshot.cpp",
-        "SpotShadow.cpp",
         "Texture.cpp",
         "VectorDrawable.cpp",
         "VkLayer.cpp",
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 9c2ab5c..74e0997 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -18,7 +18,6 @@
 
 #include "GlLayer.h"
 #include "Properties.h"
-#include "ShadowTessellator.h"
 #include "renderstate/RenderState.h"
 #include "utils/GLUtils.h"
 
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
deleted file mode 100644
index d0155ee..0000000
--- a/libs/hwui/ShadowTessellator.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <math.h>
-#include <utils/Log.h>
-#include <utils/MathUtils.h>
-#include <utils/Trace.h>
-
-#include "AmbientShadow.h"
-#include "Properties.h"
-#include "ShadowTessellator.h"
-#include "SpotShadow.h"
-#include "Vector.h"
-
-namespace android {
-namespace uirenderer {
-
-void ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon,
-                                                int casterVertexCount, const Vector3& centroid3d,
-                                                const Rect& casterBounds, const Rect& localClip,
-                                                float maxZ, VertexBuffer& shadowVertexBuffer) {
-    ATRACE_CALL();
-
-    // A bunch of parameters to tweak the shadow.
-    // TODO: Allow some of these changable by debug settings or APIs.
-    float heightFactor = 1.0f / 128;
-    const float geomFactor = 64;
-
-    if (CC_UNLIKELY(Properties::overrideAmbientRatio > 0.0f)) {
-        heightFactor *= Properties::overrideAmbientRatio;
-    }
-
-    Rect ambientShadowBounds(casterBounds);
-    ambientShadowBounds.outset(maxZ * geomFactor * heightFactor);
-
-    if (!localClip.intersects(ambientShadowBounds)) {
-#if DEBUG_SHADOW
-        ALOGD("Ambient shadow is out of clip rect!");
-#endif
-        return;
-    }
-
-    AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
-                                       heightFactor, geomFactor, shadowVertexBuffer);
-}
-
-void ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon,
-                                             int casterVertexCount, const Vector3& casterCentroid,
-                                             const mat4& receiverTransform,
-                                             const Vector3& lightCenter, int lightRadius,
-                                             const Rect& casterBounds, const Rect& localClip,
-                                             VertexBuffer& shadowVertexBuffer) {
-    ATRACE_CALL();
-
-    Vector3 adjustedLightCenter(lightCenter);
-    if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
-        adjustedLightCenter.y = -Properties::overrideLightPosY;  // negated since this shifts up
-    }
-    if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
-        adjustedLightCenter.z = Properties::overrideLightPosZ;
-    }
-
-#if DEBUG_SHADOW
-    ALOGD("light center %f %f %f %d", adjustedLightCenter.x, adjustedLightCenter.y,
-          adjustedLightCenter.z, lightRadius);
-#endif
-    if (isnan(adjustedLightCenter.x) || isnan(adjustedLightCenter.y) ||
-        isnan(adjustedLightCenter.z)) {
-        return;
-    }
-
-    // light position (because it's in local space) needs to compensate for receiver transform
-    // TODO: should apply to light orientation, not just position
-    Matrix4 reverseReceiverTransform;
-    reverseReceiverTransform.loadInverse(receiverTransform);
-    reverseReceiverTransform.mapPoint3d(adjustedLightCenter);
-
-    if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
-        lightRadius = Properties::overrideLightRadius;
-    }
-
-    // Now light and caster are both in local space, we will check whether
-    // the shadow is within the clip area.
-    Rect lightRect = Rect(adjustedLightCenter.x - lightRadius, adjustedLightCenter.y - lightRadius,
-                          adjustedLightCenter.x + lightRadius, adjustedLightCenter.y + lightRadius);
-    lightRect.unionWith(localClip);
-    if (!lightRect.intersects(casterBounds)) {
-#if DEBUG_SHADOW
-        ALOGD("Spot shadow is out of clip rect!");
-#endif
-        return;
-    }
-
-    SpotShadow::createSpotShadow(isCasterOpaque, adjustedLightCenter, lightRadius, casterPolygon,
-                                 casterVertexCount, casterCentroid, shadowVertexBuffer);
-
-#if DEBUG_SHADOW
-    if (shadowVertexBuffer.getVertexCount() <= 0) {
-        ALOGD("Spot shadow generation failed %d", shadowVertexBuffer.getVertexCount());
-    }
-#endif
-}
-
-/**
- * Calculate the centroid of a 2d polygon.
- *
- * @param poly The polygon, which is represented in a Vector2 array.
- * @param polyLength The length of the polygon in terms of number of vertices.
- * @return the centroid of the polygon.
- */
-Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) {
-    double sumx = 0;
-    double sumy = 0;
-    int p1 = polyLength - 1;
-    double area = 0;
-    for (int p2 = 0; p2 < polyLength; p2++) {
-        double x1 = poly[p1].x;
-        double y1 = poly[p1].y;
-        double x2 = poly[p2].x;
-        double y2 = poly[p2].y;
-        double a = (x1 * y2 - x2 * y1);
-        sumx += (x1 + x2) * a;
-        sumy += (y1 + y2) * a;
-        area += a;
-        p1 = p2;
-    }
-
-    Vector2 centroid = poly[0];
-    if (area != 0) {
-        centroid = (Vector2){static_cast<float>(sumx / (3 * area)),
-                             static_cast<float>(sumy / (3 * area))};
-    } else {
-        ALOGW("Area is 0 while computing centroid!");
-    }
-    return centroid;
-}
-
-// Make sure p1 -> p2 is going CW around the poly.
-Vector2 ShadowTessellator::calculateNormal(const Vector2& p1, const Vector2& p2) {
-    Vector2 result = p2 - p1;
-    if (result.x != 0 || result.y != 0) {
-        result.normalize();
-        // Calculate the normal , which is CCW 90 rotate to the delta.
-        float tempy = result.y;
-        result.y = result.x;
-        result.x = -tempy;
-    }
-    return result;
-}
-
-int ShadowTessellator::getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
-                                            float divisor) {
-    // When there is no distance difference, there is no need for extra vertices.
-    if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
-        return 0;
-    }
-    // The formula is :
-    // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
-    // The value ranges for each step are:
-    // dot( ) --- [-1, 1]
-    // acos( )     --- [0, M_PI]
-    // floor(...)  --- [0, EXTRA_VERTEX_PER_PI]
-    float dotProduct = vector1.dot(vector2);
-    // make sure that dotProduct value is in acsof input range [-1, 1]
-    dotProduct = MathUtils::clamp(dotProduct, -1.0f, 1.0f);
-    // TODO: Use look up table for the dotProduct to extraVerticesNumber
-    // computation, if needed.
-    float angle = acosf(dotProduct);
-    return (int)floor(angle / divisor);
-}
-
-void ShadowTessellator::checkOverflow(int used, int total, const char* bufferName) {
-    LOG_ALWAYS_FATAL_IF(used > total, "Error: %s overflow!!! used %d, total %d", bufferName, used,
-                        total);
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
deleted file mode 100644
index 79f46f9..0000000
--- a/libs/hwui/ShadowTessellator.h
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H
-#define ANDROID_HWUI_SHADOW_TESSELLATOR_H
-
-#include <SkPath.h>
-
-#include "Debug.h"
-#include "Matrix.h"
-
-namespace android {
-namespace uirenderer {
-
-class VertexBuffer;
-
-// All SHADOW_* are used to define all the geometry property of shadows.
-// Use a simplified example to illustrate the geometry setup here.
-// Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
-// are 0 to 5 and 6 to 11. The area between them will be the penumbra area, and
-// the area inside the 2nd hexagon is the umbra.
-// Ambient shadow is using only 1 layer for opaque caster, otherwise, spot
-// shadow and ambient shadow are using 2 layers.
-// Triange strip indices for penumbra area: (0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 0, 6)
-//                 0
-//
-//      5          6         1
-//           11         7
-//
-//           10         8
-//      4          9         2
-//
-//                 3
-
-// The total number of rays starting from the centroid of shadow area, in order
-// to generate the shadow geometry.
-#define SHADOW_RAY_COUNT 128
-
-// The total number of all the vertices representing the shadow.
-// For the case we only have 1 layer, then we will just fill only 2/3 of it.
-#define SHADOW_VERTEX_COUNT (3 * SHADOW_RAY_COUNT)
-
-// The total number of indices used for drawing the shadow geometry as triangle strips.
-// Depending on the mode we are drawing, we can have 1 layer or 2 layers.
-// Therefore, we only build the longer index buffer.
-#define TWO_POLY_RING_SHADOW_INDEX_COUNT (4 * (SHADOW_RAY_COUNT + 1))
-#define ONE_POLY_RING_SHADOW_INDEX_COUNT (2 * (SHADOW_RAY_COUNT + 1))
-
-#define MAX_SHADOW_INDEX_COUNT TWO_POLY_RING_SHADOW_INDEX_COUNT
-
-#define SHADOW_MIN_CASTER_Z 0.001f
-
-#define MINIMAL_DELTA_THETA (M_PI / 180 / 1000)
-
-class ShadowTessellator {
-public:
-    static void tessellateAmbientShadow(bool isCasterOpaque, const Vector3* casterPolygon,
-                                        int casterVertexCount, const Vector3& centroid3d,
-                                        const Rect& casterBounds, const Rect& localClip, float maxZ,
-                                        VertexBuffer& shadowVertexBuffer);
-
-    static void tessellateSpotShadow(bool isCasterOpaque, const Vector3* casterPolygon,
-                                     int casterVertexCount, const Vector3& casterCentroid,
-                                     const mat4& receiverTransform, const Vector3& lightCenter,
-                                     int lightRadius, const Rect& casterBounds,
-                                     const Rect& localClip, VertexBuffer& shadowVertexBuffer);
-
-    static Vector2 centroid2d(const Vector2* poly, int polyLength);
-
-    static Vector2 calculateNormal(const Vector2& p1, const Vector2& p2);
-
-    static int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2, float divisor);
-
-    static void checkOverflow(int used, int total, const char* bufferName);
-};  // ShadowTessellator
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_SHADOW_TESSELLATOR_H
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
deleted file mode 100644
index e371ac8..0000000
--- a/libs/hwui/SpotShadow.cpp
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// The highest z value can't be higher than (CASTER_Z_CAP_RATIO * light.z)
-#define CASTER_Z_CAP_RATIO 0.95f
-
-// When there is no umbra, then just fake the umbra using
-// centroid * (1 - FAKE_UMBRA_SIZE_RATIO) + outline * FAKE_UMBRA_SIZE_RATIO
-#define FAKE_UMBRA_SIZE_RATIO 0.05f
-
-// When the polygon is about 90 vertices, the penumbra + umbra can reach 270 rays.
-// That is consider pretty fine tessllated polygon so far.
-// This is just to prevent using too much some memory when edge slicing is not
-// needed any more.
-#define FINE_TESSELLATED_POLYGON_RAY_NUMBER 270
-/**
- * Extra vertices for the corner for smoother corner.
- * Only for outer loop.
- * Note that we use such extra memory to avoid an extra loop.
- */
-// For half circle, we could add EXTRA_VERTEX_PER_PI vertices.
-// Set to 1 if we don't want to have any.
-#define SPOT_EXTRA_CORNER_VERTEX_PER_PI 18
-
-// For the whole polygon, the sum of all the deltas b/t normals is 2 * M_PI,
-// therefore, the maximum number of extra vertices will be twice bigger.
-#define SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER (2 * SPOT_EXTRA_CORNER_VERTEX_PER_PI)
-
-// For each RADIANS_DIVISOR, we would allocate one more vertex b/t the normals.
-#define SPOT_CORNER_RADIANS_DIVISOR (M_PI / SPOT_EXTRA_CORNER_VERTEX_PER_PI)
-
-#define PENUMBRA_ALPHA 0.0f
-#define UMBRA_ALPHA 1.0f
-
-#include "SpotShadow.h"
-
-#include "ShadowTessellator.h"
-#include "Vertex.h"
-#include "VertexBuffer.h"
-#include "utils/MathUtils.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <utils/Log.h>
-#include <algorithm>
-
-// TODO: After we settle down the new algorithm, we can remove the old one and
-// its utility functions.
-// Right now, we still need to keep it for comparison purpose and future expansion.
-namespace android {
-namespace uirenderer {
-
-static const float EPSILON = 1e-7;
-
-/**
- * For each polygon's vertex, the light center will project it to the receiver
- * as one of the outline vertex.
- * For each outline vertex, we need to store the position and normal.
- * Normal here is defined against the edge by the current vertex and the next vertex.
- */
-struct OutlineData {
-    Vector2 position;
-    Vector2 normal;
-    float radius;
-};
-
-/**
- * For each vertex, we need to keep track of its angle, whether it is penumbra or
- * umbra, and its corresponding vertex index.
- */
-struct SpotShadow::VertexAngleData {
-    // The angle to the vertex from the centroid.
-    float mAngle;
-    // True is the vertex comes from penumbra, otherwise it comes from umbra.
-    bool mIsPenumbra;
-    // The index of the vertex described by this data.
-    int mVertexIndex;
-    void set(float angle, bool isPenumbra, int index) {
-        mAngle = angle;
-        mIsPenumbra = isPenumbra;
-        mVertexIndex = index;
-    }
-};
-
-/**
- * Calculate the angle between and x and a y coordinate.
- * The atan2 range from -PI to PI.
- */
-static float angle(const Vector2& point, const Vector2& center) {
-    return atan2(point.y - center.y, point.x - center.x);
-}
-
-/**
- * Calculate the intersection of a ray with the line segment defined by two points.
- *
- * Returns a negative value in error conditions.
-
- * @param rayOrigin The start of the ray
- * @param dx The x vector of the ray
- * @param dy The y vector of the ray
- * @param p1 The first point defining the line segment
- * @param p2 The second point defining the line segment
- * @return The distance along the ray if it intersects with the line segment, negative if otherwise
- */
-static float rayIntersectPoints(const Vector2& rayOrigin, float dx, float dy, const Vector2& p1,
-                                const Vector2& p2) {
-    // The math below is derived from solving this formula, basically the
-    // intersection point should stay on both the ray and the edge of (p1, p2).
-    // solve([p1x+t*(p2x-p1x)=dx*t2+px,p1y+t*(p2y-p1y)=dy*t2+py],[t,t2]);
-
-    float divisor = (dx * (p1.y - p2.y) + dy * p2.x - dy * p1.x);
-    if (divisor == 0) return -1.0f;  // error, invalid divisor
-
-#if DEBUG_SHADOW
-    float interpVal = (dx * (p1.y - rayOrigin.y) + dy * rayOrigin.x - dy * p1.x) / divisor;
-    if (interpVal < 0 || interpVal > 1) {
-        ALOGW("rayIntersectPoints is hitting outside the segment %f", interpVal);
-    }
-#endif
-
-    float distance = (p1.x * (rayOrigin.y - p2.y) + p2.x * (p1.y - rayOrigin.y) +
-                      rayOrigin.x * (p2.y - p1.y)) /
-                     divisor;
-
-    return distance;  // may be negative in error cases
-}
-
-/**
- * Sort points by their X coordinates
- *
- * @param points the points as a Vector2 array.
- * @param pointsLength the number of vertices of the polygon.
- */
-void SpotShadow::xsort(Vector2* points, int pointsLength) {
-    auto cmp = [](const Vector2& a, const Vector2& b) -> bool { return a.x < b.x; };
-    std::sort(points, points + pointsLength, cmp);
-}
-
-/**
- * compute the convex hull of a collection of Points
- *
- * @param points the points as a Vector2 array.
- * @param pointsLength the number of vertices of the polygon.
- * @param retPoly pre allocated array of floats to put the vertices
- * @return the number of points in the polygon 0 if no intersection
- */
-int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) {
-    xsort(points, pointsLength);
-    int n = pointsLength;
-    Vector2 lUpper[n];
-    lUpper[0] = points[0];
-    lUpper[1] = points[1];
-
-    int lUpperSize = 2;
-
-    for (int i = 2; i < n; i++) {
-        lUpper[lUpperSize] = points[i];
-        lUpperSize++;
-
-        while (lUpperSize > 2 &&
-               !ccw(lUpper[lUpperSize - 3].x, lUpper[lUpperSize - 3].y, lUpper[lUpperSize - 2].x,
-                    lUpper[lUpperSize - 2].y, lUpper[lUpperSize - 1].x, lUpper[lUpperSize - 1].y)) {
-            // Remove the middle point of the three last
-            lUpper[lUpperSize - 2].x = lUpper[lUpperSize - 1].x;
-            lUpper[lUpperSize - 2].y = lUpper[lUpperSize - 1].y;
-            lUpperSize--;
-        }
-    }
-
-    Vector2 lLower[n];
-    lLower[0] = points[n - 1];
-    lLower[1] = points[n - 2];
-
-    int lLowerSize = 2;
-
-    for (int i = n - 3; i >= 0; i--) {
-        lLower[lLowerSize] = points[i];
-        lLowerSize++;
-
-        while (lLowerSize > 2 &&
-               !ccw(lLower[lLowerSize - 3].x, lLower[lLowerSize - 3].y, lLower[lLowerSize - 2].x,
-                    lLower[lLowerSize - 2].y, lLower[lLowerSize - 1].x, lLower[lLowerSize - 1].y)) {
-            // Remove the middle point of the three last
-            lLower[lLowerSize - 2] = lLower[lLowerSize - 1];
-            lLowerSize--;
-        }
-    }
-
-    // output points in CW ordering
-    const int total = lUpperSize + lLowerSize - 2;
-    int outIndex = total - 1;
-    for (int i = 0; i < lUpperSize; i++) {
-        retPoly[outIndex] = lUpper[i];
-        outIndex--;
-    }
-
-    for (int i = 1; i < lLowerSize - 1; i++) {
-        retPoly[outIndex] = lLower[i];
-        outIndex--;
-    }
-    // TODO: Add test harness which verify that all the points are inside the hull.
-    return total;
-}
-
-/**
- * Test whether the 3 points form a counter clockwise turn.
- *
- * @return true if a right hand turn
- */
-bool SpotShadow::ccw(float ax, float ay, float bx, float by, float cx, float cy) {
-    return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > EPSILON;
-}
-
-/**
- * Sort points about a center point
- *
- * @param poly The in and out polyogon as a Vector2 array.
- * @param polyLength The number of vertices of the polygon.
- * @param center the center ctr[0] = x , ctr[1] = y to sort around.
- */
-void SpotShadow::sort(Vector2* poly, int polyLength, const Vector2& center) {
-    quicksortCirc(poly, 0, polyLength - 1, center);
-}
-
-/**
- * Swap points pointed to by i and j
- */
-void SpotShadow::swap(Vector2* points, int i, int j) {
-    Vector2 temp = points[i];
-    points[i] = points[j];
-    points[j] = temp;
-}
-
-/**
- * quick sort implementation about the center.
- */
-void SpotShadow::quicksortCirc(Vector2* points, int low, int high, const Vector2& center) {
-    int i = low, j = high;
-    int p = low + (high - low) / 2;
-    float pivot = angle(points[p], center);
-    while (i <= j) {
-        while (angle(points[i], center) > pivot) {
-            i++;
-        }
-        while (angle(points[j], center) < pivot) {
-            j--;
-        }
-
-        if (i <= j) {
-            swap(points, i, j);
-            i++;
-            j--;
-        }
-    }
-    if (low < j) quicksortCirc(points, low, j, center);
-    if (i < high) quicksortCirc(points, i, high, center);
-}
-
-/**
- * Test whether a point is inside the polygon.
- *
- * @param testPoint the point to test
- * @param poly the polygon
- * @return true if the testPoint is inside the poly.
- */
-bool SpotShadow::testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len) {
-    bool c = false;
-    float testx = testPoint.x;
-    float testy = testPoint.y;
-    for (int i = 0, j = len - 1; i < len; j = i++) {
-        float startX = poly[j].x;
-        float startY = poly[j].y;
-        float endX = poly[i].x;
-        float endY = poly[i].y;
-
-        if (((endY > testy) != (startY > testy)) &&
-            (testx < (startX - endX) * (testy - endY) / (startY - endY) + endX)) {
-            c = !c;
-        }
-    }
-    return c;
-}
-
-/**
- * Reverse the polygon
- *
- * @param polygon the polygon as a Vector2 array
- * @param len the number of points of the polygon
- */
-void SpotShadow::reverse(Vector2* polygon, int len) {
-    int n = len / 2;
-    for (int i = 0; i < n; i++) {
-        Vector2 tmp = polygon[i];
-        int k = len - 1 - i;
-        polygon[i] = polygon[k];
-        polygon[k] = tmp;
-    }
-}
-
-/**
- * Compute a horizontal circular polygon about point (x , y , height) of radius
- * (size)
- *
- * @param points number of the points of the output polygon.
- * @param lightCenter the center of the light.
- * @param size the light size.
- * @param ret result polygon.
- */
-void SpotShadow::computeLightPolygon(int points, const Vector3& lightCenter, float size,
-                                     Vector3* ret) {
-    // TODO: Caching all the sin / cos values and store them in a look up table.
-    for (int i = 0; i < points; i++) {
-        float angle = 2 * i * M_PI / points;
-        ret[i].x = cosf(angle) * size + lightCenter.x;
-        ret[i].y = sinf(angle) * size + lightCenter.y;
-        ret[i].z = lightCenter.z;
-    }
-}
-
-/**
- * From light center, project one vertex to the z=0 surface and get the outline.
- *
- * @param outline The result which is the outline position.
- * @param lightCenter The center of light.
- * @param polyVertex The input polygon's vertex.
- *
- * @return float The ratio of (polygon.z / light.z - polygon.z)
- */
-float SpotShadow::projectCasterToOutline(Vector2& outline, const Vector3& lightCenter,
-                                         const Vector3& polyVertex) {
-    float lightToPolyZ = lightCenter.z - polyVertex.z;
-    float ratioZ = CASTER_Z_CAP_RATIO;
-    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::clamp(polyVertex.z / lightToPolyZ, 0.0f, CASTER_Z_CAP_RATIO);
-    }
-
-    outline.x = polyVertex.x - ratioZ * (lightCenter.x - polyVertex.x);
-    outline.y = polyVertex.y - ratioZ * (lightCenter.y - polyVertex.y);
-    return ratioZ;
-}
-
-/**
- * Generate the shadow spot light of shape lightPoly and a object poly
- *
- * @param isCasterOpaque whether the caster is opaque
- * @param lightCenter the center of the light
- * @param lightSize the radius of the light
- * @param poly x,y,z vertexes of a convex polygon that occludes the light source
- * @param polyLength number of vertexes of the occluding polygon
- * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
- *                            empty strip if error.
- */
-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;
-    }
-    if (CC_UNLIKELY(polyLength < 3)) {
-#if DEBUG_SHADOW
-        ALOGW("Invalid polygon length. No spot shadow!");
-#endif
-        return;
-    }
-    OutlineData outlineData[polyLength];
-    Vector2 outlineCentroid;
-    // Calculate the projected outline for each polygon's vertices from the light center.
-    //
-    //                       O     Light
-    //                      /
-    //                    /
-    //                   .     Polygon vertex
-    //                 /
-    //               /
-    //              O     Outline vertices
-    //
-    // Ratio = (Poly - Outline) / (Light - Poly)
-    // Outline.x = Poly.x - Ratio * (Light.x - Poly.x)
-    // Outline's radius / Light's radius = Ratio
-
-    // Compute the last outline vertex to make sure we can get the normal and outline
-    // in one single loop.
-    projectCasterToOutline(outlineData[polyLength - 1].position, lightCenter, poly[polyLength - 1]);
-
-    // Take the outline's polygon, calculate the normal for each outline edge.
-    int currentNormalIndex = polyLength - 1;
-    int nextNormalIndex = 0;
-
-    for (int i = 0; i < polyLength; i++) {
-        float ratioZ = projectCasterToOutline(outlineData[i].position, lightCenter, poly[i]);
-        outlineData[i].radius = ratioZ * lightSize;
-
-        outlineData[currentNormalIndex].normal = ShadowTessellator::calculateNormal(
-                outlineData[currentNormalIndex].position, outlineData[nextNormalIndex].position);
-        currentNormalIndex = (currentNormalIndex + 1) % polyLength;
-        nextNormalIndex++;
-    }
-
-    projectCasterToOutline(outlineCentroid, lightCenter, polyCentroid);
-
-    int penumbraIndex = 0;
-    // Then each polygon's vertex produce at minmal 2 penumbra vertices.
-    // Since the size can be dynamic here, we keep track of the size and update
-    // the real size at the end.
-    int allocatedPenumbraLength = 2 * polyLength + SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER;
-    Vector2 penumbra[allocatedPenumbraLength];
-    int totalExtraCornerSliceNumber = 0;
-
-    Vector2 umbra[polyLength];
-
-    // When centroid is covered by all circles from outline, then we consider
-    // the umbra is invalid, and we will tune down the shadow strength.
-    bool hasValidUmbra = true;
-    // We need the minimal of RaitoVI to decrease the spot shadow strength accordingly.
-    float minRaitoVI = FLT_MAX;
-
-    for (int i = 0; i < polyLength; i++) {
-        // Generate all the penumbra's vertices only using the (outline vertex + normal * radius)
-        // There is no guarantee that the penumbra is still convex, but for
-        // each outline vertex, it will connect to all its corresponding penumbra vertices as
-        // triangle fans. And for neighber penumbra vertex, it will be a trapezoid.
-        //
-        // Penumbra Vertices marked as Pi
-        // Outline Vertices marked as Vi
-        //                                            (P3)
-        //          (P2)                               |     ' (P4)
-        //   (P1)'   |                                 |   '
-        //         ' |                                 | '
-        // (P0)  ------------------------------------------------(P5)
-        //           | (V0)                            |(V1)
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //           |                                 |
-        //       (V3)-----------------------------------(V2)
-        int preNormalIndex = (i + polyLength - 1) % polyLength;
-
-        const Vector2& previousNormal = outlineData[preNormalIndex].normal;
-        const Vector2& currentNormal = outlineData[i].normal;
-
-        // Depending on how roundness we want for each corner, we can subdivide
-        // further here and/or introduce some heuristic to decide how much the
-        // subdivision should be.
-        int currentExtraSliceNumber = ShadowTessellator::getExtraVertexNumber(
-                previousNormal, currentNormal, SPOT_CORNER_RADIANS_DIVISOR);
-
-        int currentCornerSliceNumber = 1 + currentExtraSliceNumber;
-        totalExtraCornerSliceNumber += currentExtraSliceNumber;
-#if DEBUG_SHADOW
-        ALOGD("currentExtraSliceNumber should be %d", currentExtraSliceNumber);
-        ALOGD("currentCornerSliceNumber should be %d", currentCornerSliceNumber);
-        ALOGD("totalCornerSliceNumber is %d", totalExtraCornerSliceNumber);
-#endif
-        if (CC_UNLIKELY(totalExtraCornerSliceNumber > SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER)) {
-            currentCornerSliceNumber = 1;
-        }
-        for (int k = 0; k <= currentCornerSliceNumber; k++) {
-            Vector2 avgNormal =
-                    (previousNormal * (currentCornerSliceNumber - k) + currentNormal * k) /
-                    currentCornerSliceNumber;
-            avgNormal.normalize();
-            penumbra[penumbraIndex++] = outlineData[i].position + avgNormal * outlineData[i].radius;
-        }
-
-        // Compute the umbra by the intersection from the outline's centroid!
-        //
-        //       (V) ------------------------------------
-        //           |          '                       |
-        //           |         '                        |
-        //           |       ' (I)                      |
-        //           |    '                             |
-        //           | '             (C)                |
-        //           |                                  |
-        //           |                                  |
-        //           |                                  |
-        //           |                                  |
-        //           ------------------------------------
-        //
-        // Connect a line b/t the outline vertex (V) and the centroid (C), it will
-        // intersect with the outline vertex's circle at point (I).
-        // Now, ratioVI = VI / VC, ratioIC = IC / VC
-        // Then the intersetion point can be computed as Ixy = Vxy * ratioIC + Cxy * ratioVI;
-        //
-        // When all of the outline circles cover the the outline centroid, (like I is
-        // on the other side of C), there is no real umbra any more, so we just fake
-        // a small area around the centroid as the umbra, and tune down the spot
-        // shadow's umbra strength to simulate the effect the whole shadow will
-        // become lighter in this case.
-        // The ratio can be simulated by using the inverse of maximum of ratioVI for
-        // all (V).
-        float distOutline = (outlineData[i].position - outlineCentroid).length();
-        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;
-        }
-
-        float ratioVI = outlineData[i].radius / distOutline;
-        minRaitoVI = std::min(minRaitoVI, ratioVI);
-        if (ratioVI >= (1 - FAKE_UMBRA_SIZE_RATIO)) {
-            ratioVI = (1 - FAKE_UMBRA_SIZE_RATIO);
-        }
-        // When we know we don't have valid umbra, don't bother to compute the
-        // values below. But we can't skip the loop yet since we want to know the
-        // maximum ratio.
-        float ratioIC = 1 - ratioVI;
-        umbra[i] = outlineData[i].position * ratioIC + outlineCentroid * ratioVI;
-    }
-
-    hasValidUmbra = (minRaitoVI <= 1.0);
-    float shadowStrengthScale = 1.0;
-    if (!hasValidUmbra) {
-#if DEBUG_SHADOW
-        ALOGW("The object is too close to the light or too small, no real umbra!");
-#endif
-        for (int i = 0; i < polyLength; i++) {
-            umbra[i] = outlineData[i].position * FAKE_UMBRA_SIZE_RATIO +
-                       outlineCentroid * (1 - FAKE_UMBRA_SIZE_RATIO);
-        }
-        shadowStrengthScale = 1.0 / minRaitoVI;
-    }
-
-    int penumbraLength = penumbraIndex;
-    int umbraLength = polyLength;
-
-#if DEBUG_SHADOW
-    ALOGD("penumbraLength is %d , allocatedPenumbraLength %d", penumbraLength,
-          allocatedPenumbraLength);
-    dumpPolygon(poly, polyLength, "input poly");
-    dumpPolygon(penumbra, penumbraLength, "penumbra");
-    dumpPolygon(umbra, umbraLength, "umbra");
-    ALOGD("hasValidUmbra is %d and shadowStrengthScale is %f", hasValidUmbra, shadowStrengthScale);
-#endif
-
-    // The penumbra and umbra needs to be in convex shape to keep consistency
-    // and quality.
-    // Since we are still shooting rays to penumbra, it needs to be convex.
-    // Umbra can be represented as a fan from the centroid, but visually umbra
-    // looks nicer when it is convex.
-    Vector2 finalUmbra[umbraLength];
-    Vector2 finalPenumbra[penumbraLength];
-    int finalUmbraLength = hull(umbra, umbraLength, finalUmbra);
-    int finalPenumbraLength = hull(penumbra, penumbraLength, finalPenumbra);
-
-    generateTriangleStrip(isCasterOpaque, shadowStrengthScale, finalPenumbra, finalPenumbraLength,
-                          finalUmbra, finalUmbraLength, poly, polyLength, shadowTriangleStrip,
-                          outlineCentroid);
-}
-
-/**
- * This is only for experimental purpose.
- * After intersections are calculated, we could smooth the polygon if needed.
- * So far, we don't think it is more appealing yet.
- *
- * @param level The level of smoothness.
- * @param rays The total number of rays.
- * @param rayDist (In and Out) The distance for each ray.
- *
- */
-void SpotShadow::smoothPolygon(int level, int rays, float* rayDist) {
-    for (int k = 0; k < level; k++) {
-        for (int i = 0; i < rays; i++) {
-            float p1 = rayDist[(rays - 1 + i) % rays];
-            float p2 = rayDist[i];
-            float p3 = rayDist[(i + 1) % rays];
-            rayDist[i] = (p1 + p2 * 2 + p3) / 4;
-        }
-    }
-}
-
-// Index pair is meant for storing the tessellation information for the penumbra
-// area. One index must come from exterior tangent of the circles, the other one
-// must come from the interior tangent of the circles.
-struct IndexPair {
-    int outerIndex;
-    int innerIndex;
-};
-
-// For one penumbra vertex, find the cloest umbra vertex and return its index.
-inline int getClosestUmbraIndex(const Vector2& pivot, const Vector2* polygon, int polygonLength) {
-    float minLengthSquared = FLT_MAX;
-    int resultIndex = -1;
-    bool hasDecreased = false;
-    // Starting with some negative offset, assuming both umbra and penumbra are starting
-    // at the same angle, this can help to find the result faster.
-    // Normally, loop 3 times, we can find the closest point.
-    int offset = polygonLength - 2;
-    for (int i = 0; i < polygonLength; i++) {
-        int currentIndex = (i + offset) % polygonLength;
-        float currentLengthSquared = (pivot - polygon[currentIndex]).lengthSquared();
-        if (currentLengthSquared < minLengthSquared) {
-            if (minLengthSquared != FLT_MAX) {
-                hasDecreased = true;
-            }
-            minLengthSquared = currentLengthSquared;
-            resultIndex = currentIndex;
-        } else if (currentLengthSquared > minLengthSquared && hasDecreased) {
-            // Early break b/c we have found the closet one and now the length
-            // is increasing again.
-            break;
-        }
-    }
-    if (resultIndex == -1) {
-        ALOGE("resultIndex is -1, the polygon must be invalid!");
-        resultIndex = 0;
-    }
-    return resultIndex;
-}
-
-// Allow some epsilon here since the later ray intersection did allow for some small
-// floating point error, when the intersection point is slightly outside the segment.
-inline bool sameDirections(bool isPositiveCross, float a, float b) {
-    if (isPositiveCross) {
-        return a >= -EPSILON && b >= -EPSILON;
-    } else {
-        return a <= EPSILON && b <= EPSILON;
-    }
-}
-
-// Find the right polygon edge to shoot the ray at.
-inline int findPolyIndex(bool isPositiveCross, int startPolyIndex, const Vector2& umbraDir,
-                         const Vector2* polyToCentroid, int polyLength) {
-    // Make sure we loop with a bound.
-    for (int i = 0; i < polyLength; i++) {
-        int currentIndex = (i + startPolyIndex) % polyLength;
-        const Vector2& currentToCentroid = polyToCentroid[currentIndex];
-        const Vector2& nextToCentroid = polyToCentroid[(currentIndex + 1) % polyLength];
-
-        float currentCrossUmbra = currentToCentroid.cross(umbraDir);
-        float umbraCrossNext = umbraDir.cross(nextToCentroid);
-        if (sameDirections(isPositiveCross, currentCrossUmbra, umbraCrossNext)) {
-#if DEBUG_SHADOW
-            ALOGD("findPolyIndex loop %d times , index %d", i, currentIndex);
-#endif
-            return currentIndex;
-        }
-    }
-    LOG_ALWAYS_FATAL("Can't find the right polygon's edge from startPolyIndex %d", startPolyIndex);
-    return -1;
-}
-
-// Generate the index pair for penumbra / umbra vertices, and more penumbra vertices
-// if needed.
-inline void genNewPenumbraAndPairWithUmbra(const Vector2* penumbra, int penumbraLength,
-                                           const Vector2* umbra, int umbraLength,
-                                           Vector2* newPenumbra, int& newPenumbraIndex,
-                                           IndexPair* verticesPair, int& verticesPairIndex) {
-    // In order to keep everything in just one loop, we need to pre-compute the
-    // closest umbra vertex for the last penumbra vertex.
-    int previousClosestUmbraIndex =
-            getClosestUmbraIndex(penumbra[penumbraLength - 1], umbra, umbraLength);
-    for (int i = 0; i < penumbraLength; i++) {
-        const Vector2& currentPenumbraVertex = penumbra[i];
-        // For current penumbra vertex, starting from previousClosestUmbraIndex,
-        // then check the next one until the distance increase.
-        // The last one before the increase is the umbra vertex we need to pair with.
-        float currentLengthSquared =
-                (currentPenumbraVertex - umbra[previousClosestUmbraIndex]).lengthSquared();
-        int currentClosestUmbraIndex = previousClosestUmbraIndex;
-        int indexDelta = 0;
-        for (int j = 1; j < umbraLength; j++) {
-            int newUmbraIndex = (previousClosestUmbraIndex + j) % umbraLength;
-            float newLengthSquared = (currentPenumbraVertex - umbra[newUmbraIndex]).lengthSquared();
-            if (newLengthSquared > currentLengthSquared) {
-                // currentClosestUmbraIndex is the umbra vertex's index which has
-                // currently found smallest distance, so we can simply break here.
-                break;
-            } else {
-                currentLengthSquared = newLengthSquared;
-                indexDelta++;
-                currentClosestUmbraIndex = newUmbraIndex;
-            }
-        }
-
-        if (indexDelta > 1) {
-            // For those umbra don't have  penumbra, generate new penumbra vertices by
-            // interpolation.
-            //
-            // Assuming Pi for penumbra vertices, and Ui for umbra vertices.
-            // In the case like below P1 paired with U1 and P2 paired with  U5.
-            // U2 to U4 are unpaired umbra vertices.
-            //
-            // P1                                        P2
-            // |                                          |
-            // U1     U2                   U3     U4     U5
-            //
-            // We will need to generate 3 more penumbra vertices P1.1, P1.2, P1.3
-            // to pair with U2 to U4.
-            //
-            // P1     P1.1                P1.2   P1.3    P2
-            // |       |                   |      |      |
-            // U1     U2                   U3     U4     U5
-            //
-            // That distance ratio b/t Ui to U1 and Ui to U5 decides its paired penumbra
-            // vertex's location.
-            int newPenumbraNumber = indexDelta - 1;
-
-            float accumulatedDeltaLength[indexDelta];
-            float totalDeltaLength = 0;
-
-            // To save time, cache the previous umbra vertex info outside the loop
-            // and update each loop.
-            Vector2 previousClosestUmbra = umbra[previousClosestUmbraIndex];
-            Vector2 skippedUmbra;
-            // Use umbra data to precompute the length b/t unpaired umbra vertices,
-            // and its ratio against the total length.
-            for (int k = 0; k < indexDelta; k++) {
-                int skippedUmbraIndex = (previousClosestUmbraIndex + k + 1) % umbraLength;
-                skippedUmbra = umbra[skippedUmbraIndex];
-                float currentDeltaLength = (skippedUmbra - previousClosestUmbra).length();
-
-                totalDeltaLength += currentDeltaLength;
-                accumulatedDeltaLength[k] = totalDeltaLength;
-
-                previousClosestUmbra = skippedUmbra;
-            }
-
-            const Vector2& previousPenumbra = penumbra[(i + penumbraLength - 1) % penumbraLength];
-            // Then for each unpaired umbra vertex, create a new penumbra by the ratio,
-            // and pair them togehter.
-            for (int k = 0; k < newPenumbraNumber; k++) {
-                float weightForCurrentPenumbra = 1.0f;
-                if (totalDeltaLength != 0.0f) {
-                    weightForCurrentPenumbra = accumulatedDeltaLength[k] / totalDeltaLength;
-                }
-                float weightForPreviousPenumbra = 1.0f - weightForCurrentPenumbra;
-
-                Vector2 interpolatedPenumbra = currentPenumbraVertex * weightForCurrentPenumbra +
-                                               previousPenumbra * weightForPreviousPenumbra;
-
-                int skippedUmbraIndex = (previousClosestUmbraIndex + k + 1) % umbraLength;
-                verticesPair[verticesPairIndex].outerIndex = newPenumbraIndex;
-                verticesPair[verticesPairIndex].innerIndex = skippedUmbraIndex;
-                verticesPairIndex++;
-                newPenumbra[newPenumbraIndex++] = interpolatedPenumbra;
-            }
-        }
-        verticesPair[verticesPairIndex].outerIndex = newPenumbraIndex;
-        verticesPair[verticesPairIndex].innerIndex = currentClosestUmbraIndex;
-        verticesPairIndex++;
-        newPenumbra[newPenumbraIndex++] = currentPenumbraVertex;
-
-        previousClosestUmbraIndex = currentClosestUmbraIndex;
-    }
-}
-
-// Precompute all the polygon's vector, return true if the reference cross product is positive.
-inline bool genPolyToCentroid(const Vector2* poly2d, int polyLength, const Vector2& centroid,
-                              Vector2* polyToCentroid) {
-    for (int j = 0; j < polyLength; j++) {
-        polyToCentroid[j] = poly2d[j] - centroid;
-        // Normalize these vectors such that we can use epsilon comparison after
-        // computing their cross products with another normalized vector.
-        polyToCentroid[j].normalize();
-    }
-    float refCrossProduct = 0;
-    for (int j = 0; j < polyLength; j++) {
-        refCrossProduct = polyToCentroid[j].cross(polyToCentroid[(j + 1) % polyLength]);
-        if (refCrossProduct != 0) {
-            break;
-        }
-    }
-
-    return refCrossProduct > 0;
-}
-
-// For one umbra vertex, shoot an ray from centroid to it.
-// If the ray hit the polygon first, then return the intersection point as the
-// closer vertex.
-inline Vector2 getCloserVertex(const Vector2& umbraVertex, const Vector2& centroid,
-                               const Vector2* poly2d, int polyLength, const Vector2* polyToCentroid,
-                               bool isPositiveCross, int& previousPolyIndex) {
-    Vector2 umbraToCentroid = umbraVertex - centroid;
-    float distanceToUmbra = umbraToCentroid.length();
-    umbraToCentroid = umbraToCentroid / distanceToUmbra;
-
-    // previousPolyIndex is updated for each item such that we can minimize the
-    // looping inside findPolyIndex();
-    previousPolyIndex = findPolyIndex(isPositiveCross, previousPolyIndex, umbraToCentroid,
-                                      polyToCentroid, polyLength);
-
-    float dx = umbraToCentroid.x;
-    float dy = umbraToCentroid.y;
-    float distanceToIntersectPoly =
-            rayIntersectPoints(centroid, dx, dy, poly2d[previousPolyIndex],
-                               poly2d[(previousPolyIndex + 1) % polyLength]);
-    if (distanceToIntersectPoly < 0) {
-        distanceToIntersectPoly = 0;
-    }
-
-    // Pick the closer one as the occluded area vertex.
-    Vector2 closerVertex;
-    if (distanceToIntersectPoly < distanceToUmbra) {
-        closerVertex.x = centroid.x + dx * distanceToIntersectPoly;
-        closerVertex.y = centroid.y + dy * distanceToIntersectPoly;
-    } else {
-        closerVertex = umbraVertex;
-    }
-
-    return closerVertex;
-}
-
-/**
- * Generate a triangle strip given two convex polygon
-**/
-void SpotShadow::generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
-                                       Vector2* penumbra, int penumbraLength, Vector2* umbra,
-                                       int umbraLength, const Vector3* poly, int polyLength,
-                                       VertexBuffer& shadowTriangleStrip, const Vector2& centroid) {
-    bool hasOccludedUmbraArea = false;
-    Vector2 poly2d[polyLength];
-
-    if (isCasterOpaque) {
-        for (int i = 0; i < polyLength; i++) {
-            poly2d[i].x = poly[i].x;
-            poly2d[i].y = poly[i].y;
-        }
-        // Make sure the centroid is inside the umbra, otherwise, fall back to the
-        // approach as if there is no occluded umbra area.
-        if (testPointInsidePolygon(centroid, poly2d, polyLength)) {
-            hasOccludedUmbraArea = true;
-        }
-    }
-
-    // For each penumbra vertex, find its corresponding closest umbra vertex index.
-    //
-    // Penumbra Vertices marked as Pi
-    // Umbra Vertices marked as Ui
-    //                                            (P3)
-    //          (P2)                               |     ' (P4)
-    //   (P1)'   |                                 |   '
-    //         ' |                                 | '
-    // (P0)  ------------------------------------------------(P5)
-    //           | (U0)                            |(U1)
-    //           |                                 |
-    //           |                                 |(U2)     (P5.1)
-    //           |                                 |
-    //           |                                 |
-    //           |                                 |
-    //           |                                 |
-    //           |                                 |
-    //           |                                 |
-    //       (U4)-----------------------------------(U3)      (P6)
-    //
-    // At least, like P0, P1, P2, they will find the matching umbra as U0.
-    // If we jump over some umbra vertex without matching penumbra vertex, then
-    // we will generate some new penumbra vertex by interpolation. Like P6 is
-    // matching U3, but U2 is not matched with any penumbra vertex.
-    // So interpolate P5.1 out and match U2.
-    // In this way, every umbra vertex will have a matching penumbra vertex.
-    //
-    // The total pair number can be as high as umbraLength + penumbraLength.
-    const int maxNewPenumbraLength = umbraLength + penumbraLength;
-    IndexPair verticesPair[maxNewPenumbraLength];
-    int verticesPairIndex = 0;
-
-    // Cache all the existing penumbra vertices and newly interpolated vertices into a
-    // a new array.
-    Vector2 newPenumbra[maxNewPenumbraLength];
-    int newPenumbraIndex = 0;
-
-    // For each penumbra vertex, find its closet umbra vertex by comparing the
-    // neighbor umbra vertices.
-    genNewPenumbraAndPairWithUmbra(penumbra, penumbraLength, umbra, umbraLength, newPenumbra,
-                                   newPenumbraIndex, verticesPair, verticesPairIndex);
-    ShadowTessellator::checkOverflow(verticesPairIndex, maxNewPenumbraLength, "Spot pair");
-    ShadowTessellator::checkOverflow(newPenumbraIndex, maxNewPenumbraLength, "Spot new penumbra");
-#if DEBUG_SHADOW
-    for (int i = 0; i < umbraLength; i++) {
-        ALOGD("umbra i %d,  [%f, %f]", i, umbra[i].x, umbra[i].y);
-    }
-    for (int i = 0; i < newPenumbraIndex; i++) {
-        ALOGD("new penumbra i %d,  [%f, %f]", i, newPenumbra[i].x, newPenumbra[i].y);
-    }
-    for (int i = 0; i < verticesPairIndex; i++) {
-        ALOGD("index i %d,  [%d, %d]", i, verticesPair[i].outerIndex, verticesPair[i].innerIndex);
-    }
-#endif
-
-    // For the size of vertex buffer, we need 3 rings, one has newPenumbraSize,
-    // one has umbraLength, the last one has at most umbraLength.
-    //
-    // For the size of index buffer, the umbra area needs (2 * umbraLength + 2).
-    // The penumbra one can vary a bit, but it is bounded by (2 * verticesPairIndex + 2).
-    // And 2 more for jumping between penumbra to umbra.
-    const int newPenumbraLength = newPenumbraIndex;
-    const int totalVertexCount = newPenumbraLength + umbraLength * 2;
-    const int totalIndexCount = 2 * umbraLength + 2 * verticesPairIndex + 6;
-    AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(totalVertexCount);
-    uint16_t* indexBuffer = shadowTriangleStrip.allocIndices<uint16_t>(totalIndexCount);
-    int vertexBufferIndex = 0;
-    int indexBufferIndex = 0;
-
-    // Fill the IB and VB for the penumbra area.
-    for (int i = 0; i < newPenumbraLength; i++) {
-        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], newPenumbra[i].x, newPenumbra[i].y,
-                         PENUMBRA_ALPHA);
-    }
-    // Since the umbra can be a faked one when the occluder is too high, the umbra should be lighter
-    // in this case.
-    float scaledUmbraAlpha = UMBRA_ALPHA * shadowStrengthScale;
-
-    for (int i = 0; i < umbraLength; i++) {
-        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], umbra[i].x, umbra[i].y,
-                         scaledUmbraAlpha);
-    }
-
-    for (int i = 0; i < verticesPairIndex; i++) {
-        indexBuffer[indexBufferIndex++] = verticesPair[i].outerIndex;
-        // All umbra index need to be offseted by newPenumbraSize.
-        indexBuffer[indexBufferIndex++] = verticesPair[i].innerIndex + newPenumbraLength;
-    }
-    indexBuffer[indexBufferIndex++] = verticesPair[0].outerIndex;
-    indexBuffer[indexBufferIndex++] = verticesPair[0].innerIndex + newPenumbraLength;
-
-    // Now fill the IB and VB for the umbra area.
-    // First duplicated the index from previous strip and the first one for the
-    // degenerated triangles.
-    indexBuffer[indexBufferIndex] = indexBuffer[indexBufferIndex - 1];
-    indexBufferIndex++;
-    indexBuffer[indexBufferIndex++] = newPenumbraLength + 0;
-    // Save the first VB index for umbra area in order to close the loop.
-    int savedStartIndex = vertexBufferIndex;
-
-    if (hasOccludedUmbraArea) {
-        // Precompute all the polygon's vector, and the reference cross product,
-        // in order to find the right polygon edge for the ray to intersect.
-        Vector2 polyToCentroid[polyLength];
-        bool isPositiveCross = genPolyToCentroid(poly2d, polyLength, centroid, polyToCentroid);
-
-        // Because both the umbra and polygon are going in the same direction,
-        // we can save the previous polygon index to make sure we have less polygon
-        // vertex to compute for each ray.
-        int previousPolyIndex = 0;
-        for (int i = 0; i < umbraLength; i++) {
-            // Shoot a ray from centroid to each umbra vertices and pick the one with
-            // shorter distance to the centroid, b/t the umbra vertex or the intersection point.
-            Vector2 closerVertex =
-                    getCloserVertex(umbra[i], centroid, poly2d, polyLength, polyToCentroid,
-                                    isPositiveCross, previousPolyIndex);
-
-            // We already stored the umbra vertices, just need to add the occlued umbra's ones.
-            indexBuffer[indexBufferIndex++] = newPenumbraLength + i;
-            indexBuffer[indexBufferIndex++] = vertexBufferIndex;
-            AlphaVertex::set(&shadowVertices[vertexBufferIndex++], closerVertex.x, closerVertex.y,
-                             scaledUmbraAlpha);
-        }
-    } else {
-        // If there is no occluded umbra at all, then draw the triangle fan
-        // starting from the centroid to all umbra vertices.
-        int lastCentroidIndex = vertexBufferIndex;
-        AlphaVertex::set(&shadowVertices[vertexBufferIndex++], centroid.x, centroid.y,
-                         scaledUmbraAlpha);
-        for (int i = 0; i < umbraLength; i++) {
-            indexBuffer[indexBufferIndex++] = newPenumbraLength + i;
-            indexBuffer[indexBufferIndex++] = lastCentroidIndex;
-        }
-    }
-    // Closing the umbra area triangle's loop here.
-    indexBuffer[indexBufferIndex++] = newPenumbraLength;
-    indexBuffer[indexBufferIndex++] = savedStartIndex;
-
-    // At the end, update the real index and vertex buffer size.
-    shadowTriangleStrip.updateVertexCount(vertexBufferIndex);
-    shadowTriangleStrip.updateIndexCount(indexBufferIndex);
-    ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Spot Vertex Buffer");
-    ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Spot Index Buffer");
-
-    shadowTriangleStrip.setMeshFeatureFlags(VertexBuffer::kAlpha | VertexBuffer::kIndices);
-    shadowTriangleStrip.computeBounds<AlphaVertex>();
-}
-
-#if DEBUG_SHADOW
-
-#define TEST_POINT_NUMBER 128
-/**
- * Calculate the bounds for generating random test points.
- */
-void SpotShadow::updateBound(const Vector2 inVector, Vector2& lowerBound, Vector2& upperBound) {
-    if (inVector.x < lowerBound.x) {
-        lowerBound.x = inVector.x;
-    }
-
-    if (inVector.y < lowerBound.y) {
-        lowerBound.y = inVector.y;
-    }
-
-    if (inVector.x > upperBound.x) {
-        upperBound.x = inVector.x;
-    }
-
-    if (inVector.y > upperBound.y) {
-        upperBound.y = inVector.y;
-    }
-}
-
-/**
- * For debug purpose, when things go wrong, dump the whole polygon data.
- */
-void SpotShadow::dumpPolygon(const Vector2* poly, int polyLength, const char* polyName) {
-    for (int i = 0; i < polyLength; i++) {
-        ALOGD("polygon %s i %d x %f y %f", polyName, i, poly[i].x, poly[i].y);
-    }
-}
-
-/**
- * For debug purpose, when things go wrong, dump the whole polygon data.
- */
-void SpotShadow::dumpPolygon(const Vector3* poly, int polyLength, const char* polyName) {
-    for (int i = 0; i < polyLength; i++) {
-        ALOGD("polygon %s i %d x %f y %f z %f", polyName, i, poly[i].x, poly[i].y, poly[i].z);
-    }
-}
-
-/**
- * Test whether the polygon is convex.
- */
-bool SpotShadow::testConvex(const Vector2* polygon, int polygonLength, const char* name) {
-    bool isConvex = true;
-    for (int i = 0; i < polygonLength; i++) {
-        Vector2 start = polygon[i];
-        Vector2 middle = polygon[(i + 1) % polygonLength];
-        Vector2 end = polygon[(i + 2) % polygonLength];
-
-        float delta = (float(middle.x) - start.x) * (float(end.y) - start.y) -
-                      (float(middle.y) - start.y) * (float(end.x) - start.x);
-        bool isCCWOrCoLinear = (delta >= EPSILON);
-
-        if (isCCWOrCoLinear) {
-            ALOGW("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f),"
-                  "middle (x %f, y %f) and end (x %f, y %f) , delta is %f !!!",
-                  name, start.x, start.y, middle.x, middle.y, end.x, end.y, delta);
-            isConvex = false;
-            break;
-        }
-    }
-    return isConvex;
-}
-
-/**
- * Test whether or not the polygon (intersection) is within the 2 input polygons.
- * Using Marte Carlo method, we generate a random point, and if it is inside the
- * intersection, then it must be inside both source polygons.
- */
-void SpotShadow::testIntersection(const Vector2* poly1, int poly1Length, const Vector2* poly2,
-                                  int poly2Length, const Vector2* intersection,
-                                  int intersectionLength) {
-    // Find the min and max of x and y.
-    Vector2 lowerBound = {FLT_MAX, FLT_MAX};
-    Vector2 upperBound = {-FLT_MAX, -FLT_MAX};
-    for (int i = 0; i < poly1Length; i++) {
-        updateBound(poly1[i], lowerBound, upperBound);
-    }
-    for (int i = 0; i < poly2Length; i++) {
-        updateBound(poly2[i], lowerBound, upperBound);
-    }
-
-    bool dumpPoly = false;
-    for (int k = 0; k < TEST_POINT_NUMBER; k++) {
-        // Generate a random point between minX, minY and maxX, maxY.
-        float randomX = rand() / float(RAND_MAX);
-        float randomY = rand() / float(RAND_MAX);
-
-        Vector2 testPoint;
-        testPoint.x = lowerBound.x + randomX * (upperBound.x - lowerBound.x);
-        testPoint.y = lowerBound.y + randomY * (upperBound.y - lowerBound.y);
-
-        // If the random point is in both poly 1 and 2, then it must be intersection.
-        if (testPointInsidePolygon(testPoint, intersection, intersectionLength)) {
-            if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) {
-                dumpPoly = true;
-                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
-                      " not in the poly1",
-                      testPoint.x, testPoint.y);
-            }
-
-            if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) {
-                dumpPoly = true;
-                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
-                      " not in the poly2",
-                      testPoint.x, testPoint.y);
-            }
-        }
-    }
-
-    if (dumpPoly) {
-        dumpPolygon(intersection, intersectionLength, "intersection");
-        for (int i = 1; i < intersectionLength; i++) {
-            Vector2 delta = intersection[i] - intersection[i - 1];
-            ALOGD("Intersetion i, %d Vs i-1 is delta %f", i, delta.lengthSquared());
-        }
-
-        dumpPolygon(poly1, poly1Length, "poly 1");
-        dumpPolygon(poly2, poly2Length, "poly 2");
-    }
-}
-#endif
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
deleted file mode 100644
index 8476be7..0000000
--- a/libs/hwui/SpotShadow.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_SPOT_SHADOW_H
-#define ANDROID_HWUI_SPOT_SHADOW_H
-
-#include "Debug.h"
-#include "Vector.h"
-
-namespace android {
-namespace uirenderer {
-
-class VertexBuffer;
-
-class SpotShadow {
-public:
-    static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter, float lightSize,
-                                 const Vector3* poly, int polyLength, const Vector3& polyCentroid,
-                                 VertexBuffer& retstrips);
-
-private:
-    struct VertexAngleData;
-
-    static float projectCasterToOutline(Vector2& outline, const Vector3& lightCenter,
-                                        const Vector3& polyVertex);
-
-    static void computeLightPolygon(int points, const Vector3& lightCenter, float size,
-                                    Vector3* ret);
-
-    static void smoothPolygon(int level, int rays, float* rayDist);
-    static float rayIntersectPoly(const Vector2* poly, int polyLength, const Vector2& point,
-                                  float dx, float dy);
-
-    static void xsort(Vector2* points, int pointsLength);
-    static int hull(Vector2* points, int pointsLength, Vector2* retPoly);
-    static bool ccw(float ax, float ay, float bx, float by, float cx, float cy);
-    static void sort(Vector2* poly, int polyLength, const Vector2& center);
-
-    static void swap(Vector2* points, int i, int j);
-    static void quicksortCirc(Vector2* points, int low, int high, const Vector2& center);
-    static void quicksortX(Vector2* points, int low, int high);
-
-    static bool testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len);
-    static void reverse(Vector2* polygon, int len);
-
-    static void generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
-                                      Vector2* penumbra, int penumbraLength, Vector2* umbra,
-                                      int umbraLength, const Vector3* poly, int polyLength,
-                                      VertexBuffer& retstrips, const Vector2& centroid);
-
-#if DEBUG_SHADOW
-    static bool testConvex(const Vector2* polygon, int polygonLength, const char* name);
-    static void testIntersection(const Vector2* poly1, int poly1Length, const Vector2* poly2,
-                                 int poly2Length, const Vector2* intersection,
-                                 int intersectionLength);
-    static void updateBound(const Vector2 inVector, Vector2& lowerBound, Vector2& upperBound);
-    static void dumpPolygon(const Vector2* poly, int polyLength, const char* polyName);
-    static void dumpPolygon(const Vector3* poly, int polyLength, const char* polyName);
-#endif
-
-};  // SpotShadow
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_SPOT_SHADOW_H
diff --git a/libs/hwui/renderstate/Blend.cpp b/libs/hwui/renderstate/Blend.cpp
index 5bef01c..08e18e0 100644
--- a/libs/hwui/renderstate/Blend.cpp
+++ b/libs/hwui/renderstate/Blend.cpp
@@ -16,8 +16,6 @@
 #include <renderstate/Blend.h>
 #include "Program.h"
 
-#include "ShadowTessellator.h"
-
 namespace android {
 namespace uirenderer {
 
