Merge "Merge "Fix NPE finding target activity after recents animation controller crash" into pi-dev am: ebcfc4bb79 am: 4790ae379d"
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 90cc7bb..0933e98 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -15,9 +15,6 @@
 #include <cutils/ashmem.h>
 #include <hwui/Canvas.h>
 
-#include <Caches.h>
-#include <TextureCache.h>
-
 using namespace android;
 
 void doThrowNPE(JNIEnv* env) {
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 97abd82..aedb6ac 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -28,7 +28,6 @@
 #include "SkPathOps.h"
 #include "SkGeometry.h" // WARNING: Internal Skia Header
 
-#include <Caches.h>
 #include <vector>
 #include <map>
 
@@ -38,10 +37,6 @@
 public:
 
     static void finalizer(SkPath* obj) {
-        // Purge entries from the HWUI path cache if this path's data is unique
-        if (obj->unique() && android::uirenderer::Caches::hasInstance()) {
-            android::uirenderer::Caches::getInstance().pathCache.removeDeferred(obj);
-        }
         delete obj;
     }
 
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 3495c4f..d716844 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -211,14 +211,12 @@
         "DeferredLayerUpdater.cpp",
         "DeviceInfo.cpp",
         "DisplayList.cpp",
-        "FboCache.cpp",
         "FrameBuilder.cpp",
         "FrameInfo.cpp",
         "FrameInfoVisualizer.cpp",
         "GlLayer.cpp",
         "GlopBuilder.cpp",
         "GpuMemoryTracker.cpp",
-        "GradientCache.cpp",
         "Image.cpp",
         "Interpolator.cpp",
         "JankTracker.cpp",
@@ -229,8 +227,6 @@
         "OpDumper.cpp",
         "EglReadback.cpp",
         "Patch.cpp",
-        "PatchCache.cpp",
-        "PathCache.cpp",
         "PathParser.cpp",
         "PathTessellator.cpp",
         "PixelBuffer.cpp",
@@ -238,12 +234,10 @@
         "ProfileDataContainer.cpp",
         "ProfileRenderer.cpp",
         "Program.cpp",
-        "ProgramCache.cpp",
         "Properties.cpp",
         "PropertyValuesAnimatorSet.cpp",
         "PropertyValuesHolder.cpp",
         "RecordingCanvas.cpp",
-        "RenderBufferCache.cpp",
         "RenderNode.cpp",
         "RenderProperties.cpp",
         "ResourceCache.cpp",
@@ -253,9 +247,7 @@
         "SkiaShader.cpp",
         "Snapshot.cpp",
         "SpotShadow.cpp",
-        "TessellationCache.cpp",
         "Texture.cpp",
-        "TextureCache.cpp",
         "VectorDrawable.cpp",
         "VkLayer.cpp",
         "protos/graphicsstats.proto",
@@ -411,7 +403,6 @@
         "tests/microbench/LinearAllocatorBench.cpp",
         "tests/microbench/PathParserBench.cpp",
         "tests/microbench/RenderNodeBench.cpp",
-        "tests/microbench/ShadowBench.cpp",
         "tests/microbench/TaskManagerBench.cpp",
     ],
 }
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 2c7aab8..1f931ed 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -36,153 +36,14 @@
 namespace android {
 namespace uirenderer {
 
-static void storeTexturedRect(TextureVertex* vertices, const Rect& bounds) {
-    vertices[0] = {bounds.left, bounds.top, 0, 0};
-    vertices[1] = {bounds.right, bounds.top, 1, 0};
-    vertices[2] = {bounds.left, bounds.bottom, 0, 1};
-    vertices[3] = {bounds.right, bounds.bottom, 1, 1};
-}
-
 void BakedOpDispatcher::onMergedBitmapOps(BakedOpRenderer& renderer,
                                           const MergedBakedOpList& opList) {
-    const BakedOpState& firstState = *(opList.states[0]);
-    Bitmap* bitmap = (static_cast<const BitmapOp*>(opList.states[0]->op))->bitmap;
-
-    Texture* texture = renderer.caches().textureCache.get(bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    TextureVertex vertices[opList.count * 4];
-    for (size_t i = 0; i < opList.count; i++) {
-        const BakedOpState& state = *(opList.states[i]);
-        TextureVertex* rectVerts = &vertices[i * 4];
-
-        // calculate unclipped bounds, since they'll determine texture coordinates
-        Rect opBounds = state.op->unmappedBounds;
-        state.computedState.transform.mapRect(opBounds);
-        if (CC_LIKELY(state.computedState.transform.isPureTranslate())) {
-            // pure translate, so snap (same behavior as onBitmapOp)
-            opBounds.snapToPixelBoundaries();
-        }
-        storeTexturedRect(rectVerts, opBounds);
-        renderer.dirtyRenderTarget(opBounds);
-    }
-
-    const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
-                                         ? TextureFillFlags::IsAlphaMaskTexture
-                                         : TextureFillFlags::None;
-    Glop glop;
-    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-            .setRoundRectClipState(firstState.roundRectClipState)
-            .setMeshTexturedIndexedQuads(vertices, opList.count * 6)
-            .setFillTexturePaint(*texture, textureFillFlags, firstState.op->paint, firstState.alpha)
-            .setTransform(Matrix4::identity(), TransformFlags::None)
-            .setModelViewIdentityEmptyBounds()
-            .build();
-    ClipRect renderTargetClip(opList.clip);
-    const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
-    renderer.renderGlop(nullptr, clip, glop);
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onMergedPatchOps(BakedOpRenderer& renderer,
                                          const MergedBakedOpList& opList) {
-    const PatchOp& firstOp = *(static_cast<const PatchOp*>(opList.states[0]->op));
-    const BakedOpState& firstState = *(opList.states[0]);
-
-    // Batches will usually contain a small number of items so it's
-    // worth performing a first iteration to count the exact number
-    // of vertices we need in the new mesh
-    uint32_t totalVertices = 0;
-
-    for (size_t i = 0; i < opList.count; i++) {
-        const PatchOp& op = *(static_cast<const PatchOp*>(opList.states[i]->op));
-
-        // TODO: cache mesh lookups
-        const Patch* opMesh = renderer.caches().patchCache.get(
-                op.bitmap->width(), op.bitmap->height(), op.unmappedBounds.getWidth(),
-                op.unmappedBounds.getHeight(), op.patch);
-        totalVertices += opMesh->verticesCount;
-    }
-
-    const bool dirtyRenderTarget = renderer.offscreenRenderTarget();
-
-    uint32_t indexCount = 0;
-
-    TextureVertex vertices[totalVertices];
-    TextureVertex* vertex = &vertices[0];
-    // Create a mesh that contains the transformed vertices for all the
-    // 9-patch objects that are part of the batch. Note that onDefer()
-    // enforces ops drawn by this function to have a pure translate or
-    // identity matrix
-    for (size_t i = 0; i < opList.count; i++) {
-        const PatchOp& op = *(static_cast<const PatchOp*>(opList.states[i]->op));
-        const BakedOpState& state = *opList.states[i];
-
-        // TODO: cache mesh lookups
-        const Patch* opMesh = renderer.caches().patchCache.get(
-                op.bitmap->width(), op.bitmap->height(), op.unmappedBounds.getWidth(),
-                op.unmappedBounds.getHeight(), op.patch);
-
-        uint32_t vertexCount = opMesh->verticesCount;
-        if (vertexCount == 0) continue;
-
-        // We use the bounds to know where to translate our vertices
-        // Using patchOp->state.mBounds wouldn't work because these
-        // bounds are clipped
-        const float tx = floorf(state.computedState.transform.getTranslateX() +
-                                op.unmappedBounds.left + 0.5f);
-        const float ty = floorf(state.computedState.transform.getTranslateY() +
-                                op.unmappedBounds.top + 0.5f);
-
-        // Copy & transform all the vertices for the current operation
-        TextureVertex* opVertices = opMesh->vertices.get();
-        for (uint32_t j = 0; j < vertexCount; j++, opVertices++) {
-            TextureVertex::set(vertex++, opVertices->x + tx, opVertices->y + ty, opVertices->u,
-                               opVertices->v);
-        }
-
-        // Dirty the current layer if possible. When the 9-patch does not
-        // contain empty quads we can take a shortcut and simply set the
-        // dirty rect to the object's bounds.
-        if (dirtyRenderTarget) {
-            if (!opMesh->hasEmptyQuads) {
-                renderer.dirtyRenderTarget(Rect(tx, ty, tx + op.unmappedBounds.getWidth(),
-                                                ty + op.unmappedBounds.getHeight()));
-            } else {
-                const size_t count = opMesh->quads.size();
-                for (size_t i = 0; i < count; i++) {
-                    const Rect& quadBounds = opMesh->quads[i];
-                    const float x = tx + quadBounds.left;
-                    const float y = ty + quadBounds.top;
-                    renderer.dirtyRenderTarget(
-                            Rect(x, y, x + quadBounds.getWidth(), y + quadBounds.getHeight()));
-                }
-            }
-        }
-
-        indexCount += opMesh->indexCount;
-    }
-
-    Texture* texture = renderer.caches().textureCache.get(firstOp.bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    // 9 patches are built for stretching - always filter
-    int textureFillFlags = TextureFillFlags::ForceFilter;
-    if (firstOp.bitmap->colorType() == kAlpha_8_SkColorType) {
-        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
-    }
-    Glop glop;
-    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-            .setRoundRectClipState(firstState.roundRectClipState)
-            .setMeshTexturedIndexedQuads(vertices, indexCount)
-            .setFillTexturePaint(*texture, textureFillFlags, firstOp.paint, firstState.alpha)
-            .setTransform(Matrix4::identity(), TransformFlags::None)
-            .setModelViewIdentityEmptyBounds()
-            .build();
-    ClipRect renderTargetClip(opList.clip);
-    const ClipBase* clip = opList.clipSideFlags ? &renderTargetClip : nullptr;
-    renderer.renderGlop(nullptr, clip, glop);
+    // DEAD CODE
 }
 
 static void renderTextShadow(BakedOpRenderer& renderer, const TextOp& op,
@@ -244,29 +105,6 @@
     }
 }
 
-static void renderConvexPath(BakedOpRenderer& renderer, const BakedOpState& state,
-                             const SkPath& path, const SkPaint& paint) {
-    VertexBuffer vertexBuffer;
-    // TODO: try clipping large paths to viewport
-    PathTessellator::tessellatePath(path, &paint, state.computedState.transform, vertexBuffer);
-    renderVertexBuffer(renderer, state, vertexBuffer, 0.0f, 0.0f, paint, 0);
-}
-
-static void renderPathTexture(BakedOpRenderer& renderer, const BakedOpState& state, float xOffset,
-                              float yOffset, PathTexture& texture, const SkPaint& paint) {
-    Rect dest(texture.width(), texture.height());
-    dest.translate(xOffset + texture.left - texture.offset, yOffset + texture.top - texture.offset);
-    Glop glop;
-    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-            .setRoundRectClipState(state.roundRectClipState)
-            .setMeshTexturedUnitQuad(nullptr)
-            .setFillPathTexturePaint(texture, paint, state.alpha)
-            .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewMapUnitToRect(dest)
-            .build();
-    renderer.renderGlop(state, glop);
-}
-
 SkRect getBoundsOfFill(const RecordedOp& op) {
     SkRect bounds = op.unmappedBounds.toSkRect();
     if (op.paint->getStyle() == SkPaint::kStrokeAndFill_Style) {
@@ -278,29 +116,7 @@
 
 void BakedOpDispatcher::onArcOp(BakedOpRenderer& renderer, const ArcOp& op,
                                 const BakedOpState& state) {
-    // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
-    if (op.paint->getStyle() != SkPaint::kStroke_Style || op.paint->getPathEffect() != nullptr ||
-        op.useCenter) {
-        PathTexture* texture = renderer.caches().pathCache.getArc(
-                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.startAngle,
-                op.sweepAngle, op.useCenter, op.paint);
-        const AutoTexture holder(texture);
-        if (CC_LIKELY(holder.texture)) {
-            renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.top,
-                              *texture, *(op.paint));
-        }
-    } else {
-        SkRect rect = getBoundsOfFill(op);
-        SkPath path;
-        if (op.useCenter) {
-            path.moveTo(rect.centerX(), rect.centerY());
-        }
-        path.arcTo(rect, op.startAngle, op.sweepAngle, !op.useCenter);
-        if (op.useCenter) {
-            path.close();
-        }
-        renderConvexPath(renderer, state, path, *(op.paint));
-    }
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op,
@@ -325,69 +141,7 @@
 
 void BakedOpDispatcher::onBitmapMeshOp(BakedOpRenderer& renderer, const BitmapMeshOp& op,
                                        const BakedOpState& state) {
-    Texture* texture = renderer.caches().textureCache.get(op.bitmap);
-    if (!texture) {
-        return;
-    }
-    const AutoTexture autoCleanup(texture);
-
-    const uint32_t elementCount = op.meshWidth * op.meshHeight * 6;
-
-    std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[elementCount]);
-    ColorTextureVertex* vertex = &mesh[0];
-
-    const int* colors = op.colors;
-    std::unique_ptr<int[]> tempColors;
-    if (!colors) {
-        uint32_t colorsCount = (op.meshWidth + 1) * (op.meshHeight + 1);
-        tempColors.reset(new int[colorsCount]);
-        memset(tempColors.get(), 0xff, colorsCount * sizeof(int));
-        colors = tempColors.get();
-    }
-
-    for (int32_t y = 0; y < op.meshHeight; y++) {
-        for (int32_t x = 0; x < op.meshWidth; x++) {
-            uint32_t i = (y * (op.meshWidth + 1) + x) * 2;
-
-            float u1 = float(x) / op.meshWidth;
-            float u2 = float(x + 1) / op.meshWidth;
-            float v1 = float(y) / op.meshHeight;
-            float v2 = float(y + 1) / op.meshHeight;
-
-            int ax = i + (op.meshWidth + 1) * 2;
-            int ay = ax + 1;
-            int bx = i;
-            int by = bx + 1;
-            int cx = i + 2;
-            int cy = cx + 1;
-            int dx = i + (op.meshWidth + 1) * 2 + 2;
-            int dy = dx + 1;
-
-            const float* vertices = op.vertices;
-            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2, colors[ax / 2]);
-            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
-
-            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1, colors[cx / 2]);
-        }
-    }
-
-    /*
-     * TODO: handle alpha_8 textures correctly by applying paint color, but *not*
-     * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh.
-     */
-    const int textureFillFlags = TextureFillFlags::None;
-    Glop glop;
-    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-            .setRoundRectClipState(state.roundRectClipState)
-            .setMeshColoredTexturedMesh(mesh.get(), elementCount)
-            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
-            .setTransform(state.computedState.transform, TransformFlags::None)
-            .setModelViewOffsetRect(0, 0, op.unmappedBounds)
-            .build();
-    renderer.renderGlop(state, glop);
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRectOp& op,
@@ -450,67 +204,17 @@
 
 void BakedOpDispatcher::onOvalOp(BakedOpRenderer& renderer, const OvalOp& op,
                                  const BakedOpState& state) {
-    if (op.paint->getPathEffect() != nullptr) {
-        PathTexture* texture = renderer.caches().pathCache.getOval(
-                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.paint);
-        const AutoTexture holder(texture);
-        if (CC_LIKELY(holder.texture)) {
-            renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.top,
-                              *texture, *(op.paint));
-        }
-    } else {
-        SkPath path;
-        SkRect rect = getBoundsOfFill(op);
-        path.addOval(rect);
-
-        if (state.computedState.localProjectionPathMask != nullptr) {
-            // Mask the ripple path by the local space projection mask in local space.
-            // Note that this can create CCW paths.
-            Op(path, *state.computedState.localProjectionPathMask, kIntersect_SkPathOp, &path);
-        }
-        renderConvexPath(renderer, state, path, *(op.paint));
-    }
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onPatchOp(BakedOpRenderer& renderer, const PatchOp& op,
                                   const BakedOpState& state) {
-    // 9 patches are built for stretching - always filter
-    int textureFillFlags = TextureFillFlags::ForceFilter;
-    if (op.bitmap->colorType() == kAlpha_8_SkColorType) {
-        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
-    }
-
-    // TODO: avoid redoing the below work each frame:
-    const Patch* mesh = renderer.caches().patchCache.get(op.bitmap->width(), op.bitmap->height(),
-                                                         op.unmappedBounds.getWidth(),
-                                                         op.unmappedBounds.getHeight(), op.patch);
-
-    Texture* texture = renderer.caches().textureCache.get(op.bitmap);
-    if (CC_LIKELY(texture)) {
-        const AutoTexture autoCleanup(texture);
-        Glop glop;
-        GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-                .setRoundRectClipState(state.roundRectClipState)
-                .setMeshPatchQuads(*mesh)
-                .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
-                .setTransform(state.computedState.transform, TransformFlags::None)
-                .setModelViewOffsetRectSnap(
-                        op.unmappedBounds.left, op.unmappedBounds.top,
-                        Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight()))
-                .build();
-        renderer.renderGlop(state, glop);
-    }
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onPathOp(BakedOpRenderer& renderer, const PathOp& op,
                                  const BakedOpState& state) {
-    PathTexture* texture = renderer.caches().pathCache.get(op.path, op.paint);
-    const AutoTexture holder(texture);
-    if (CC_LIKELY(holder.texture)) {
-        // Unlike other callers to renderPathTexture, no offsets are used because PathOp doesn't
-        // have any translate built in, other than what's in the SkPath itself
-        renderPathTexture(renderer, state, 0, 0, *texture, *(op.paint));
-    }
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onPointsOp(BakedOpRenderer& renderer, const PointsOp& op,
@@ -527,96 +231,12 @@
 
 void BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op,
                                  const BakedOpState& state) {
-    if (op.paint->getStyle() != SkPaint::kFill_Style) {
-        // only fill + default miter is supported by drawConvexPath, since others must handle joins
-        static_assert(SkPaintDefaults_MiterLimit == 4.0f, "Miter limit has changed");
-        if (CC_UNLIKELY(op.paint->getPathEffect() != nullptr ||
-                        op.paint->getStrokeJoin() != SkPaint::kMiter_Join ||
-                        op.paint->getStrokeMiter() != SkPaintDefaults_MiterLimit)) {
-            PathTexture* texture = renderer.caches().pathCache.getRect(
-                    op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.paint);
-            const AutoTexture holder(texture);
-            if (CC_LIKELY(holder.texture)) {
-                renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.top,
-                                  *texture, *(op.paint));
-            }
-        } else {
-            SkPath path;
-            path.addRect(getBoundsOfFill(op));
-            renderConvexPath(renderer, state, path, *(op.paint));
-        }
-    } else {
-        if (op.paint->isAntiAlias() && !state.computedState.transform.isSimple()) {
-            SkPath path;
-            path.addRect(op.unmappedBounds.toSkRect());
-            renderConvexPath(renderer, state, path, *(op.paint));
-        } else {
-            // render simple unit quad, no tessellation required
-            Glop glop;
-            GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
-                    .setRoundRectClipState(state.roundRectClipState)
-                    .setMeshUnitQuad()
-                    .setFillPaint(*op.paint, state.alpha)
-                    .setTransform(state.computedState.transform, TransformFlags::None)
-                    .setModelViewMapUnitToRect(op.unmappedBounds)
-                    .build();
-            renderer.renderGlop(state, glop);
-        }
-    }
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onRoundRectOp(BakedOpRenderer& renderer, const RoundRectOp& op,
                                       const BakedOpState& state) {
-    if (op.paint->getPathEffect() != nullptr) {
-        PathTexture* texture = renderer.caches().pathCache.getRoundRect(
-                op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight(), op.rx, op.ry,
-                op.paint);
-        const AutoTexture holder(texture);
-        if (CC_LIKELY(holder.texture)) {
-            renderPathTexture(renderer, state, op.unmappedBounds.left, op.unmappedBounds.top,
-                              *texture, *(op.paint));
-        }
-    } else {
-        const VertexBuffer* buffer = renderer.caches().tessellationCache.getRoundRect(
-                state.computedState.transform, *(op.paint), op.unmappedBounds.getWidth(),
-                op.unmappedBounds.getHeight(), op.rx, op.ry);
-        renderVertexBuffer(renderer, state, *buffer, op.unmappedBounds.left, op.unmappedBounds.top,
-                           *(op.paint), 0);
-    }
-}
-
-static void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, float casterAlpha,
-                         const VertexBuffer* ambientShadowVertexBuffer,
-                         const VertexBuffer* spotShadowVertexBuffer) {
-    SkPaint paint;
-    paint.setAntiAlias(true);  // want to use AlphaVertex
-
-    // The caller has made sure casterAlpha > 0.
-    uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha;
-    if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
-        ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
-    }
-    if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) {
-        paint.setAlpha((uint8_t)(casterAlpha * ambientShadowAlpha));
-        renderVertexBuffer(renderer, state, *ambientShadowVertexBuffer, 0, 0, paint,
-                           VertexBufferRenderFlags::ShadowInterp);
-    }
-
-    uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha;
-    if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
-        spotShadowAlpha = Properties::overrideSpotShadowStrength;
-    }
-    if (spotShadowVertexBuffer && spotShadowAlpha > 0) {
-        paint.setAlpha((uint8_t)(casterAlpha * spotShadowAlpha));
-        renderVertexBuffer(renderer, state, *spotShadowVertexBuffer, 0, 0, paint,
-                           VertexBufferRenderFlags::ShadowInterp);
-    }
-}
-
-void BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op,
-                                   const BakedOpState& state) {
-    TessellationCache::vertexBuffer_pair_t buffers = op.shadowTask->getResult();
-    renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second);
+    // DEAD CODE
 }
 
 void BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleRectsOp& op,
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 6b64b94..0a3e3e4 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -84,7 +84,6 @@
         // if stencil was used for clipping, detach it and return it to pool
         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
         GL_CHECKPOINT(MODERATE);
-        mCaches.renderBufferCache.put(mRenderTarget.stencil);
         mRenderTarget.stencil = nullptr;
     }
     mRenderTarget.lastStencilClip = nullptr;
@@ -182,7 +181,7 @@
 }
 
 Texture* BakedOpRenderer::getTexture(Bitmap* bitmap) {
-    return mCaches.textureCache.get(bitmap);
+    return nullptr;
 }
 
 void BakedOpRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
@@ -304,15 +303,7 @@
                 // Stencil needed, but current stencil isn't up to date
                 mRenderTarget.lastStencilClip = clip;
 
-                if (mRenderTarget.frameBufferId != 0 && !mRenderTarget.stencil) {
-                    OffscreenBuffer* layer = mRenderTarget.offscreenBuffer;
-                    mRenderTarget.stencil = mCaches.renderBufferCache.get(
-                            Stencil::getLayerStencilFormat(), layer->texture.width(),
-                            layer->texture.height());
-                    // stencil is bound + allocated - associate it with current FBO
-                    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                                              GL_RENDERBUFFER, mRenderTarget.stencil->getName());
-                }
+                // DEAD CODE
 
                 if (clip->mode == ClipMode::RectangleList) {
                     setupStencilRectList(clip);
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index 7c0590d..ae8928e 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -26,6 +26,7 @@
 class Caches;
 struct Glop;
 class Layer;
+struct RenderBuffer;
 class RenderState;
 struct ClipBase;
 
diff --git a/libs/hwui/BakedOpState.cpp b/libs/hwui/BakedOpState.cpp
index 63edf77..0c673f3 100644
--- a/libs/hwui/BakedOpState.cpp
+++ b/libs/hwui/BakedOpState.cpp
@@ -149,14 +149,6 @@
     return bakedState;
 }
 
-BakedOpState* BakedOpState::tryShadowOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
-                                                 const ShadowOp* shadowOpPtr) {
-    if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
-
-    // clip isn't empty, so construct the op
-    return allocator.create_trivial<BakedOpState>(allocator, snapshot, shadowOpPtr);
-}
-
 BakedOpState* BakedOpState::directConstruct(LinearAllocator& allocator, const ClipRect* clip,
                                             const Rect& dstRect, const RecordedOp& recordedOp) {
     return allocator.create_trivial<BakedOpState>(clip, dstRect, recordedOp);
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index e12dfbb..a50feff 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -120,9 +120,6 @@
                                                   StrokeBehavior strokeBehavior,
                                                   bool expandForPathTexture);
 
-    static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator, Snapshot& snapshot,
-                                              const ShadowOp* shadowOpPtr);
-
     static BakedOpState* directConstruct(LinearAllocator& allocator, const ClipRect* clip,
                                          const Rect& dstRect, const RecordedOp& recordedOp);
 
@@ -154,12 +151,6 @@
             , roundRectClipState(snapshot.roundRectClipState)
             , op(&recordedOp) {}
 
-    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
-            : computedState(allocator, snapshot)
-            , alpha(snapshot.alpha)
-            , roundRectClipState(snapshot.roundRectClipState)
-            , op(shadowOpPtr) {}
-
     BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
             : computedState(clipRect, dstRect)
             , alpha(1.0f)
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 6aefb35..9c2ab5c 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -46,10 +46,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Caches::Caches(RenderState& renderState)
-        : gradientCache(extensions())
-        , patchCache(renderState)
-        , programCache(extensions())
-        , mRenderState(&renderState)
+        : mRenderState(&renderState)
         , mInitialized(false) {
     INIT_LOGD("Creating OpenGL renderer caches");
     init();
@@ -102,13 +99,8 @@
     if (!mInitialized) return;
     mRegionMesh.reset(nullptr);
 
-    fboCache.clear();
-
-    programCache.clear();
     mProgram = nullptr;
 
-    patchCache.clear();
-
     clearGarbage();
 
     delete mPixelBufferState;
@@ -119,7 +111,7 @@
 }
 
 void Caches::setProgram(const ProgramDescription& description) {
-    setProgram(programCache.get(description));
+    // DEAD CODE
 }
 
 void Caches::setProgram(Program* program) {
@@ -157,8 +149,6 @@
 void Caches::dumpMemoryUsage(String8& log) {
     uint32_t total = 0;
     log.appendFormat("Current memory usage / total memory usage (bytes):\n");
-    log.appendFormat("  TextureCache         %8d / %8d\n", textureCache.getSize(),
-                     textureCache.getMaxSize());
     if (mRenderState) {
         int memused = 0;
         for (std::set<Layer*>::iterator it = mRenderState->mActiveLayers.begin();
@@ -174,27 +164,6 @@
                          mRenderState->mActiveLayers.size());
         total += memused;
     }
-    log.appendFormat("  RenderBufferCache    %8d / %8d\n", renderBufferCache.getSize(),
-                     renderBufferCache.getMaxSize());
-    log.appendFormat("  GradientCache        %8d / %8d\n", gradientCache.getSize(),
-                     gradientCache.getMaxSize());
-    log.appendFormat("  PathCache            %8d / %8d\n", pathCache.getSize(),
-                     pathCache.getMaxSize());
-    log.appendFormat("  TessellationCache    %8d / %8d\n", tessellationCache.getSize(),
-                     tessellationCache.getMaxSize());
-    log.appendFormat("  PatchCache           %8d / %8d\n", patchCache.getSize(),
-                     patchCache.getMaxSize());
-
-    log.appendFormat("Other:\n");
-    log.appendFormat("  FboCache             %8d / %8d\n", fboCache.getSize(),
-                     fboCache.getMaxSize());
-
-    total += textureCache.getSize();
-    total += renderBufferCache.getSize();
-    total += gradientCache.getSize();
-    total += pathCache.getSize();
-    total += tessellationCache.getSize();
-    total += patchCache.getSize();
 
     log.appendFormat("Total memory usage:\n");
     log.appendFormat("  %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
@@ -205,30 +174,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void Caches::clearGarbage() {
-    pathCache.clearGarbage();
-    patchCache.clearGarbage();
 }
 
 void Caches::flush(FlushMode mode) {
-    FLUSH_LOGD("Flushing caches (mode %d)", mode);
-
-    switch (mode) {
-        case FlushMode::Full:
-            textureCache.clear();
-            patchCache.clear();
-            gradientCache.clear();
-            fboCache.clear();
-        // fall through
-        case FlushMode::Moderate:
-            textureCache.flush();
-            pathCache.clear();
-            tessellationCache.clear();
-        // fall through
-        case FlushMode::Layers:
-            renderBufferCache.clear();
-            break;
-    }
-
     clearGarbage();
     glFinish();
     // Errors during cleanup should be considered non-fatal, dump them and
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index ed2d0b3..4cb6aff 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -18,15 +18,8 @@
 
 #include "DeviceInfo.h"
 #include "Extensions.h"
-#include "FboCache.h"
-#include "GradientCache.h"
-#include "PatchCache.h"
-#include "PathCache.h"
-#include "ProgramCache.h"
-#include "RenderBufferCache.h"
+#include "Program.h"
 #include "ResourceCache.h"
-#include "TessellationCache.h"
-#include "TextureCache.h"
 #include "renderstate/PixelBufferState.h"
 #include "renderstate/TextureState.h"
 #include "thread/TaskManager.h"
@@ -140,15 +133,6 @@
     GLint maxTextureSize;
 
 public:
-    TextureCache textureCache;
-    RenderBufferCache renderBufferCache;
-    GradientCache gradientCache;
-    PatchCache patchCache;
-    PathCache pathCache;
-    ProgramCache programCache;
-    TessellationCache tessellationCache;
-    FboCache fboCache;
-
     TaskManager tasks;
 
     bool gpuPixelBuffersEnabled;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index aa87aea..f1f0d2d 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -64,9 +64,6 @@
 
     for (size_t i = 0; i < pathResources.size(); i++) {
         const SkPath* path = pathResources[i];
-        if (path->unique() && Caches::hasInstance()) {
-            Caches::getInstance().pathCache.removeDeferred(path);
-        }
         delete path;
     }
 
diff --git a/libs/hwui/FboCache.cpp b/libs/hwui/FboCache.cpp
deleted file mode 100644
index 88302cc..0000000
--- a/libs/hwui/FboCache.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 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 <stdlib.h>
-
-#include "Debug.h"
-#include "FboCache.h"
-#include "Properties.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-FboCache::FboCache() : mMaxSize(0) {}
-
-FboCache::~FboCache() {
-    clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t FboCache::getSize() {
-    return mCache.size();
-}
-
-uint32_t FboCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void FboCache::clear() {
-    for (size_t i = 0; i < mCache.size(); i++) {
-        const GLuint fbo = mCache.itemAt(i);
-        glDeleteFramebuffers(1, &fbo);
-    }
-    mCache.clear();
-}
-
-GLuint FboCache::get() {
-    GLuint fbo;
-    if (mCache.size() > 0) {
-        fbo = mCache.itemAt(mCache.size() - 1);
-        mCache.removeAt(mCache.size() - 1);
-    } else {
-        glGenFramebuffers(1, &fbo);
-    }
-    return fbo;
-}
-
-bool FboCache::put(GLuint fbo) {
-    if (mCache.size() < mMaxSize) {
-        mCache.add(fbo);
-        return true;
-    }
-
-    glDeleteFramebuffers(1, &fbo);
-    return false;
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/FboCache.h b/libs/hwui/FboCache.h
deleted file mode 100644
index 5e8bb0c..0000000
--- a/libs/hwui/FboCache.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 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_FBO_CACHE_H
-#define ANDROID_HWUI_FBO_CACHE_H
-
-#include <GLES2/gl2.h>
-
-#include <utils/SortedVector.h>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache
-///////////////////////////////////////////////////////////////////////////////
-
-class FboCache {
-public:
-    FboCache();
-    ~FboCache();
-
-    /**
-     * Returns an FBO from the cache. If no FBO is available, a new one
-     * is created. If creating a new FBO fails, 0 is returned.
-     *
-     * When an FBO is obtained from the cache, it is removed and the
-     * total number of FBOs available in the cache decreases.
-     *
-     * @return The name of the FBO, or 0 if no FBO can be obtained.
-     */
-    GLuint get();
-
-    /**
-     * Adds the specified FBO to the cache.
-     *
-     * @param fbo The FBO to add to the cache.
-     *
-     * @return True if the FBO was added, false otherwise.
-     */
-    bool put(GLuint fbo);
-
-    /**
-     * Clears the cache. This causes all FBOs to be deleted.
-     */
-    void clear();
-
-    /**
-     * Returns the current size of the cache.
-     */
-    uint32_t getSize();
-
-    /**
-     * Returns the maximum number of FBOs that the cache can hold.
-     */
-    uint32_t getMaxSize();
-
-private:
-    SortedVector<GLuint> mCache;
-    uint32_t mMaxSize;
-};  // class FboCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_FBO_CACHE_H
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 049cd45..575aea5 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -386,71 +386,7 @@
 }
 
 void FrameBuilder::deferShadow(const ClipBase* reorderClip, const RenderNodeOp& casterNodeOp) {
-    auto& node = *casterNodeOp.renderNode;
-    auto& properties = node.properties();
-
-    if (properties.getAlpha() <= 0.0f || properties.getOutline().getAlpha() <= 0.0f ||
-        !properties.getOutline().getPath() || properties.getScaleX() == 0 ||
-        properties.getScaleY() == 0) {
-        // no shadow to draw
-        return;
-    }
-
-    const SkPath* casterOutlinePath = properties.getOutline().getPath();
-    const SkPath* revealClipPath = properties.getRevealClip().getPath();
-    if (revealClipPath && revealClipPath->isEmpty()) return;
-
-    float casterAlpha = properties.getAlpha() * properties.getOutline().getAlpha();
-
-    // holds temporary SkPath to store the result of intersections
-    SkPath* frameAllocatedPath = nullptr;
-    const SkPath* casterPath = casterOutlinePath;
-
-    // intersect the shadow-casting path with the reveal, if present
-    if (revealClipPath) {
-        frameAllocatedPath = createFrameAllocatedPath();
-
-        Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath);
-        casterPath = frameAllocatedPath;
-    }
-
-    // intersect the shadow-casting path with the clipBounds, if present
-    if (properties.getClippingFlags() & CLIP_TO_CLIP_BOUNDS) {
-        if (!frameAllocatedPath) {
-            frameAllocatedPath = createFrameAllocatedPath();
-        }
-        Rect clipBounds;
-        properties.getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
-        SkPath clipBoundsPath;
-        clipBoundsPath.addRect(clipBounds.left, clipBounds.top, clipBounds.right,
-                               clipBounds.bottom);
-
-        Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath);
-        casterPath = frameAllocatedPath;
-    }
-
-    // apply reorder clip to shadow, so it respects clip at beginning of reorderable chunk
-    int restoreTo = mCanvasState.save(SaveFlags::MatrixClip);
-    mCanvasState.writableSnapshot()->applyClip(reorderClip,
-                                               *mCanvasState.currentSnapshot()->transform);
-    if (CC_LIKELY(!mCanvasState.getRenderTargetClipBounds().isEmpty())) {
-        Matrix4 shadowMatrixXY(casterNodeOp.localMatrix);
-        Matrix4 shadowMatrixZ(casterNodeOp.localMatrix);
-        node.applyViewPropertyTransforms(shadowMatrixXY, false);
-        node.applyViewPropertyTransforms(shadowMatrixZ, true);
-
-        sp<TessellationCache::ShadowTask> task = mCaches.tessellationCache.getShadowTask(
-                mCanvasState.currentTransform(), mCanvasState.getLocalClipBounds(),
-                casterAlpha >= 1.0f, casterPath, &shadowMatrixXY, &shadowMatrixZ,
-                mCanvasState.currentSnapshot()->getRelativeLightCenter(), mLightRadius);
-        ShadowOp* shadowOp = mAllocator.create<ShadowOp>(task, casterAlpha);
-        BakedOpState* bakedOpState = BakedOpState::tryShadowOpConstruct(
-                mAllocator, *mCanvasState.writableSnapshot(), shadowOp);
-        if (CC_LIKELY(bakedOpState)) {
-            currentLayer().deferUnmergeableOp(mAllocator, bakedOpState, OpBatchType::Shadow);
-        }
-    }
-    mCanvasState.restoreToCount(restoreTo);
+    // DEAD CODE
 }
 
 void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) {
@@ -682,10 +618,7 @@
 }
 
 void FrameBuilder::deferPathOp(const PathOp& op) {
-    auto state = deferStrokeableOp(op, OpBatchType::AlphaMaskTexture);
-    if (CC_LIKELY(state)) {
-        mCaches.pathCache.precache(op.path, op.paint);
-    }
+    /*auto state = */deferStrokeableOp(op, OpBatchType::AlphaMaskTexture);
 }
 
 void FrameBuilder::deferPointsOp(const PointsOp& op) {
@@ -698,13 +631,7 @@
 }
 
 void FrameBuilder::deferRoundRectOp(const RoundRectOp& op) {
-    auto state = deferStrokeableOp(op, tessBatchId(op));
-    if (CC_LIKELY(state && !op.paint->getPathEffect())) {
-        // TODO: consider storing tessellation task in BakedOpState
-        mCaches.tessellationCache.precacheRoundRect(state->computedState.transform, *(op.paint),
-                                                    op.unmappedBounds.getWidth(),
-                                                    op.unmappedBounds.getHeight(), op.rx, op.ry);
-    }
+    // DEAD CODE
 }
 
 void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) {
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 941373d..13a4112 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -21,7 +21,6 @@
 #include "Layer.h"
 #include "Matrix.h"
 #include "Patch.h"
-#include "PathCache.h"
 #include "SkiaShader.h"
 #include "Texture.h"
 #include "VertexBuffer.h"
@@ -203,17 +202,7 @@
 }
 
 GlopBuilder& GlopBuilder::setMeshPatchQuads(const Patch& patch) {
-    TRIGGER_STAGE(kMeshStage);
-
-    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
-    mOutGlop->mesh.indices = {mRenderState.meshState().getQuadListIBO(), nullptr};
-    mOutGlop->mesh.vertices = {mCaches.patchCache.getMeshBuffer(),
-                               VertexAttribFlags::TextureCoord,
-                               (void*)patch.positionOffset,
-                               (void*)patch.textureOffset,
-                               nullptr,
-                               kTextureVertexStride};
-    mOutGlop->mesh.elementCount = patch.indexCount;
+    // DEAD CODE
     return *this;
 }
 
@@ -365,17 +354,7 @@
 
 GlopBuilder& GlopBuilder::setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint,
                                                   float alphaScale) {
-    TRIGGER_STAGE(kFillStage);
-    REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
-    // specify invalid filter/clamp, since these are always static for PathTextures
-    mOutGlop->fill.texture = {&texture, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
-
-    setFill(paint.getColor(), alphaScale, paint.getBlendMode(), Blend::ModeOrderSwap::NoSwap,
-            paint.getShader(), paint.getColorFilter());
-
-    mDescription.hasAlpha8Texture = true;
-    mDescription.modulate = mOutGlop->fill.color.isNotBlack();
+    // DEAD CODE
     return *this;
 }
 
@@ -625,9 +604,6 @@
     mOutGlop->fill.colorEnabled = mDescription.modulate || singleColor;
 
     verify(mDescription, *mOutGlop);
-
-    // Final step: populate program and map bounds into render target space
-    mOutGlop->fill.program = mCaches.programCache.get(mDescription);
 }
 
 void GlopBuilder::dump(const Glop& glop) {
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
deleted file mode 100644
index 21e3c73..0000000
--- a/libs/hwui/GradientCache.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2010 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 <utils/JenkinsHash.h>
-
-#include "Caches.h"
-#include "Debug.h"
-#include "DeviceInfo.h"
-#include "GradientCache.h"
-#include "Properties.h"
-
-#include <cutils/properties.h>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Functions
-///////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-static inline T min(T a, T b) {
-    return a < b ? a : b;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache entry
-///////////////////////////////////////////////////////////////////////////////
-
-hash_t GradientCacheEntry::hash() const {
-    uint32_t hash = JenkinsHashMix(0, count);
-    for (uint32_t i = 0; i < count; i++) {
-        hash = JenkinsHashMix(hash, android::hash_type(colors[i]));
-        hash = JenkinsHashMix(hash, android::hash_type(positions[i]));
-    }
-    return JenkinsHashWhiten(hash);
-}
-
-int GradientCacheEntry::compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
-    int deltaInt = int(lhs.count) - int(rhs.count);
-    if (deltaInt != 0) return deltaInt;
-
-    deltaInt = memcmp(lhs.colors.get(), rhs.colors.get(), lhs.count * sizeof(uint32_t));
-    if (deltaInt != 0) return deltaInt;
-
-    return memcmp(lhs.positions.get(), rhs.positions.get(), lhs.count * sizeof(float));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-GradientCache::GradientCache(const Extensions& extensions)
-        : mCache(LruCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity)
-        , mSize(0)
-        , mMaxSize(MB(1))
-        , mUseFloatTexture(extensions.hasFloatTextures())
-        , mHasNpot(extensions.hasNPot())
-        , mHasLinearBlending(extensions.hasLinearBlending()) {
-    mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
-
-    mCache.setOnEntryRemovedListener(this);
-}
-
-GradientCache::~GradientCache() {
-    mCache.clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t GradientCache::getSize() {
-    return mSize;
-}
-
-uint32_t GradientCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void GradientCache::operator()(GradientCacheEntry&, Texture*& texture) {
-    if (texture) {
-        mSize -= texture->objectSize();
-        texture->deleteTexture();
-        delete texture;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-Texture* GradientCache::get(uint32_t* colors, float* positions, int count) {
-    GradientCacheEntry gradient(colors, positions, count);
-    Texture* texture = mCache.get(gradient);
-
-    if (!texture) {
-        texture = addLinearGradient(gradient, colors, positions, count);
-    }
-
-    return texture;
-}
-
-void GradientCache::clear() {
-    mCache.clear();
-}
-
-void GradientCache::getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info) {
-    uint32_t width = 256 * (count - 1);
-
-    // If the npot extension is not supported we cannot use non-clamp
-    // wrap modes. We therefore find the nearest largest power of 2
-    // unless width is already a power of 2
-    if (!mHasNpot && (width & (width - 1)) != 0) {
-        width = 1 << (32 - __builtin_clz(width));
-    }
-
-    bool hasAlpha = false;
-    for (int i = 0; i < count; i++) {
-        if (((colors[i] >> 24) & 0xff) < 255) {
-            hasAlpha = true;
-            break;
-        }
-    }
-
-    info.width = min(width, uint32_t(mMaxTextureSize));
-    info.hasAlpha = hasAlpha;
-}
-
-Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors,
-                                          float* positions, int count) {
-    GradientInfo info;
-    getGradientInfo(colors, count, info);
-
-    Texture* texture = new Texture(Caches::getInstance());
-    texture->blend = info.hasAlpha;
-    texture->generation = 1;
-
-    // Assume the cache is always big enough
-    const uint32_t size = info.width * 2 * bytesPerPixel();
-    while (getSize() + size > mMaxSize) {
-        LOG_ALWAYS_FATAL_IF(!mCache.removeOldest(),
-                            "Ran out of things to remove from the cache? getSize() = %" PRIu32
-                            ", size = %" PRIu32 ", mMaxSize = %" PRIu32 ", width = %" PRIu32,
-                            getSize(), size, mMaxSize, info.width);
-    }
-
-    generateTexture(colors, positions, info.width, 2, texture);
-
-    mSize += size;
-    LOG_ALWAYS_FATAL_IF((int)size != texture->objectSize(),
-                        "size != texture->objectSize(), size %" PRIu32
-                        ", objectSize %d"
-                        " width = %" PRIu32 " bytesPerPixel() = %zu",
-                        size, texture->objectSize(), info.width, bytesPerPixel());
-    mCache.put(gradient, texture);
-
-    return texture;
-}
-
-size_t GradientCache::bytesPerPixel() const {
-    // We use 4 channels (RGBA)
-    return 4 * (mUseFloatTexture ? /* fp16 */ 2 : sizeof(uint8_t));
-}
-
-size_t GradientCache::sourceBytesPerPixel() const {
-    // We use 4 channels (RGBA) and upload from floats (not half floats)
-    return 4 * (mUseFloatTexture ? sizeof(float) : sizeof(uint8_t));
-}
-
-void GradientCache::mixBytes(const FloatColor& start, const FloatColor& end, float amount,
-                             uint8_t*& dst) const {
-    float oppAmount = 1.0f - amount;
-    float a = start.a * oppAmount + end.a * amount;
-    *dst++ = uint8_t(OECF(start.r * oppAmount + end.r * amount) * 255.0f);
-    *dst++ = uint8_t(OECF(start.g * oppAmount + end.g * amount) * 255.0f);
-    *dst++ = uint8_t(OECF(start.b * oppAmount + end.b * amount) * 255.0f);
-    *dst++ = uint8_t(a * 255.0f);
-}
-
-void GradientCache::mixFloats(const FloatColor& start, const FloatColor& end, float amount,
-                              uint8_t*& dst) const {
-    float oppAmount = 1.0f - amount;
-    float a = start.a * oppAmount + end.a * amount;
-    float* d = (float*)dst;
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
-    // We want to stay linear
-    *d++ = (start.r * oppAmount + end.r * amount);
-    *d++ = (start.g * oppAmount + end.g * amount);
-    *d++ = (start.b * oppAmount + end.b * amount);
-#else
-    *d++ = OECF(start.r * oppAmount + end.r * amount);
-    *d++ = OECF(start.g * oppAmount + end.g * amount);
-    *d++ = OECF(start.b * oppAmount + end.b * amount);
-#endif
-    *d++ = a;
-    dst += 4 * sizeof(float);
-}
-
-void GradientCache::generateTexture(uint32_t* colors, float* positions, const uint32_t width,
-                                    const uint32_t height, Texture* texture) {
-    const GLsizei rowBytes = width * sourceBytesPerPixel();
-    uint8_t pixels[rowBytes * height];
-
-    static ChannelMixer gMixers[] = {
-            // colors are stored gamma-encoded
-            &android::uirenderer::GradientCache::mixBytes,
-            // colors are stored in linear (linear blending on)
-            // or gamma-encoded (linear blending off)
-            &android::uirenderer::GradientCache::mixFloats,
-    };
-    ChannelMixer mix = gMixers[mUseFloatTexture];
-
-    FloatColor start;
-    start.set(colors[0]);
-
-    FloatColor end;
-    end.set(colors[1]);
-
-    int currentPos = 1;
-    float startPos = positions[0];
-    float distance = positions[1] - startPos;
-
-    uint8_t* dst = pixels;
-    for (uint32_t x = 0; x < width; x++) {
-        float pos = x / float(width - 1);
-        if (pos > positions[currentPos]) {
-            start = end;
-            startPos = positions[currentPos];
-
-            currentPos++;
-
-            end.set(colors[currentPos]);
-            distance = positions[currentPos] - startPos;
-        }
-
-        float amount = (pos - startPos) / distance;
-        (this->*mix)(start, end, amount, dst);
-    }
-
-    memcpy(pixels + rowBytes, pixels, rowBytes);
-
-    if (mUseFloatTexture) {
-        texture->upload(GL_RGBA16F, width, height, GL_RGBA, GL_FLOAT, pixels);
-    } else {
-        GLint internalFormat = mHasLinearBlending ? GL_SRGB8_ALPHA8 : GL_RGBA;
-        texture->upload(internalFormat, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-    }
-
-    texture->setFilter(GL_LINEAR);
-    texture->setWrap(GL_CLAMP_TO_EDGE);
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
deleted file mode 100644
index ff426cd..0000000
--- a/libs/hwui/GradientCache.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 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_GRADIENT_CACHE_H
-#define ANDROID_HWUI_GRADIENT_CACHE_H
-
-#include <memory>
-
-#include <GLES3/gl3.h>
-
-#include <SkShader.h>
-
-#include <utils/LruCache.h>
-#include <utils/Mutex.h>
-
-#include "FloatColor.h"
-
-namespace android {
-namespace uirenderer {
-
-class Texture;
-
-struct GradientCacheEntry {
-    GradientCacheEntry() {
-        count = 0;
-        colors = nullptr;
-        positions = nullptr;
-    }
-
-    GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
-        copy(colors, positions, count);
-    }
-
-    GradientCacheEntry(const GradientCacheEntry& entry) {
-        copy(entry.colors.get(), entry.positions.get(), entry.count);
-    }
-
-    GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
-        if (this != &entry) {
-            copy(entry.colors.get(), entry.positions.get(), entry.count);
-        }
-
-        return *this;
-    }
-
-    hash_t hash() const;
-
-    static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);
-
-    bool operator==(const GradientCacheEntry& other) const { return compare(*this, other) == 0; }
-
-    bool operator!=(const GradientCacheEntry& other) const { return compare(*this, other) != 0; }
-
-    std::unique_ptr<uint32_t[]> colors;
-    std::unique_ptr<float[]> positions;
-    uint32_t count;
-
-private:
-    void copy(uint32_t* colors, float* positions, uint32_t count) {
-        this->count = count;
-        this->colors.reset(new uint32_t[count]);
-        this->positions.reset(new float[count]);
-
-        memcpy(this->colors.get(), colors, count * sizeof(uint32_t));
-        memcpy(this->positions.get(), positions, count * sizeof(float));
-    }
-
-};  // GradientCacheEntry
-
-// Caching support
-
-inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
-    return GradientCacheEntry::compare(lhs, rhs) < 0;
-}
-
-inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
-    return GradientCacheEntry::compare(lhs, rhs);
-}
-
-inline hash_t hash_type(const GradientCacheEntry& entry) {
-    return entry.hash();
-}
-
-/**
- * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
- * Any texture added to the cache causing the cache to grow beyond the maximum
- * allowed size will also cause the oldest texture to be kicked out.
- */
-class GradientCache : public OnEntryRemoved<GradientCacheEntry, Texture*> {
-public:
-    explicit GradientCache(const Extensions& extensions);
-    ~GradientCache();
-
-    /**
-     * Used as a callback when an entry is removed from the cache.
-     * Do not invoke directly.
-     */
-    void operator()(GradientCacheEntry& shader, Texture*& texture) override;
-
-    /**
-     * Returns the texture associated with the specified shader.
-     */
-    Texture* get(uint32_t* colors, float* positions, int count);
-
-    /**
-     * Clears the cache. This causes all textures to be deleted.
-     */
-    void clear();
-
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-private:
-    /**
-     * Adds a new linear gradient to the cache. The generated texture is
-     * returned.
-     */
-    Texture* addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions,
-                               int count);
-
-    void generateTexture(uint32_t* colors, float* positions, const uint32_t width,
-                         const uint32_t height, Texture* texture);
-
-    struct GradientInfo {
-        uint32_t width;
-        bool hasAlpha;
-    };
-
-    void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);
-
-    size_t bytesPerPixel() const;
-    size_t sourceBytesPerPixel() const;
-
-    typedef void (GradientCache::*ChannelMixer)(const FloatColor& start, const FloatColor& end,
-                                                float amount, uint8_t*& dst) const;
-
-    void mixBytes(const FloatColor& start, const FloatColor& end, float amount,
-                  uint8_t*& dst) const;
-    void mixFloats(const FloatColor& start, const FloatColor& end, float amount,
-                   uint8_t*& dst) const;
-
-    LruCache<GradientCacheEntry, Texture*> mCache;
-
-    uint32_t mSize;
-    const uint32_t mMaxSize;
-
-    GLint mMaxTextureSize;
-    bool mUseFloatTexture;
-    bool mHasNpot;
-    bool mHasLinearBlending;
-
-    mutable Mutex mLock;
-};  // class GradientCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_GRADIENT_CACHE_H
diff --git a/libs/hwui/PatchCache.cpp b/libs/hwui/PatchCache.cpp
deleted file mode 100644
index 673d73c..0000000
--- a/libs/hwui/PatchCache.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2010 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 <utils/JenkinsHash.h>
-#include <utils/Log.h>
-
-#include "Caches.h"
-#include "Patch.h"
-#include "PatchCache.h"
-#include "Properties.h"
-#include "renderstate/RenderState.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-PatchCache::PatchCache(RenderState& renderState)
-        : mRenderState(renderState)
-        , mMaxSize(KB(128))
-        , mSize(0)
-        , mCache(LruCache<PatchDescription, Patch*>::kUnlimitedCapacity)
-        , mMeshBuffer(0)
-        , mFreeBlocks(nullptr) {}
-
-PatchCache::~PatchCache() {
-    clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-hash_t PatchCache::PatchDescription::hash() const {
-    uint32_t hash = JenkinsHashMix(0, android::hash_type(mPatch));
-    hash = JenkinsHashMix(hash, mBitmapWidth);
-    hash = JenkinsHashMix(hash, mBitmapHeight);
-    hash = JenkinsHashMix(hash, mPixelWidth);
-    hash = JenkinsHashMix(hash, mPixelHeight);
-    return JenkinsHashWhiten(hash);
-}
-
-int PatchCache::PatchDescription::compare(const PatchCache::PatchDescription& lhs,
-                                          const PatchCache::PatchDescription& rhs) {
-    return memcmp(&lhs, &rhs, sizeof(PatchDescription));
-}
-
-void PatchCache::clear() {
-    clearCache();
-
-    if (mMeshBuffer) {
-        mRenderState.meshState().deleteMeshBuffer(mMeshBuffer);
-        mMeshBuffer = 0;
-        mSize = 0;
-    }
-}
-
-void PatchCache::clearCache() {
-    LruCache<PatchDescription, Patch*>::Iterator i(mCache);
-    while (i.next()) {
-        delete i.value();
-    }
-    mCache.clear();
-
-    BufferBlock* block = mFreeBlocks;
-    while (block) {
-        BufferBlock* next = block->next;
-        delete block;
-        block = next;
-    }
-    mFreeBlocks = nullptr;
-}
-
-void PatchCache::remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch) {
-    LruCache<PatchDescription, Patch*>::Iterator i(mCache);
-    while (i.next()) {
-        const PatchDescription& key = i.key();
-        if (key.getPatch() == patch) {
-            patchesToRemove.push(patch_pair_t(&key, i.value()));
-        }
-    }
-}
-
-void PatchCache::removeDeferred(Res_png_9patch* patch) {
-    Mutex::Autolock _l(mLock);
-
-    // Assert that patch is not already garbage
-    size_t count = mGarbage.size();
-    for (size_t i = 0; i < count; i++) {
-        if (patch == mGarbage[i]) {
-            patch = nullptr;
-            break;
-        }
-    }
-    LOG_ALWAYS_FATAL_IF(patch == nullptr);
-
-    mGarbage.push(patch);
-}
-
-void PatchCache::clearGarbage() {
-    Vector<patch_pair_t> patchesToRemove;
-
-    {  // scope for the mutex
-        Mutex::Autolock _l(mLock);
-        size_t count = mGarbage.size();
-        for (size_t i = 0; i < count; i++) {
-            Res_png_9patch* patch = mGarbage[i];
-            remove(patchesToRemove, patch);
-            // A Res_png_9patch is actually an array of byte that's larger
-            // than sizeof(Res_png_9patch). It must be freed as an array.
-            delete[](int8_t*) patch;
-        }
-        mGarbage.clear();
-    }
-
-    // TODO: We could sort patchesToRemove by offset to merge
-    // adjacent free blocks
-    for (size_t i = 0; i < patchesToRemove.size(); i++) {
-        const patch_pair_t& pair = patchesToRemove[i];
-
-        // Release the patch and mark the space in the free list
-        Patch* patch = pair.getSecond();
-        BufferBlock* block = new BufferBlock(patch->positionOffset, patch->getSize());
-        block->next = mFreeBlocks;
-        mFreeBlocks = block;
-
-        mSize -= patch->getSize();
-
-        mCache.remove(*pair.getFirst());
-        delete patch;
-    }
-
-#if DEBUG_PATCHES
-    if (patchesToRemove.size() > 0) {
-        dumpFreeBlocks("Removed garbage");
-    }
-#endif
-}
-
-void PatchCache::createVertexBuffer() {
-    mRenderState.meshState().genOrUpdateMeshBuffer(&mMeshBuffer, mMaxSize, nullptr,
-                                                   GL_DYNAMIC_DRAW);
-    mSize = 0;
-    mFreeBlocks = new BufferBlock(0, mMaxSize);
-}
-
-/**
- * Sets the mesh's offsets and copies its associated vertices into
- * the mesh buffer (VBO).
- */
-void PatchCache::setupMesh(Patch* newMesh) {
-    // This call ensures the VBO exists and that it is bound
-    if (!mMeshBuffer) {
-        createVertexBuffer();
-    }
-
-    // If we're running out of space, let's clear the entire cache
-    uint32_t size = newMesh->getSize();
-    if (mSize + size > mMaxSize) {
-        clearCache();
-        createVertexBuffer();
-    }
-
-    // Find a block where we can fit the mesh
-    BufferBlock* previous = nullptr;
-    BufferBlock* block = mFreeBlocks;
-    while (block) {
-        // The mesh fits
-        if (block->size >= size) {
-            break;
-        }
-        previous = block;
-        block = block->next;
-    }
-
-    // We have enough space left in the buffer, but it's
-    // too fragmented, let's clear the cache
-    if (!block) {
-        clearCache();
-        createVertexBuffer();
-        previous = nullptr;
-        block = mFreeBlocks;
-    }
-
-    // Copy the 9patch mesh in the VBO
-    newMesh->positionOffset = (GLintptr)(block->offset);
-    newMesh->textureOffset = newMesh->positionOffset + kMeshTextureOffset;
-
-    mRenderState.meshState().updateMeshBufferSubData(mMeshBuffer, newMesh->positionOffset, size,
-                                                     newMesh->vertices.get());
-
-    // Remove the block since we've used it entirely
-    if (block->size == size) {
-        if (previous) {
-            previous->next = block->next;
-        } else {
-            mFreeBlocks = block->next;
-        }
-        delete block;
-    } else {
-        // Resize the block now that it's occupied
-        block->offset += size;
-        block->size -= size;
-    }
-
-    mSize += size;
-}
-
-static const UvMapper sIdentity;
-
-const Patch* PatchCache::get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-                             const float pixelWidth, const float pixelHeight,
-                             const Res_png_9patch* patch) {
-    const PatchDescription description(bitmapWidth, bitmapHeight, pixelWidth, pixelHeight, patch);
-    const Patch* mesh = mCache.get(description);
-
-    if (!mesh) {
-        Patch* newMesh =
-                new Patch(bitmapWidth, bitmapHeight, pixelWidth, pixelHeight, sIdentity, patch);
-
-        if (newMesh->vertices) {
-            setupMesh(newMesh);
-        }
-
-#if DEBUG_PATCHES
-        dumpFreeBlocks("Adding patch");
-#endif
-
-        mCache.put(description, newMesh);
-        return newMesh;
-    }
-
-    return mesh;
-}
-
-#if DEBUG_PATCHES
-void PatchCache::dumpFreeBlocks(const char* prefix) {
-    String8 dump;
-    BufferBlock* block = mFreeBlocks;
-    while (block) {
-        dump.appendFormat("->(%d, %d)", block->positionOffset, block->size);
-        block = block->next;
-    }
-    ALOGD("%s: Free blocks%s", prefix, dump.string());
-}
-#endif
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
deleted file mode 100644
index 273c3f5..0000000
--- a/libs/hwui/PatchCache.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#pragma once
-
-#include <GLES2/gl2.h>
-
-#include <utils/LruCache.h>
-
-#include <androidfw/ResourceTypes.h>
-
-#include "Debug.h"
-#include "utils/Pair.h"
-
-namespace android {
-namespace uirenderer {
-
-class Patch;
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_PATCHES
-#define PATCH_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-#define PATCH_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache
-///////////////////////////////////////////////////////////////////////////////
-
-class Caches;
-class RenderState;
-
-class PatchCache {
-public:
-    explicit PatchCache(RenderState& renderState);
-    ~PatchCache();
-
-    const Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-                     const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch);
-    void clear();
-
-    uint32_t getSize() const { return mSize; }
-
-    uint32_t getMaxSize() const { return mMaxSize; }
-
-    GLuint getMeshBuffer() const { return mMeshBuffer; }
-
-    /**
-     * Removes the entries associated with the specified 9-patch. This is meant
-     * to be called from threads that are not the EGL context thread (GC thread
-     * on the VM side for instance.)
-     */
-    void removeDeferred(Res_png_9patch* patch);
-
-    /**
-     * Process deferred removals.
-     */
-    void clearGarbage();
-
-private:
-    struct PatchDescription {
-        PatchDescription()
-                : mPatch(nullptr)
-                , mBitmapWidth(0)
-                , mBitmapHeight(0)
-                , mPixelWidth(0)
-                , mPixelHeight(0) {}
-
-        PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
-                         const float pixelWidth, const float pixelHeight,
-                         const Res_png_9patch* patch)
-                : mPatch(patch)
-                , mBitmapWidth(bitmapWidth)
-                , mBitmapHeight(bitmapHeight)
-                , mPixelWidth(pixelWidth)
-                , mPixelHeight(pixelHeight) {}
-
-        hash_t hash() const;
-
-        const Res_png_9patch* getPatch() const { return mPatch; }
-
-        static int compare(const PatchDescription& lhs, const PatchDescription& rhs);
-
-        bool operator==(const PatchDescription& other) const { return compare(*this, other) == 0; }
-
-        bool operator!=(const PatchDescription& other) const { return compare(*this, other) != 0; }
-
-        friend inline int strictly_order_type(const PatchDescription& lhs,
-                                              const PatchDescription& rhs) {
-            return PatchDescription::compare(lhs, rhs) < 0;
-        }
-
-        friend inline int compare_type(const PatchDescription& lhs, const PatchDescription& rhs) {
-            return PatchDescription::compare(lhs, rhs);
-        }
-
-        friend inline hash_t hash_type(const PatchDescription& entry) { return entry.hash(); }
-
-    private:
-        const Res_png_9patch* mPatch;
-        uint32_t mBitmapWidth;
-        uint32_t mBitmapHeight;
-        float mPixelWidth;
-        float mPixelHeight;
-
-    };  // struct PatchDescription
-
-    /**
-     * A buffer block represents an empty range in the mesh buffer
-     * that can be used to store vertices.
-     *
-     * The patch cache maintains a linked-list of buffer blocks
-     * to track available regions of memory in the VBO.
-     */
-    struct BufferBlock {
-        BufferBlock(uint32_t offset, uint32_t size) : offset(offset), size(size), next(nullptr) {}
-
-        uint32_t offset;
-        uint32_t size;
-
-        BufferBlock* next;
-    };  // struct BufferBlock
-
-    typedef Pair<const PatchDescription*, Patch*> patch_pair_t;
-
-    void clearCache();
-    void createVertexBuffer();
-
-    void setupMesh(Patch* newMesh);
-
-    void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch);
-
-#if DEBUG_PATCHES
-    void dumpFreeBlocks(const char* prefix);
-#endif
-
-    RenderState& mRenderState;
-    const uint32_t mMaxSize;
-    uint32_t mSize;
-
-    LruCache<PatchDescription, Patch*> mCache;
-
-    GLuint mMeshBuffer;
-    // First available free block inside the mesh buffer
-    BufferBlock* mFreeBlocks;
-
-    // Garbage tracking, required to handle GC events on the VM side
-    Vector<Res_png_9patch*> mGarbage;
-    mutable Mutex mLock;
-};  // class PatchCache
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
deleted file mode 100644
index e67c5bd..0000000
--- a/libs/hwui/PathCache.cpp
+++ /dev/null
@@ -1,559 +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 <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkColorFilter.h>
-#include <SkMaskFilter.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-#include <SkPathEffect.h>
-#include <SkRect.h>
-
-#include <utils/JenkinsHash.h>
-#include <utils/Trace.h>
-
-#include "Caches.h"
-#include "PathCache.h"
-
-#include "thread/Signal.h"
-#include "thread/TaskProcessor.h"
-
-#include <cutils/properties.h>
-
-namespace android {
-namespace uirenderer {
-
-static constexpr size_t PATH_CACHE_COUNT_LIMIT = 256;
-
-template <class T>
-static bool compareWidthHeight(const T& lhs, const T& rhs) {
-    return (lhs.mWidth == rhs.mWidth) && (lhs.mHeight == rhs.mHeight);
-}
-
-static bool compareRoundRects(const PathDescription::Shape::RoundRect& lhs,
-                              const PathDescription::Shape::RoundRect& rhs) {
-    return compareWidthHeight(lhs, rhs) && lhs.mRx == rhs.mRx && lhs.mRy == rhs.mRy;
-}
-
-static bool compareArcs(const PathDescription::Shape::Arc& lhs,
-                        const PathDescription::Shape::Arc& rhs) {
-    return compareWidthHeight(lhs, rhs) && lhs.mStartAngle == rhs.mStartAngle &&
-           lhs.mSweepAngle == rhs.mSweepAngle && lhs.mUseCenter == rhs.mUseCenter;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache entries
-///////////////////////////////////////////////////////////////////////////////
-
-PathDescription::PathDescription()
-        : type(ShapeType::None)
-        , join(SkPaint::kDefault_Join)
-        , cap(SkPaint::kDefault_Cap)
-        , style(SkPaint::kFill_Style)
-        , miter(4.0f)
-        , strokeWidth(1.0f)
-        , pathEffect(nullptr) {
-    // Shape bits should be set to zeroes, because they are used for hash calculation.
-    memset(&shape, 0, sizeof(Shape));
-}
-
-PathDescription::PathDescription(ShapeType type, const SkPaint* paint)
-        : type(type)
-        , join(paint->getStrokeJoin())
-        , cap(paint->getStrokeCap())
-        , style(paint->getStyle())
-        , miter(paint->getStrokeMiter())
-        , strokeWidth(paint->getStrokeWidth())
-        , pathEffect(paint->getPathEffect()) {
-    // Shape bits should be set to zeroes, because they are used for hash calculation.
-    memset(&shape, 0, sizeof(Shape));
-}
-
-hash_t PathDescription::hash() const {
-    uint32_t hash = JenkinsHashMix(0, static_cast<int>(type));
-    hash = JenkinsHashMix(hash, join);
-    hash = JenkinsHashMix(hash, cap);
-    hash = JenkinsHashMix(hash, style);
-    hash = JenkinsHashMix(hash, android::hash_type(miter));
-    hash = JenkinsHashMix(hash, android::hash_type(strokeWidth));
-    hash = JenkinsHashMix(hash, android::hash_type(pathEffect));
-    hash = JenkinsHashMixBytes(hash, (uint8_t*)&shape, sizeof(Shape));
-    return JenkinsHashWhiten(hash);
-}
-
-bool PathDescription::operator==(const PathDescription& rhs) const {
-    if (type != rhs.type) return false;
-    if (join != rhs.join) return false;
-    if (cap != rhs.cap) return false;
-    if (style != rhs.style) return false;
-    if (miter != rhs.miter) return false;
-    if (strokeWidth != rhs.strokeWidth) return false;
-    if (pathEffect != rhs.pathEffect) return false;
-    switch (type) {
-        case ShapeType::None:
-            return 0;
-        case ShapeType::Rect:
-            return compareWidthHeight(shape.rect, rhs.shape.rect);
-        case ShapeType::RoundRect:
-            return compareRoundRects(shape.roundRect, rhs.shape.roundRect);
-        case ShapeType::Circle:
-            return shape.circle.mRadius == rhs.shape.circle.mRadius;
-        case ShapeType::Oval:
-            return compareWidthHeight(shape.oval, rhs.shape.oval);
-        case ShapeType::Arc:
-            return compareArcs(shape.arc, rhs.shape.arc);
-        case ShapeType::Path:
-            return shape.path.mGenerationID == rhs.shape.path.mGenerationID;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Utilities
-///////////////////////////////////////////////////////////////////////////////
-
-static void computePathBounds(const SkPath* path, const SkPaint* paint, PathTexture* texture,
-                              uint32_t& width, uint32_t& height) {
-    const SkRect& bounds = path->getBounds();
-    const float pathWidth = std::max(bounds.width(), 1.0f);
-    const float pathHeight = std::max(bounds.height(), 1.0f);
-
-    texture->left = floorf(bounds.fLeft);
-    texture->top = floorf(bounds.fTop);
-
-    texture->offset = (int)floorf(std::max(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f);
-
-    width = uint32_t(pathWidth + texture->offset * 2.0 + 0.5);
-    height = uint32_t(pathHeight + texture->offset * 2.0 + 0.5);
-}
-
-static void initPaint(SkPaint& paint) {
-    // Make sure the paint is opaque, color, alpha, filter, etc.
-    // will be applied later when compositing the alpha8 texture
-    paint.setColor(SK_ColorBLACK);
-    paint.setAlpha(255);
-    paint.setColorFilter(nullptr);
-    paint.setMaskFilter(nullptr);
-    paint.setShader(nullptr);
-    paint.setBlendMode(SkBlendMode::kSrc);
-}
-
-static sk_sp<Bitmap> drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
-                              uint32_t maxTextureSize) {
-    uint32_t width, height;
-    computePathBounds(path, paint, texture, width, height);
-    if (width > maxTextureSize || height > maxTextureSize) {
-        ALOGW("Shape too large to be rendered into a texture (%dx%d, max=%dx%d)", width, height,
-              maxTextureSize, maxTextureSize);
-        return nullptr;
-    }
-
-    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
-    SkPaint pathPaint(*paint);
-    initPaint(pathPaint);
-
-    SkBitmap skBitmap;
-    bitmap->getSkBitmap(&skBitmap);
-    skBitmap.eraseColor(0);
-    SkCanvas canvas(skBitmap);
-    canvas.translate(-texture->left + texture->offset, -texture->top + texture->offset);
-    canvas.drawPath(*path, pathPaint);
-    return bitmap;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache constructor/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-PathCache::PathCache()
-        : mCache(LruCache<PathDescription, PathTexture*>::kUnlimitedCapacity)
-        , mSize(0)
-        , mMaxSize(DeviceInfo::multiplyByResolution(4)) {
-    mCache.setOnEntryRemovedListener(this);
-    mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
-    mDebugEnabled = Properties::debugLevel & kDebugCaches;
-}
-
-PathCache::~PathCache() {
-    mCache.clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t PathCache::getSize() {
-    return mSize;
-}
-
-uint32_t PathCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::operator()(PathDescription& entry, PathTexture*& texture) {
-    removeTexture(texture);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::removeTexture(PathTexture* texture) {
-    if (texture) {
-        const uint32_t size = texture->width() * texture->height();
-
-        // If there is a pending task we must wait for it to return
-        // before attempting our cleanup
-        const sp<PathTask>& task = texture->task();
-        if (task != nullptr) {
-            task->getResult();
-            texture->clearTask();
-        } else {
-            // If there is a pending task, the path was not added
-            // to the cache and the size wasn't increased
-            if (size > mSize) {
-                ALOGE("Removing path texture of size %d will leave "
-                      "the cache in an inconsistent state",
-                      size);
-            }
-            mSize -= size;
-        }
-
-        PATH_LOGD("PathCache::delete name, size, mSize = %d, %d, %d", texture->id, size, mSize);
-        if (mDebugEnabled) {
-            ALOGD("Shape deleted, size = %d", size);
-        }
-
-        texture->deleteTexture();
-        delete texture;
-    }
-}
-
-void PathCache::purgeCache(uint32_t width, uint32_t height) {
-    const uint32_t size = width * height;
-    // Don't even try to cache a bitmap that's bigger than the cache
-    if (size < mMaxSize) {
-        while (mSize + size > mMaxSize) {
-            mCache.removeOldest();
-        }
-    }
-}
-
-void PathCache::trim() {
-    while (mSize > mMaxSize || mCache.size() > PATH_CACHE_COUNT_LIMIT) {
-        LOG_ALWAYS_FATAL_IF(!mCache.size(),
-                            "Inconsistent mSize! Ran out of items to remove!"
-                            " mSize = %u, mMaxSize = %u",
-                            mSize, mMaxSize);
-        mCache.removeOldest();
-    }
-}
-
-PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath* path,
-                                   const SkPaint* paint) {
-    ATRACE_NAME("Generate Path Texture");
-
-    PathTexture* texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
-    sk_sp<Bitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
-    if (!bitmap) {
-        delete texture;
-        return nullptr;
-    }
-
-    purgeCache(bitmap->width(), bitmap->height());
-    generateTexture(entry, *bitmap, texture);
-    return texture;
-}
-
-void PathCache::generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
-                                bool addToCache) {
-    generateTexture(bitmap, texture);
-
-    // Note here that we upload to a texture even if it's bigger than mMaxSize.
-    // Such an entry in mCache will only be temporary, since it will be evicted
-    // immediately on trim, or on any other Path entering the cache.
-    uint32_t size = texture->width() * texture->height();
-    mSize += size;
-    PATH_LOGD("PathCache::get/create: name, size, mSize = %d, %d, %d", texture->id, size, mSize);
-    if (mDebugEnabled) {
-        ALOGD("Shape created, size = %d", size);
-    }
-    if (addToCache) {
-        mCache.put(entry, texture);
-    }
-}
-
-void PathCache::clear() {
-    mCache.clear();
-}
-
-void PathCache::generateTexture(Bitmap& bitmap, Texture* texture) {
-    ATRACE_NAME("Upload Path Texture");
-    texture->upload(bitmap);
-    texture->setFilter(GL_LINEAR);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Path precaching
-///////////////////////////////////////////////////////////////////////////////
-
-PathCache::PathProcessor::PathProcessor(Caches& caches)
-        : TaskProcessor<sk_sp<Bitmap> >(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {}
-
-void PathCache::PathProcessor::onProcess(const sp<Task<sk_sp<Bitmap> > >& task) {
-    PathTask* t = static_cast<PathTask*>(task.get());
-    ATRACE_NAME("pathPrecache");
-
-    t->setResult(drawPath(&t->path, &t->paint, t->texture, mMaxTextureSize));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Paths
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::removeDeferred(const SkPath* path) {
-    Mutex::Autolock l(mLock);
-    mGarbage.push_back(path->getGenerationID());
-}
-
-void PathCache::clearGarbage() {
-    Vector<PathDescription> pathsToRemove;
-
-    {  // scope for the mutex
-        Mutex::Autolock l(mLock);
-        for (const uint32_t generationID : mGarbage) {
-            LruCache<PathDescription, PathTexture*>::Iterator iter(mCache);
-            while (iter.next()) {
-                const PathDescription& key = iter.key();
-                if (key.type == ShapeType::Path && key.shape.path.mGenerationID == generationID) {
-                    pathsToRemove.push(key);
-                }
-            }
-        }
-        mGarbage.clear();
-    }
-
-    for (size_t i = 0; i < pathsToRemove.size(); i++) {
-        mCache.remove(pathsToRemove.itemAt(i));
-    }
-}
-
-PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Path, paint);
-    entry.shape.path.mGenerationID = path->getGenerationID();
-
-    PathTexture* texture = mCache.get(entry);
-
-    if (!texture) {
-        texture = addTexture(entry, path, paint);
-    } else {
-        // A bitmap is attached to the texture, this means we need to
-        // upload it as a GL texture
-        const sp<PathTask>& task = texture->task();
-        if (task != nullptr) {
-            // But we must first wait for the worker thread to be done
-            // producing the bitmap, so let's wait
-            sk_sp<Bitmap> bitmap = task->getResult();
-            if (bitmap) {
-                generateTexture(entry, *bitmap, texture, false);
-                texture->clearTask();
-            } else {
-                texture->clearTask();
-                texture = nullptr;
-                mCache.remove(entry);
-            }
-        }
-    }
-
-    return texture;
-}
-
-void PathCache::remove(const SkPath* path, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Path, paint);
-    entry.shape.path.mGenerationID = path->getGenerationID();
-    mCache.remove(entry);
-}
-
-void PathCache::precache(const SkPath* path, const SkPaint* paint) {
-    if (!Caches::getInstance().tasks.canRunTasks()) {
-        return;
-    }
-
-    PathDescription entry(ShapeType::Path, paint);
-    entry.shape.path.mGenerationID = path->getGenerationID();
-
-    PathTexture* texture = mCache.get(entry);
-
-    bool generate = false;
-    if (!texture) {
-        generate = true;
-    }
-
-    if (generate) {
-        // It is important to specify the generation ID so we do not
-        // attempt to precache the same path several times
-        texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
-        sp<PathTask> task = new PathTask(path, paint, texture);
-        texture->setTask(task);
-
-        // During the precaching phase we insert path texture objects into
-        // the cache that do not point to any GL texture. They are instead
-        // treated as a task for the precaching worker thread. This is why
-        // we do not check the cache limit when inserting these objects.
-        // The conversion into GL texture will happen in get(), when a client
-        // asks for a path texture. This is also when the cache limit will
-        // be enforced.
-        mCache.put(entry, texture);
-
-        if (mProcessor == nullptr) {
-            mProcessor = new PathProcessor(Caches::getInstance());
-        }
-        mProcessor->add(task);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Rounded rects
-///////////////////////////////////////////////////////////////////////////////
-
-PathTexture* PathCache::getRoundRect(float width, float height, float rx, float ry,
-                                     const SkPaint* paint) {
-    PathDescription entry(ShapeType::RoundRect, paint);
-    entry.shape.roundRect.mWidth = width;
-    entry.shape.roundRect.mHeight = height;
-    entry.shape.roundRect.mRx = rx;
-    entry.shape.roundRect.mRy = ry;
-
-    PathTexture* texture = get(entry);
-
-    if (!texture) {
-        SkPath path;
-        SkRect r;
-        r.set(0.0f, 0.0f, width, height);
-        path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
-
-        texture = addTexture(entry, &path, paint);
-    }
-
-    return texture;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Circles
-///////////////////////////////////////////////////////////////////////////////
-
-PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Circle, paint);
-    entry.shape.circle.mRadius = radius;
-
-    PathTexture* texture = get(entry);
-
-    if (!texture) {
-        SkPath path;
-        path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
-
-        texture = addTexture(entry, &path, paint);
-    }
-
-    return texture;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Ovals
-///////////////////////////////////////////////////////////////////////////////
-
-PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Oval, paint);
-    entry.shape.oval.mWidth = width;
-    entry.shape.oval.mHeight = height;
-
-    PathTexture* texture = get(entry);
-
-    if (!texture) {
-        SkPath path;
-        SkRect r;
-        r.set(0.0f, 0.0f, width, height);
-        path.addOval(r, SkPath::kCW_Direction);
-
-        texture = addTexture(entry, &path, paint);
-    }
-
-    return texture;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Rects
-///////////////////////////////////////////////////////////////////////////////
-
-PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Rect, paint);
-    entry.shape.rect.mWidth = width;
-    entry.shape.rect.mHeight = height;
-
-    PathTexture* texture = get(entry);
-
-    if (!texture) {
-        SkPath path;
-        SkRect r;
-        r.set(0.0f, 0.0f, width, height);
-        path.addRect(r, SkPath::kCW_Direction);
-
-        texture = addTexture(entry, &path, paint);
-    }
-
-    return texture;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Arcs
-///////////////////////////////////////////////////////////////////////////////
-
-PathTexture* PathCache::getArc(float width, float height, float startAngle, float sweepAngle,
-                               bool useCenter, const SkPaint* paint) {
-    PathDescription entry(ShapeType::Arc, paint);
-    entry.shape.arc.mWidth = width;
-    entry.shape.arc.mHeight = height;
-    entry.shape.arc.mStartAngle = startAngle;
-    entry.shape.arc.mSweepAngle = sweepAngle;
-    entry.shape.arc.mUseCenter = useCenter;
-
-    PathTexture* texture = get(entry);
-
-    if (!texture) {
-        SkPath path;
-        SkRect r;
-        r.set(0.0f, 0.0f, width, height);
-        if (useCenter) {
-            path.moveTo(r.centerX(), r.centerY());
-        }
-        path.arcTo(r, startAngle, sweepAngle, !useCenter);
-        if (useCenter) {
-            path.close();
-        }
-
-        texture = addTexture(entry, &path, paint);
-    }
-
-    return texture;
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
deleted file mode 100644
index 28c8bbb..0000000
--- a/libs/hwui/PathCache.h
+++ /dev/null
@@ -1,267 +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_PATH_CACHE_H
-#define ANDROID_HWUI_PATH_CACHE_H
-
-#include "Debug.h"
-#include "Texture.h"
-#include "hwui/Bitmap.h"
-#include "thread/Task.h"
-#include "thread/TaskProcessor.h"
-#include "utils/Macros.h"
-#include "utils/Pair.h"
-
-#include <GLES2/gl2.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-#include <utils/LruCache.h>
-#include <utils/Mutex.h>
-
-#include <vector>
-
-class SkCanvas;
-class SkPaint;
-struct SkRect;
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_PATHS
-#define PATH_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-#define PATH_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Classes
-///////////////////////////////////////////////////////////////////////////////
-
-struct PathTexture;
-class PathTask : public Task<sk_sp<Bitmap>> {
-public:
-    PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture)
-            : path(*path), paint(*paint), texture(texture) {}
-
-    // copied, since input path not guaranteed to survive for duration of task
-    const SkPath path;
-
-    // copied, since input paint may not be immutable
-    const SkPaint paint;
-    PathTexture* texture;
-};
-
-/**
- * Alpha texture used to represent a path.
- */
-struct PathTexture : public Texture {
-    PathTexture(Caches& caches, int generation) : Texture(caches) { this->generation = generation; }
-
-    ~PathTexture() { clearTask(); }
-
-    /**
-     * Left coordinate of the path bounds.
-     */
-    float left = 0;
-    /**
-     * Top coordinate of the path bounds.
-     */
-    float top = 0;
-    /**
-     * Offset to draw the path at the correct origin.
-     */
-    float offset = 0;
-
-    sp<PathTask> task() const { return mTask; }
-
-    void setTask(const sp<PathTask>& task) { mTask = task; }
-
-    void clearTask() {
-        if (mTask != nullptr) {
-            mTask.clear();
-        }
-    }
-
-private:
-    sp<PathTask> mTask;
-};  // struct PathTexture
-
-enum class ShapeType { None, Rect, RoundRect, Circle, Oval, Arc, Path };
-
-struct PathDescription {
-    HASHABLE_TYPE(PathDescription);
-    ShapeType type;
-    SkPaint::Join join;
-    SkPaint::Cap cap;
-    SkPaint::Style style;
-    float miter;
-    float strokeWidth;
-    SkPathEffect* pathEffect;
-    union Shape {
-        struct Path {
-            uint32_t mGenerationID;
-        } path;
-        struct RoundRect {
-            float mWidth;
-            float mHeight;
-            float mRx;
-            float mRy;
-        } roundRect;
-        struct Circle {
-            float mRadius;
-        } circle;
-        struct Oval {
-            float mWidth;
-            float mHeight;
-        } oval;
-        struct Rect {
-            float mWidth;
-            float mHeight;
-        } rect;
-        struct Arc {
-            float mWidth;
-            float mHeight;
-            float mStartAngle;
-            float mSweepAngle;
-            bool mUseCenter;
-        } arc;
-    } shape;
-
-    PathDescription();
-    PathDescription(ShapeType shapeType, const SkPaint* paint);
-};
-
-/**
- * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
- * Any texture added to the cache causing the cache to grow beyond the maximum
- * allowed size will also cause the oldest texture to be kicked out.
- */
-class PathCache : public OnEntryRemoved<PathDescription, PathTexture*> {
-public:
-    PathCache();
-    ~PathCache();
-
-    /**
-     * Used as a callback when an entry is removed from the cache.
-     * Do not invoke directly.
-     */
-    void operator()(PathDescription& path, PathTexture*& texture) override;
-
-    /**
-     * Clears the cache. This causes all textures to be deleted.
-     */
-    void clear();
-
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-    PathTexture* getRoundRect(float width, float height, float rx, float ry, const SkPaint* paint);
-    PathTexture* getCircle(float radius, const SkPaint* paint);
-    PathTexture* getOval(float width, float height, const SkPaint* paint);
-    PathTexture* getRect(float width, float height, const SkPaint* paint);
-    PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
-                        bool useCenter, const SkPaint* paint);
-    PathTexture* get(const SkPath* path, const SkPaint* paint);
-    void remove(const SkPath* path, const SkPaint* paint);
-
-    /**
-     * Removes the specified path. This is meant to be called from threads
-     * that are not the EGL context thread.
-     */
-    ANDROID_API void removeDeferred(const SkPath* path);
-    /**
-     * Process deferred removals.
-     */
-    void clearGarbage();
-    /**
-     * Trims the contents of the cache, removing items until it's under its
-     * specified limit.
-     *
-     * Trimming is used for caches that support pre-caching from a worker
-     * thread. During pre-caching the maximum limit of the cache can be
-     * exceeded for the duration of the frame. It is therefore required to
-     * trim the cache at the end of the frame to keep the total amount of
-     * memory used under control.
-     */
-    void trim();
-
-    /**
-     * Precaches the specified path using background threads.
-     */
-    void precache(const SkPath* path, const SkPaint* paint);
-
-private:
-    PathTexture* addTexture(const PathDescription& entry, const SkPath* path, const SkPaint* paint);
-
-    /**
-     * Generates the texture from a bitmap into the specified texture structure.
-     */
-    void generateTexture(Bitmap& bitmap, Texture* texture);
-    void generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
-                         bool addToCache = true);
-
-    PathTexture* get(const PathDescription& entry) { return mCache.get(entry); }
-
-    /**
-     * Ensures there is enough space in the cache for a texture of the specified
-     * dimensions.
-     */
-    void purgeCache(uint32_t width, uint32_t height);
-
-    void removeTexture(PathTexture* texture);
-
-    void init();
-
-    class PathProcessor : public TaskProcessor<sk_sp<Bitmap>> {
-    public:
-        explicit PathProcessor(Caches& caches);
-        ~PathProcessor() {}
-
-        virtual void onProcess(const sp<Task<sk_sp<Bitmap>>>& task) override;
-
-    private:
-        uint32_t mMaxTextureSize;
-    };
-
-    LruCache<PathDescription, PathTexture*> mCache;
-    uint32_t mSize;
-    const uint32_t mMaxSize;
-    GLuint mMaxTextureSize;
-
-    bool mDebugEnabled;
-
-    sp<PathProcessor> mProcessor;
-
-    std::vector<uint32_t> mGarbage;
-    mutable Mutex mLock;
-};  // class PathCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_PATH_CACHE_H
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
deleted file mode 100644
index 2839ed7..0000000
--- a/libs/hwui/ProgramCache.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
- * Copyright (C) 2010 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 <utils/String8.h>
-
-#include "Caches.h"
-#include "ProgramCache.h"
-#include "Properties.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-#define MODULATE_OP_NO_MODULATE 0
-#define MODULATE_OP_MODULATE 1
-#define MODULATE_OP_MODULATE_A8 2
-
-#define STR(x) STR1(x)
-#define STR1(x) #x
-
-///////////////////////////////////////////////////////////////////////////////
-// Vertex shaders snippets
-///////////////////////////////////////////////////////////////////////////////
-
-const char* gVS_Header_Start =
-        "#version 100\n"
-        "attribute vec4 position;\n";
-const char* gVS_Header_Attributes_TexCoords = "attribute vec2 texCoords;\n";
-const char* gVS_Header_Attributes_Colors = "attribute vec4 colors;\n";
-const char* gVS_Header_Attributes_VertexAlphaParameters = "attribute float vtxAlpha;\n";
-const char* gVS_Header_Uniforms_TextureTransform = "uniform mat4 mainTextureTransform;\n";
-const char* gVS_Header_Uniforms =
-        "uniform mat4 projection;\n"
-        "uniform mat4 transform;\n";
-const char* gVS_Header_Uniforms_HasGradient = "uniform mat4 screenSpace;\n";
-const char* gVS_Header_Uniforms_HasBitmap =
-        "uniform mat4 textureTransform;\n"
-        "uniform mediump vec2 textureDimension;\n";
-const char* gVS_Header_Uniforms_HasRoundRectClip =
-        "uniform mat4 roundRectInvTransform;\n"
-        "uniform mediump vec4 roundRectInnerRectLTWH;\n"
-        "uniform mediump float roundRectRadius;\n";
-const char* gVS_Header_Varyings_HasTexture = "varying highp vec2 outTexCoords;\n";
-const char* gVS_Header_Varyings_HasColors = "varying vec4 outColors;\n";
-const char* gVS_Header_Varyings_HasVertexAlpha = "varying float alpha;\n";
-const char* gVS_Header_Varyings_HasBitmap = "varying highp vec2 outBitmapTexCoords;\n";
-const char* gVS_Header_Varyings_HasGradient[6] = {
-        // Linear
-        "varying highp vec2 linear;\n", "varying float linear;\n",
-
-        // Circular
-        "varying highp vec2 circular;\n", "varying highp vec2 circular;\n",
-
-        // Sweep
-        "varying highp vec2 sweep;\n", "varying highp vec2 sweep;\n",
-};
-const char* gVS_Header_Varyings_HasRoundRectClip = "varying mediump vec2 roundRectPos;\n";
-const char* gVS_Main = "\nvoid main(void) {\n";
-const char* gVS_Main_OutTexCoords = "    outTexCoords = texCoords;\n";
-const char* gVS_Main_OutColors = "    outColors = colors;\n";
-const char* gVS_Main_OutTransformedTexCoords =
-        "    outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n";
-const char* gVS_Main_OutGradient[6] = {
-        // Linear
-        "    linear = vec2((screenSpace * position).x, 0.5);\n",
-        "    linear = (screenSpace * position).x;\n",
-
-        // Circular
-        "    circular = (screenSpace * position).xy;\n",
-        "    circular = (screenSpace * position).xy;\n",
-
-        // Sweep
-        "    sweep = (screenSpace * position).xy;\n", "    sweep = (screenSpace * position).xy;\n"};
-const char* gVS_Main_OutBitmapTexCoords =
-        "    outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
-const char* gVS_Main_Position =
-        "    vec4 transformedPosition = projection * transform * position;\n"
-        "    gl_Position = transformedPosition;\n";
-
-const char* gVS_Main_VertexAlpha = "    alpha = vtxAlpha;\n";
-
-const char* gVS_Main_HasRoundRectClip =
-        "    roundRectPos = ((roundRectInvTransform * transformedPosition).xy / roundRectRadius) - "
-        "roundRectInnerRectLTWH.xy;\n";
-const char* gVS_Footer = "}\n\n";
-
-///////////////////////////////////////////////////////////////////////////////
-// Fragment shaders snippets
-///////////////////////////////////////////////////////////////////////////////
-
-const char* gFS_Header_Start = "#version 100\n";
-const char* gFS_Header_Extension_FramebufferFetch =
-        "#extension GL_NV_shader_framebuffer_fetch : enable\n\n";
-const char* gFS_Header_Extension_ExternalTexture =
-        "#extension GL_OES_EGL_image_external : require\n\n";
-const char* gFS_Header = "precision mediump float;\n\n";
-const char* gFS_Uniforms_Color = "uniform vec4 color;\n";
-const char* gFS_Uniforms_TextureSampler = "uniform sampler2D baseSampler;\n";
-const char* gFS_Uniforms_ExternalTextureSampler = "uniform samplerExternalOES baseSampler;\n";
-const char* gFS_Uniforms_GradientSampler[2] = {
-        "uniform vec2 screenSize;\n"
-        "uniform sampler2D gradientSampler;\n",
-
-        "uniform vec2 screenSize;\n"
-        "uniform vec4 startColor;\n"
-        "uniform vec4 endColor;\n"};
-const char* gFS_Uniforms_BitmapSampler = "uniform sampler2D bitmapSampler;\n";
-const char* gFS_Uniforms_BitmapExternalSampler = "uniform samplerExternalOES bitmapSampler;\n";
-const char* gFS_Uniforms_ColorOp[3] = {
-        // None
-        "",
-        // Matrix
-        "uniform mat4 colorMatrix;\n"
-        "uniform vec4 colorMatrixVector;\n",
-        // PorterDuff
-        "uniform vec4 colorBlend;\n"};
-
-const char* gFS_Uniforms_HasRoundRectClip =
-        "uniform mediump vec4 roundRectInnerRectLTWH;\n"
-        "uniform mediump float roundRectRadius;\n";
-
-const char* gFS_Uniforms_ColorSpaceConversion =
-        // TODO: Should we use a 3D LUT to combine the matrix and transfer functions?
-        // 32x32x32 fp16 LUTs (for scRGB output) are large and heavy to generate...
-        "uniform mat3 colorSpaceMatrix;\n";
-
-const char* gFS_Uniforms_TransferFunction[4] = {
-        // In this order: g, a, b, c, d, e, f
-        // See ColorSpace::TransferParameters
-        // We'll use hardware sRGB conversion as much as possible
-        "", "uniform float transferFunction[7];\n", "uniform float transferFunction[5];\n",
-        "uniform float transferFunctionGamma;\n"};
-
-const char* gFS_OETF[2] = {
-        R"__SHADER__(
-        vec4 OETF(const vec4 linear) {
-            return linear;
-        }
-        )__SHADER__",
-        // We expect linear data to be scRGB so we mirror the gamma function
-        R"__SHADER__(
-        vec4 OETF(const vec4 linear) {
-            return vec4(sign(linear.rgb) * OETF_sRGB(abs(linear.rgb)), linear.a);
-        }
-        )__SHADER__"};
-
-const char* gFS_ColorConvert[3] = {
-        // Just OETF
-        R"__SHADER__(
-        vec4 colorConvert(const vec4 color) {
-            return OETF(color);
-        }
-        )__SHADER__",
-        // Full color conversion for opaque bitmaps
-        R"__SHADER__(
-        vec4 colorConvert(const vec4 color) {
-            return OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a));
-        }
-        )__SHADER__",
-        // Full color conversion for translucent bitmaps
-        // Note: 0.5/256=0.0019
-        R"__SHADER__(
-        vec4 colorConvert(in vec4 color) {
-            color.rgb /= color.a + 0.0019;
-            color = OETF(vec4(colorSpaceMatrix * EOTF_Parametric(color.rgb), color.a));
-            color.rgb *= color.a + 0.0019;
-            return color;
-        }
-        )__SHADER__",
-};
-
-const char* gFS_sRGB_TransferFunctions = R"__SHADER__(
-        float OETF_sRGB(const float linear) {
-            // IEC 61966-2-1:1999
-            return linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1.0 / 2.4) * 1.055) - 0.055;
-        }
-
-        vec3 OETF_sRGB(const vec3 linear) {
-            return vec3(OETF_sRGB(linear.r), OETF_sRGB(linear.g), OETF_sRGB(linear.b));
-        }
-
-        float EOTF_sRGB(float srgb) {
-            // IEC 61966-2-1:1999
-            return srgb <= 0.04045 ? srgb / 12.92 : pow((srgb + 0.055) / 1.055, 2.4);
-        }
-)__SHADER__";
-
-const char* gFS_TransferFunction[4] = {
-        // Conversion done by the texture unit (sRGB)
-        R"__SHADER__(
-        vec3 EOTF_Parametric(const vec3 x) {
-            return x;
-        }
-        )__SHADER__",
-        // Full transfer function
-        // TODO: We should probably use a 1D LUT (256x1 with texelFetch() since input is 8 bit)
-        // TODO: That would cause 3 dependent texture fetches. Is it worth it?
-        R"__SHADER__(
-        float EOTF_Parametric(float x) {
-            return x <= transferFunction[4]
-                  ? transferFunction[3] * x + transferFunction[6]
-                  : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0])
-                          + transferFunction[5];
-        }
-
-        vec3 EOTF_Parametric(const vec3 x) {
-            return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b));
-        }
-        )__SHADER__",
-        // Limited transfer function, e = f = 0.0
-        R"__SHADER__(
-        float EOTF_Parametric(float x) {
-            return x <= transferFunction[4]
-                  ? transferFunction[3] * x
-                  : pow(transferFunction[1] * x + transferFunction[2], transferFunction[0]);
-        }
-
-        vec3 EOTF_Parametric(const vec3 x) {
-            return vec3(EOTF_Parametric(x.r), EOTF_Parametric(x.g), EOTF_Parametric(x.b));
-        }
-        )__SHADER__",
-        // Gamma transfer function, e = f = 0.0
-        R"__SHADER__(
-        vec3 EOTF_Parametric(const vec3 x) {
-            return vec3(pow(x.r, transferFunctionGamma),
-                        pow(x.g, transferFunctionGamma),
-                        pow(x.b, transferFunctionGamma));
-        }
-        )__SHADER__"};
-
-// Dithering must be done in the quantization space
-// When we are writing to an sRGB framebuffer, we must do the following:
-//     EOTF(OETF(color) + dither)
-// The dithering pattern is generated with a triangle noise generator in the range [-1.0,1.0]
-// TODO: Handle linear fp16 render targets
-const char* gFS_GradientFunctions = R"__SHADER__(
-        float triangleNoise(const highp vec2 n) {
-            highp vec2 p = fract(n * vec2(5.3987, 5.4421));
-            p += dot(p.yx, p.xy + vec2(21.5351, 14.3137));
-            highp float xy = p.x * p.y;
-            return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
-        }
-)__SHADER__";
-
-const char* gFS_GradientPreamble[2] = {
-        // Linear framebuffer
-        R"__SHADER__(
-        vec4 dither(const vec4 color) {
-            return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
-        }
-        )__SHADER__",
-        // sRGB framebuffer
-        R"__SHADER__(
-        vec4 dither(const vec4 color) {
-            vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
-            return vec4(dithered * dithered, color.a);
-        }
-        )__SHADER__",
-};
-
-// Uses luminance coefficients from Rec.709 to choose the appropriate gamma
-// The gamma() function assumes that bright text will be displayed on a dark
-// background and that dark text will be displayed on bright background
-// The gamma coefficient is chosen to thicken or thin the text accordingly
-// The dot product used to compute the luminance could be approximated with
-// a simple max(color.r, color.g, color.b)
-const char* gFS_Gamma_Preamble = R"__SHADER__(
-        #define GAMMA (%.2f)
-        #define GAMMA_INV (%.2f)
-
-        float gamma(float a, const vec3 color) {
-            float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
-            return pow(a, luminance < 0.5 ? GAMMA_INV : GAMMA);
-        }
-)__SHADER__";
-
-const char* gFS_Main =
-        "\nvoid main(void) {\n"
-        "    vec4 fragColor;\n";
-
-const char* gFS_Main_AddDither = "    fragColor = dither(fragColor);\n";
-
-// General case
-const char* gFS_Main_FetchColor = "    fragColor = color;\n";
-const char* gFS_Main_ModulateColor = "    fragColor *= color.a;\n";
-const char* gFS_Main_ApplyVertexAlphaLinearInterp = "    fragColor *= alpha;\n";
-const char* gFS_Main_ApplyVertexAlphaShadowInterp =
-        // map alpha through shadow alpha sampler
-        "    fragColor *= texture2D(baseSampler, vec2(alpha, 0.5)).a;\n";
-const char* gFS_Main_FetchTexture[2] = {
-        // Don't modulate
-        "    fragColor = colorConvert(texture2D(baseSampler, outTexCoords));\n",
-        // Modulate
-        "    fragColor = color * colorConvert(texture2D(baseSampler, outTexCoords));\n"};
-const char* gFS_Main_FetchA8Texture[4] = {
-        // Don't modulate
-        "    fragColor = texture2D(baseSampler, outTexCoords);\n",
-        "    fragColor = texture2D(baseSampler, outTexCoords);\n",
-        // Modulate
-        "    fragColor = color * texture2D(baseSampler, outTexCoords).a;\n",
-        "    fragColor = color * gamma(texture2D(baseSampler, outTexCoords).a, color.rgb);\n",
-};
-const char* gFS_Main_FetchGradient[6] = {
-        // Linear
-        "    vec4 gradientColor = texture2D(gradientSampler, linear);\n",
-
-        "    vec4 gradientColor = mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
-
-        // Circular
-        "    vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
-
-        "    vec4 gradientColor = mix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
-
-        // Sweep
-        "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
-        "    vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n",
-
-        "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
-        "    vec4 gradientColor = mix(startColor, endColor, clamp(index - floor(index), 0.0, "
-        "1.0));\n"};
-const char* gFS_Main_FetchBitmap =
-        "    vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, outBitmapTexCoords));\n";
-const char* gFS_Main_FetchBitmapNpot =
-        "    vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, "
-        "wrap(outBitmapTexCoords)));\n";
-const char* gFS_Main_BlendShadersBG = "    fragColor = blendShaders(gradientColor, bitmapColor)";
-const char* gFS_Main_BlendShadersGB = "    fragColor = blendShaders(bitmapColor, gradientColor)";
-const char* gFS_Main_BlendShaders_Modulate[6] = {
-        // Don't modulate
-        ";\n", ";\n",
-        // Modulate
-        " * color.a;\n", " * color.a;\n",
-        // Modulate with alpha 8 texture
-        " * texture2D(baseSampler, outTexCoords).a;\n",
-        " * gamma(texture2D(baseSampler, outTexCoords).a, color.rgb);\n",
-};
-const char* gFS_Main_GradientShader_Modulate[6] = {
-        // Don't modulate
-        "    fragColor = gradientColor;\n", "    fragColor = gradientColor;\n",
-        // Modulate
-        "    fragColor = gradientColor * color.a;\n", "    fragColor = gradientColor * color.a;\n",
-        // Modulate with alpha 8 texture
-        "    fragColor = gradientColor * texture2D(baseSampler, outTexCoords).a;\n",
-        "    fragColor = gradientColor * gamma(texture2D(baseSampler, outTexCoords).a, "
-        "gradientColor.rgb);\n",
-};
-const char* gFS_Main_BitmapShader_Modulate[6] = {
-        // Don't modulate
-        "    fragColor = bitmapColor;\n", "    fragColor = bitmapColor;\n",
-        // Modulate
-        "    fragColor = bitmapColor * color.a;\n", "    fragColor = bitmapColor * color.a;\n",
-        // Modulate with alpha 8 texture
-        "    fragColor = bitmapColor * texture2D(baseSampler, outTexCoords).a;\n",
-        "    fragColor = bitmapColor * gamma(texture2D(baseSampler, outTexCoords).a, "
-        "bitmapColor.rgb);\n",
-};
-const char* gFS_Main_FragColor = "    gl_FragColor = fragColor;\n";
-const char* gFS_Main_FragColor_HasColors = "    gl_FragColor *= outColors;\n";
-const char* gFS_Main_FragColor_Blend =
-        "    gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n";
-const char* gFS_Main_FragColor_Blend_Swap =
-        "    gl_FragColor = blendFramebuffer(gl_LastFragColor, fragColor);\n";
-const char* gFS_Main_ApplyColorOp[3] = {
-        // None
-        "",
-        // Matrix
-        "    fragColor.rgb /= (fragColor.a + 0.0019);\n"  // un-premultiply
-        "    fragColor *= colorMatrix;\n"
-        "    fragColor += colorMatrixVector;\n"
-        "    fragColor.rgb *= (fragColor.a + 0.0019);\n",  // re-premultiply
-        // PorterDuff
-        "    fragColor = blendColors(colorBlend, fragColor);\n"};
-
-// Note: LTWH (left top width height) -> xyzw
-// roundRectPos is now divided by roundRectRadius in vertex shader
-// after we also subtract roundRectInnerRectLTWH.xy from roundRectPos
-const char* gFS_Main_FragColor_HasRoundRectClip =
-        "    mediump vec2 fragToLT = -roundRectPos;\n"
-        "    mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTWH.zw;\n"
-
-        // since distance is divided by radius, it's in [0;1] so precision is not an issue
-        // this also lets us clamp(0.0, 1.0) instead of max() which is cheaper on GPUs
-        "    mediump vec2 dist = clamp(max(fragToLT, fragFromRB), 0.0, 1.0);\n"
-        "    mediump float linearDist = clamp(roundRectRadius - (length(dist) * roundRectRadius), "
-        "0.0, 1.0);\n"
-        "    gl_FragColor *= linearDist;\n";
-
-const char* gFS_Main_DebugHighlight = "    gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n";
-const char* gFS_Footer = "}\n\n";
-
-///////////////////////////////////////////////////////////////////////////////
-// PorterDuff snippets
-///////////////////////////////////////////////////////////////////////////////
-
-const char* gBlendOps[18] = {
-        // Clear
-        "return vec4(0.0, 0.0, 0.0, 0.0);\n",
-        // Src
-        "return src;\n",
-        // Dst
-        "return dst;\n",
-        // SrcOver
-        "return src + dst * (1.0 - src.a);\n",
-        // DstOver
-        "return dst + src * (1.0 - dst.a);\n",
-        // SrcIn
-        "return src * dst.a;\n",
-        // DstIn
-        "return dst * src.a;\n",
-        // SrcOut
-        "return src * (1.0 - dst.a);\n",
-        // DstOut
-        "return dst * (1.0 - src.a);\n",
-        // SrcAtop
-        "return vec4(src.rgb * dst.a + (1.0 - src.a) * dst.rgb, dst.a);\n",
-        // DstAtop
-        "return vec4(dst.rgb * src.a + (1.0 - dst.a) * src.rgb, src.a);\n",
-        // Xor
-        "return vec4(src.rgb * (1.0 - dst.a) + (1.0 - src.a) * dst.rgb, "
-        "src.a + dst.a - 2.0 * src.a * dst.a);\n",
-        // Plus
-        "return min(src + dst, 1.0);\n",
-        // Modulate
-        "return src * dst;\n",
-        // Screen
-        "return src + dst - src * dst;\n",
-        // Overlay
-        "return clamp(vec4(mix("
-        "2.0 * src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a), "
-        "src.a * dst.a - 2.0 * (dst.a - dst.rgb) * (src.a - src.rgb) + src.rgb * (1.0 - dst.a) + "
-        "dst.rgb * (1.0 - src.a), "
-        "step(dst.a, 2.0 * dst.rgb)), "
-        "src.a + dst.a - src.a * dst.a), 0.0, 1.0);\n",
-        // Darken
-        "return vec4(src.rgb * (1.0 - dst.a) + (1.0 - src.a) * dst.rgb + "
-        "min(src.rgb * dst.a, dst.rgb * src.a), src.a + dst.a - src.a * dst.a);\n",
-        // Lighten
-        "return vec4(src.rgb * (1.0 - dst.a) + (1.0 - src.a) * dst.rgb + "
-        "max(src.rgb * dst.a, dst.rgb * src.a), src.a + dst.a - src.a * dst.a);\n",
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructors
-///////////////////////////////////////////////////////////////////////////////
-
-ProgramCache::ProgramCache(const Extensions& extensions)
-        : mHasES3(extensions.getMajorGlVersion() >= 3)
-        , mHasLinearBlending(extensions.hasLinearBlending()) {}
-
-ProgramCache::~ProgramCache() {
-    clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache management
-///////////////////////////////////////////////////////////////////////////////
-
-void ProgramCache::clear() {
-    PROGRAM_LOGD("Clearing program cache");
-    mCache.clear();
-}
-
-Program* ProgramCache::get(const ProgramDescription& description) {
-    programid key = description.key();
-    if (key == (PROGRAM_KEY_TEXTURE | PROGRAM_KEY_A8_TEXTURE)) {
-        // program for A8, unmodulated, texture w/o shader (black text/path textures) is equivalent
-        // to standard texture program (bitmaps, patches). Consider them equivalent.
-        key = PROGRAM_KEY_TEXTURE;
-    }
-
-    auto iter = mCache.find(key);
-    Program* program = nullptr;
-    if (iter == mCache.end()) {
-        description.log("Could not find program");
-        program = generateProgram(description, key);
-        mCache[key] = std::unique_ptr<Program>(program);
-    } else {
-        program = iter->second.get();
-    }
-    return program;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Program generation
-///////////////////////////////////////////////////////////////////////////////
-
-Program* ProgramCache::generateProgram(const ProgramDescription& description, programid key) {
-    String8 vertexShader = generateVertexShader(description);
-    String8 fragmentShader = generateFragmentShader(description);
-
-    return new Program(description, vertexShader.string(), fragmentShader.string());
-}
-
-static inline size_t gradientIndex(const ProgramDescription& description) {
-    return description.gradientType * 2 + description.isSimpleGradient;
-}
-
-String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
-    // Add attributes
-    String8 shader(gVS_Header_Start);
-    if (description.hasTexture || description.hasExternalTexture) {
-        shader.append(gVS_Header_Attributes_TexCoords);
-    }
-    if (description.hasVertexAlpha) {
-        shader.append(gVS_Header_Attributes_VertexAlphaParameters);
-    }
-    if (description.hasColors) {
-        shader.append(gVS_Header_Attributes_Colors);
-    }
-    // Uniforms
-    shader.append(gVS_Header_Uniforms);
-    if (description.hasTextureTransform) {
-        shader.append(gVS_Header_Uniforms_TextureTransform);
-    }
-    if (description.hasGradient) {
-        shader.append(gVS_Header_Uniforms_HasGradient);
-    }
-    if (description.hasBitmap) {
-        shader.append(gVS_Header_Uniforms_HasBitmap);
-    }
-    if (description.hasRoundRectClip) {
-        shader.append(gVS_Header_Uniforms_HasRoundRectClip);
-    }
-    // Varyings
-    if (description.hasTexture || description.hasExternalTexture) {
-        shader.append(gVS_Header_Varyings_HasTexture);
-    }
-    if (description.hasVertexAlpha) {
-        shader.append(gVS_Header_Varyings_HasVertexAlpha);
-    }
-    if (description.hasColors) {
-        shader.append(gVS_Header_Varyings_HasColors);
-    }
-    if (description.hasGradient) {
-        shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
-    }
-    if (description.hasBitmap) {
-        shader.append(gVS_Header_Varyings_HasBitmap);
-    }
-    if (description.hasRoundRectClip) {
-        shader.append(gVS_Header_Varyings_HasRoundRectClip);
-    }
-
-    // Begin the shader
-    shader.append(gVS_Main);
-    {
-        if (description.hasTextureTransform) {
-            shader.append(gVS_Main_OutTransformedTexCoords);
-        } else if (description.hasTexture || description.hasExternalTexture) {
-            shader.append(gVS_Main_OutTexCoords);
-        }
-        if (description.hasVertexAlpha) {
-            shader.append(gVS_Main_VertexAlpha);
-        }
-        if (description.hasColors) {
-            shader.append(gVS_Main_OutColors);
-        }
-        if (description.hasBitmap) {
-            shader.append(gVS_Main_OutBitmapTexCoords);
-        }
-        // Output transformed position
-        shader.append(gVS_Main_Position);
-        if (description.hasGradient) {
-            shader.append(gVS_Main_OutGradient[gradientIndex(description)]);
-        }
-        if (description.hasRoundRectClip) {
-            shader.append(gVS_Main_HasRoundRectClip);
-        }
-    }
-    // End the shader
-    shader.append(gVS_Footer);
-
-    PROGRAM_LOGD("*** Generated vertex shader:\n\n%s", shader.string());
-
-    return shader;
-}
-
-static bool shaderOp(const ProgramDescription& description, String8& shader, const int modulateOp,
-                     const char** snippets) {
-    int op = description.hasAlpha8Texture ? MODULATE_OP_MODULATE_A8 : modulateOp;
-    op = op * 2 + description.hasGammaCorrection;
-    shader.append(snippets[op]);
-    return description.hasAlpha8Texture;
-}
-
-String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
-    String8 shader(gFS_Header_Start);
-
-    const bool blendFramebuffer = description.framebufferMode >= SkBlendMode::kPlus;
-    if (blendFramebuffer) {
-        shader.append(gFS_Header_Extension_FramebufferFetch);
-    }
-    if (description.hasExternalTexture ||
-        (description.hasBitmap && description.isShaderBitmapExternal)) {
-        shader.append(gFS_Header_Extension_ExternalTexture);
-    }
-
-    shader.append(gFS_Header);
-
-    // Varyings
-    if (description.hasTexture || description.hasExternalTexture) {
-        shader.append(gVS_Header_Varyings_HasTexture);
-    }
-    if (description.hasVertexAlpha) {
-        shader.append(gVS_Header_Varyings_HasVertexAlpha);
-    }
-    if (description.hasColors) {
-        shader.append(gVS_Header_Varyings_HasColors);
-    }
-    if (description.hasGradient) {
-        shader.append(gVS_Header_Varyings_HasGradient[gradientIndex(description)]);
-    }
-    if (description.hasBitmap) {
-        shader.append(gVS_Header_Varyings_HasBitmap);
-    }
-    if (description.hasRoundRectClip) {
-        shader.append(gVS_Header_Varyings_HasRoundRectClip);
-    }
-
-    // Uniforms
-    int modulateOp = MODULATE_OP_NO_MODULATE;
-    const bool singleColor = !description.hasTexture && !description.hasExternalTexture &&
-                             !description.hasGradient && !description.hasBitmap;
-
-    if (description.modulate || singleColor) {
-        shader.append(gFS_Uniforms_Color);
-        if (!singleColor) modulateOp = MODULATE_OP_MODULATE;
-    }
-    if (description.hasTexture || description.useShadowAlphaInterp) {
-        shader.append(gFS_Uniforms_TextureSampler);
-    } else if (description.hasExternalTexture) {
-        shader.append(gFS_Uniforms_ExternalTextureSampler);
-    }
-    if (description.hasGradient) {
-        shader.append(gFS_Uniforms_GradientSampler[description.isSimpleGradient]);
-    }
-    if (description.hasRoundRectClip) {
-        shader.append(gFS_Uniforms_HasRoundRectClip);
-    }
-
-    if (description.hasGammaCorrection) {
-        shader.appendFormat(gFS_Gamma_Preamble, Properties::textGamma,
-                            1.0f / Properties::textGamma);
-    }
-
-    if (description.hasBitmap) {
-        if (description.isShaderBitmapExternal) {
-            shader.append(gFS_Uniforms_BitmapExternalSampler);
-        } else {
-            shader.append(gFS_Uniforms_BitmapSampler);
-        }
-    }
-    shader.append(gFS_Uniforms_ColorOp[static_cast<int>(description.colorOp)]);
-
-    if (description.hasColorSpaceConversion) {
-        shader.append(gFS_Uniforms_ColorSpaceConversion);
-    }
-    shader.append(gFS_Uniforms_TransferFunction[static_cast<int>(description.transferFunction)]);
-
-    // Generate required functions
-    if (description.hasGradient && description.hasBitmap) {
-        generateBlend(shader, "blendShaders", description.shadersMode);
-    }
-    if (description.colorOp == ProgramDescription::ColorFilterMode::Blend) {
-        generateBlend(shader, "blendColors", description.colorMode);
-    }
-    if (blendFramebuffer) {
-        generateBlend(shader, "blendFramebuffer", description.framebufferMode);
-    }
-    if (description.useShaderBasedWrap) {
-        generateTextureWrap(shader, description.bitmapWrapS, description.bitmapWrapT);
-    }
-    if (description.hasGradient || description.hasLinearTexture ||
-        description.hasColorSpaceConversion) {
-        shader.append(gFS_sRGB_TransferFunctions);
-    }
-    if (description.hasBitmap || ((description.hasTexture || description.hasExternalTexture) &&
-                                  !description.hasAlpha8Texture)) {
-        shader.append(gFS_TransferFunction[static_cast<int>(description.transferFunction)]);
-        shader.append(
-                gFS_OETF[(description.hasLinearTexture || description.hasColorSpaceConversion) &&
-                         !mHasLinearBlending]);
-        shader.append(gFS_ColorConvert[description.hasColorSpaceConversion
-                                               ? 1 + description.hasTranslucentConversion
-                                               : 0]);
-    }
-    if (description.hasGradient) {
-        shader.append(gFS_GradientFunctions);
-        shader.append(gFS_GradientPreamble[mHasLinearBlending]);
-    }
-
-    // Begin the shader
-    shader.append(gFS_Main);
-    {
-        // Stores the result in fragColor directly
-        if (description.hasTexture || description.hasExternalTexture) {
-            if (description.hasAlpha8Texture) {
-                if (!description.hasGradient && !description.hasBitmap) {
-                    shader.append(gFS_Main_FetchA8Texture[modulateOp * 2 +
-                                                          description.hasGammaCorrection]);
-                }
-            } else {
-                shader.append(gFS_Main_FetchTexture[modulateOp]);
-            }
-        } else {
-            if (!description.hasGradient && !description.hasBitmap) {
-                shader.append(gFS_Main_FetchColor);
-            }
-        }
-        if (description.hasGradient) {
-            shader.append(gFS_Main_FetchGradient[gradientIndex(description)]);
-        }
-        if (description.hasBitmap) {
-            if (!description.useShaderBasedWrap) {
-                shader.append(gFS_Main_FetchBitmap);
-            } else {
-                shader.append(gFS_Main_FetchBitmapNpot);
-            }
-        }
-        bool applyModulate = false;
-        // Case when we have two shaders set
-        if (description.hasGradient && description.hasBitmap) {
-            if (description.isBitmapFirst) {
-                shader.append(gFS_Main_BlendShadersBG);
-            } else {
-                shader.append(gFS_Main_BlendShadersGB);
-            }
-            applyModulate =
-                    shaderOp(description, shader, modulateOp, gFS_Main_BlendShaders_Modulate);
-        } else {
-            if (description.hasGradient) {
-                applyModulate =
-                        shaderOp(description, shader, modulateOp, gFS_Main_GradientShader_Modulate);
-            } else if (description.hasBitmap) {
-                applyModulate =
-                        shaderOp(description, shader, modulateOp, gFS_Main_BitmapShader_Modulate);
-            }
-        }
-
-        if (description.modulate && applyModulate) {
-            shader.append(gFS_Main_ModulateColor);
-        }
-
-        // Apply the color op if needed
-        shader.append(gFS_Main_ApplyColorOp[static_cast<int>(description.colorOp)]);
-
-        if (description.hasVertexAlpha) {
-            if (description.useShadowAlphaInterp) {
-                shader.append(gFS_Main_ApplyVertexAlphaShadowInterp);
-            } else {
-                shader.append(gFS_Main_ApplyVertexAlphaLinearInterp);
-            }
-        }
-
-        if (description.hasGradient) {
-            shader.append(gFS_Main_AddDither);
-        }
-
-        // Output the fragment
-        if (!blendFramebuffer) {
-            shader.append(gFS_Main_FragColor);
-        } else {
-            shader.append(!description.swapSrcDst ? gFS_Main_FragColor_Blend
-                                                  : gFS_Main_FragColor_Blend_Swap);
-        }
-        if (description.hasColors) {
-            shader.append(gFS_Main_FragColor_HasColors);
-        }
-        if (description.hasRoundRectClip) {
-            shader.append(gFS_Main_FragColor_HasRoundRectClip);
-        }
-        if (description.hasDebugHighlight) {
-            shader.append(gFS_Main_DebugHighlight);
-        }
-    }
-    // End the shader
-    shader.append(gFS_Footer);
-
-#if DEBUG_PROGRAMS
-    PROGRAM_LOGD("*** Generated fragment shader:\n\n");
-    printLongString(shader);
-#endif
-
-    return shader;
-}
-
-void ProgramCache::generateBlend(String8& shader, const char* name, SkBlendMode mode) {
-    shader.append("\nvec4 ");
-    shader.append(name);
-    shader.append("(vec4 src, vec4 dst) {\n");
-    shader.append("    ");
-    shader.append(gBlendOps[(int)mode]);
-    shader.append("}\n");
-}
-
-void ProgramCache::generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT) {
-    shader.append("\nhighp vec2 wrap(highp vec2 texCoords) {\n");
-    if (wrapS == GL_MIRRORED_REPEAT) {
-        shader.append("    highp float xMod2 = mod(texCoords.x, 2.0);\n");
-        shader.append("    if (xMod2 > 1.0) xMod2 = 2.0 - xMod2;\n");
-    }
-    if (wrapT == GL_MIRRORED_REPEAT) {
-        shader.append("    highp float yMod2 = mod(texCoords.y, 2.0);\n");
-        shader.append("    if (yMod2 > 1.0) yMod2 = 2.0 - yMod2;\n");
-    }
-    shader.append("    return vec2(");
-    switch (wrapS) {
-        case GL_CLAMP_TO_EDGE:
-            shader.append("texCoords.x");
-            break;
-        case GL_REPEAT:
-            shader.append("mod(texCoords.x, 1.0)");
-            break;
-        case GL_MIRRORED_REPEAT:
-            shader.append("xMod2");
-            break;
-    }
-    shader.append(", ");
-    switch (wrapT) {
-        case GL_CLAMP_TO_EDGE:
-            shader.append("texCoords.y");
-            break;
-        case GL_REPEAT:
-            shader.append("mod(texCoords.y, 1.0)");
-            break;
-        case GL_MIRRORED_REPEAT:
-            shader.append("yMod2");
-            break;
-    }
-    shader.append(");\n");
-    shader.append("}\n");
-}
-
-void ProgramCache::printLongString(const String8& shader) const {
-    ssize_t index = 0;
-    ssize_t lastIndex = 0;
-    const char* str = shader.string();
-    while ((index = shader.find("\n", index)) > -1) {
-        String8 line(str, index - lastIndex);
-        if (line.length() == 0) line.append("\n");
-        ALOGD("%s", line.string());
-        index++;
-        str += (index - lastIndex);
-        lastIndex = index;
-    }
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
deleted file mode 100644
index 488a499..0000000
--- a/libs/hwui/ProgramCache.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 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_PROGRAM_CACHE_H
-#define ANDROID_HWUI_PROGRAM_CACHE_H
-
-#include <utils/KeyedVector.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <map>
-
-#include <GLES2/gl2.h>
-
-#include "Debug.h"
-#include "Program.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Generates and caches program. Programs are generated based on
- * ProgramDescriptions.
- */
-class ProgramCache {
-public:
-    explicit ProgramCache(const Extensions& extensions);
-    ~ProgramCache();
-
-    Program* get(const ProgramDescription& description);
-
-    void clear();
-
-private:
-    Program* generateProgram(const ProgramDescription& description, programid key);
-    String8 generateVertexShader(const ProgramDescription& description);
-    String8 generateFragmentShader(const ProgramDescription& description);
-    void generateBlend(String8& shader, const char* name, SkBlendMode mode);
-    void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
-
-    void printLongString(const String8& shader) const;
-
-    std::map<programid, std::unique_ptr<Program>> mCache;
-
-    const bool mHasES3;
-    const bool mHasLinearBlending;
-};  // class ProgramCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_PROGRAM_CACHE_H
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index f514691..a8f105d 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -20,7 +20,6 @@
 #include "Matrix.h"
 #include "Rect.h"
 #include "RenderNode.h"
-#include "TessellationCache.h"
 #include "Vector.h"
 #include "utils/LinearAllocator.h"
 #include "utils/PaintUtils.h"
@@ -84,7 +83,6 @@
     PRE_RENDER_OP_FN(EndUnclippedLayerOp)                                             \
     PRE_RENDER_OP_FN(VectorDrawableOp)                                                \
                                                                                       \
-    RENDER_ONLY_OP_FN(ShadowOp)                                                       \
     RENDER_ONLY_OP_FN(LayerOp)                                                        \
     RENDER_ONLY_OP_FN(CopyToLayerOp)                                                  \
     RENDER_ONLY_OP_FN(CopyFromLayerOp)                                                \
@@ -333,23 +331,6 @@
     VectorDrawable::Tree* vectorDrawable;
 };
 
-/**
- * Real-time, dynamic-lit shadow.
- *
- * Uses invalid/empty bounds and matrix since ShadowOp bounds aren't known at defer time,
- * and are resolved dynamically, and transform isn't needed.
- *
- * State construction handles these properties specially, ignoring matrix/bounds.
- */
-struct ShadowOp : RecordedOp {
-    ShadowOp(sp<TessellationCache::ShadowTask>& shadowTask, float casterAlpha)
-            : RecordedOp(RecordedOpId::ShadowOp, Rect(), Matrix4::identity(), nullptr, nullptr)
-            , shadowTask(shadowTask)
-            , casterAlpha(casterAlpha){};
-    sp<TessellationCache::ShadowTask> shadowTask;
-    const float casterAlpha;
-};
-
 struct SimpleRectsOp : RecordedOp {  // Filled, no AA (TODO: better name?)
     SimpleRectsOp(BASE_PARAMS, Vertex* vertices, size_t vertexCount)
             : SUPER(SimpleRectsOp), vertices(vertices), vertexCount(vertexCount) {}
diff --git a/libs/hwui/RenderBufferCache.cpp b/libs/hwui/RenderBufferCache.cpp
deleted file mode 100644
index 98010d8..0000000
--- a/libs/hwui/RenderBufferCache.cpp
+++ /dev/null
@@ -1,161 +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 "RenderBufferCache.h"
-#include "Debug.h"
-#include "DeviceInfo.h"
-#include "Properties.h"
-
-#include <utils/Log.h>
-
-#include <cstdlib>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_RENDER_BUFFERS
-#define RENDER_BUFFER_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-#define RENDER_BUFFER_LOGD(...)
-#endif
-
-static uint32_t calculateRboCacheSize() {
-    // TODO: Do we need to use extensions().has4BitStencil() here?
-    // The tuning guide recommends it, but all real devices are configured
-    // with a larger cache than necessary by 4x, so keep the 2x for now regardless
-    return DeviceInfo::multiplyByResolution(2);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-RenderBufferCache::RenderBufferCache() : mSize(0), mMaxSize(calculateRboCacheSize()) {}
-
-RenderBufferCache::~RenderBufferCache() {
-    clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t RenderBufferCache::getSize() {
-    return mSize;
-}
-
-uint32_t RenderBufferCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-int RenderBufferCache::RenderBufferEntry::compare(const RenderBufferCache::RenderBufferEntry& lhs,
-                                                  const RenderBufferCache::RenderBufferEntry& rhs) {
-    int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
-    if (deltaInt != 0) return deltaInt;
-
-    deltaInt = int(lhs.mHeight) - int(rhs.mHeight);
-    if (deltaInt != 0) return deltaInt;
-
-    return int(lhs.mFormat) - int(rhs.mFormat);
-}
-
-void RenderBufferCache::deleteBuffer(RenderBuffer* buffer) {
-    if (buffer) {
-        RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d)",
-                           RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
-                           buffer->getHeight());
-
-        mSize -= buffer->getSize();
-        delete buffer;
-    }
-}
-
-void RenderBufferCache::clear() {
-    for (auto entry : mCache) {
-        deleteBuffer(entry.mBuffer);
-    }
-    mCache.clear();
-}
-
-RenderBuffer* RenderBufferCache::get(GLenum format, const uint32_t width, const uint32_t height) {
-    RenderBuffer* buffer = nullptr;
-
-    RenderBufferEntry entry(format, width, height);
-    auto iter = mCache.find(entry);
-
-    if (iter != mCache.end()) {
-        entry = *iter;
-        mCache.erase(iter);
-
-        buffer = entry.mBuffer;
-        mSize -= buffer->getSize();
-
-        RENDER_BUFFER_LOGD("Found %s render buffer (%dx%d)", RenderBuffer::formatName(format),
-                           width, height);
-    } else {
-        buffer = new RenderBuffer(format, width, height);
-
-        RENDER_BUFFER_LOGD("Created new %s render buffer (%dx%d)", RenderBuffer::formatName(format),
-                           width, height);
-    }
-
-    buffer->bind();
-    buffer->allocate();
-
-    return buffer;
-}
-
-bool RenderBufferCache::put(RenderBuffer* buffer) {
-    if (!buffer) return false;
-
-    const uint32_t size = buffer->getSize();
-    if (size < mMaxSize) {
-        while (mSize + size > mMaxSize) {
-            RenderBuffer* victim = mCache.begin()->mBuffer;
-            deleteBuffer(victim);
-            mCache.erase(mCache.begin());
-        }
-
-        RenderBufferEntry entry(buffer);
-
-        mCache.insert(entry);
-        mSize += size;
-
-        RENDER_BUFFER_LOGD("Added %s render buffer (%dx%d)",
-                           RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
-                           buffer->getHeight());
-
-        return true;
-    } else {
-        RENDER_BUFFER_LOGD("Deleted %s render buffer (%dx%d) Size=%d, MaxSize=%d",
-                           RenderBuffer::formatName(buffer->getFormat()), buffer->getWidth(),
-                           buffer->getHeight(), size, mMaxSize);
-        delete buffer;
-    }
-    return false;
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/RenderBufferCache.h b/libs/hwui/RenderBufferCache.h
deleted file mode 100644
index c936a52..0000000
--- a/libs/hwui/RenderBufferCache.h
+++ /dev/null
@@ -1,115 +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_RENDER_BUFFER_CACHE_H
-#define ANDROID_HWUI_RENDER_BUFFER_CACHE_H
-
-#include <GLES2/gl2.h>
-
-#include "RenderBuffer.h"
-
-#include <set>
-
-namespace android {
-namespace uirenderer {
-
-class RenderBufferCache {
-public:
-    RenderBufferCache();
-    ~RenderBufferCache();
-
-    /**
-     * Returns a buffer with the exact specified dimensions. If no suitable
-     * buffer can be found, a new one is created and returned. If creating a
-     * new buffer fails, NULL is returned.
-     *
-     * When a buffer is obtained from the cache, it is removed and the total
-     * size of the cache goes down.
-     *
-     * The returned buffer is always allocated and bound
-     * (see RenderBuffer::isAllocated()).
-     *
-     * @param format The desired render buffer format
-     * @param width The desired width of the buffer
-     * @param height The desired height of the buffer
-     */
-    RenderBuffer* get(GLenum format, const uint32_t width, const uint32_t height);
-
-    /**
-     * Adds the buffer to the cache. The buffer will not be added if there is
-     * not enough space available. Adding a buffer can cause other buffer to
-     * be removed from the cache.
-     *
-     * @param buffer The render buffer to add to the cache
-     *
-     * @return True if the buffer was added, false otherwise.
-     */
-    bool put(RenderBuffer* buffer);
-    /**
-     * Clears the cache. This causes all layers to be deleted.
-     */
-    void clear();
-
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-private:
-    struct RenderBufferEntry {
-        RenderBufferEntry() : mBuffer(nullptr), mWidth(0), mHeight(0) {}
-
-        RenderBufferEntry(GLenum format, const uint32_t width, const uint32_t height)
-                : mBuffer(nullptr), mFormat(format), mWidth(width), mHeight(height) {}
-
-        explicit RenderBufferEntry(RenderBuffer* buffer)
-                : mBuffer(buffer)
-                , mFormat(buffer->getFormat())
-                , mWidth(buffer->getWidth())
-                , mHeight(buffer->getHeight()) {}
-
-        static int compare(const RenderBufferEntry& lhs, const RenderBufferEntry& rhs);
-
-        bool operator==(const RenderBufferEntry& other) const { return compare(*this, other) == 0; }
-
-        bool operator!=(const RenderBufferEntry& other) const { return compare(*this, other) != 0; }
-
-        bool operator<(const RenderBufferEntry& other) const {
-            return RenderBufferEntry::compare(*this, other) < 0;
-        }
-
-        RenderBuffer* mBuffer;
-        GLenum mFormat;
-        uint32_t mWidth;
-        uint32_t mHeight;
-    };  // struct RenderBufferEntry
-
-    void deleteBuffer(RenderBuffer* buffer);
-
-    std::multiset<RenderBufferEntry> mCache;
-
-    uint32_t mSize;
-    uint32_t mMaxSize;
-};  // class RenderBufferCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_RENDER_BUFFER_CACHE_H
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index d60b994..464a58d 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -113,7 +113,7 @@
     if (ref == nullptr) {
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
-            Caches::getInstance().patchCache.removeDeferred(resource);
+            // DEAD CODE
         } else {
             // A Res_png_9patch is actually an array of byte that's larger
             // than sizeof(Res_png_9patch). It must be freed as an array.
@@ -136,7 +136,7 @@
         switch (ref->resourceType) {
             case kNinePatch: {
                 if (Caches::hasInstance()) {
-                    Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*)resource);
+                    // DEAD CODE
                 } else {
                     // A Res_png_9patch is actually an array of byte that's larger
                     // than sizeof(Res_png_9patch). It must be freed as an array.
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index df74655..6f7bb9b 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -45,13 +45,6 @@
 static_assert(gTileModes[SkShader::kMirror_TileMode] == GL_MIRRORED_REPEAT,
               "SkShader TileModes have changed");
 
-/**
- * This function does not work for n == 0.
- */
-static inline bool isPowerOfTwo(unsigned int n) {
-    return !(n & (n - 1));
-}
-
 static inline void bindUniformColor(int slot, FloatColor color) {
     glUniform4fv(slot, 1, reinterpret_cast<const float*>(&color));
 }
@@ -80,106 +73,9 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Gradient shader matrix helpers
-///////////////////////////////////////////////////////////////////////////////
-
-static void toLinearUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) {
-    SkVector vec = pts[1] - pts[0];
-    const float mag = vec.length();
-    const float inv = mag ? 1.0f / mag : 0;
-
-    vec.scale(inv);
-    matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
-    matrix->postTranslate(-pts[0].fX, -pts[0].fY);
-    matrix->postScale(inv, inv);
-}
-
-static void toCircularUnitMatrix(const float x, const float y, const float radius,
-                                 SkMatrix* matrix) {
-    const float inv = 1.0f / radius;
-    matrix->setTranslate(-x, -y);
-    matrix->postScale(inv, inv);
-}
-
-static void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) {
-    matrix->setTranslate(-x, -y);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Common gradient code
-///////////////////////////////////////////////////////////////////////////////
-
-static bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) {
-    return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode;
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // Store / apply
 ///////////////////////////////////////////////////////////////////////////////
 
-bool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 modelViewMatrix,
-                      GLuint* textureUnit, ProgramDescription* description,
-                      SkiaShaderData::GradientShaderData* outData) {
-    SkShader::GradientInfo gradInfo;
-    gradInfo.fColorCount = 0;
-    gradInfo.fColors = nullptr;
-    gradInfo.fColorOffsets = nullptr;
-
-    SkMatrix unitMatrix;
-    switch (shader.asAGradient(&gradInfo)) {
-        case SkShader::kLinear_GradientType:
-            description->gradientType = ProgramDescription::kGradientLinear;
-
-            toLinearUnitMatrix(gradInfo.fPoint, &unitMatrix);
-            break;
-        case SkShader::kRadial_GradientType:
-            description->gradientType = ProgramDescription::kGradientCircular;
-
-            toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, gradInfo.fRadius[0],
-                                 &unitMatrix);
-            break;
-        case SkShader::kSweep_GradientType:
-            description->gradientType = ProgramDescription::kGradientSweep;
-
-            toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix);
-            break;
-        default:
-            // Do nothing. This shader is unsupported.
-            return false;
-    }
-    description->hasGradient = true;
-    description->isSimpleGradient = isSimpleGradient(gradInfo);
-
-    computeScreenSpaceMatrix(outData->screenSpace, unitMatrix, shader.getLocalMatrix(),
-                             modelViewMatrix);
-
-    // re-query shader to get full color / offset data
-    std::unique_ptr<SkColor[]> colorStorage(new SkColor[gradInfo.fColorCount]);
-    std::unique_ptr<SkScalar[]> colorOffsets(new SkScalar[gradInfo.fColorCount]);
-    gradInfo.fColors = &colorStorage[0];
-    gradInfo.fColorOffsets = &colorOffsets[0];
-    shader.asAGradient(&gradInfo);
-
-    if (CC_UNLIKELY(!description->isSimpleGradient)) {
-        outData->gradientSampler = (*textureUnit)++;
-
-#ifndef SK_SCALAR_IS_FLOAT
-#error Need to convert gradInfo.fColorOffsets to float!
-#endif
-        outData->gradientTexture = caches.gradientCache.get(
-                gradInfo.fColors, gradInfo.fColorOffsets, gradInfo.fColorCount);
-        outData->wrapST = gTileModes[gradInfo.fTileMode];
-    } else {
-        outData->gradientSampler = 0;
-        outData->gradientTexture = nullptr;
-
-        outData->startColor.set(gradInfo.fColors[0]);
-        outData->endColor.set(gradInfo.fColors[1]);
-    }
-
-    return true;
-}
-
 void applyGradient(Caches& caches, const SkiaShaderData::GradientShaderData& data,
                    const GLsizei width, const GLsizei height) {
     if (CC_UNLIKELY(data.gradientTexture)) {
@@ -199,52 +95,7 @@
 bool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
                     GLuint* textureUnit, ProgramDescription* description,
                     SkiaShaderData::BitmapShaderData* outData) {
-    SkBitmap bitmap;
-    SkShader::TileMode xy[2];
-    if (!shader.isABitmap(&bitmap, nullptr, xy)) {
-        return false;
-    }
-
-    // TODO: create  hwui-owned BitmapShader.
-    Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
-    outData->bitmapTexture = caches.textureCache.get(hwuiBitmap);
-    if (!outData->bitmapTexture) return false;
-
-    outData->bitmapSampler = (*textureUnit)++;
-
-    const float width = outData->bitmapTexture->width();
-    const float height = outData->bitmapTexture->height();
-
-    Texture* texture = outData->bitmapTexture;
-
-    description->hasBitmap = true;
-    description->hasLinearTexture = texture->isLinear();
-    description->hasColorSpaceConversion = texture->hasColorSpaceConversion();
-    description->transferFunction = texture->getTransferFunctionType();
-    description->hasTranslucentConversion = texture->blend;
-    description->isShaderBitmapExternal = hwuiBitmap->isHardware();
-    // gralloc doesn't support non-clamp modes
-    if (hwuiBitmap->isHardware() ||
-        (!caches.extensions().hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) &&
-         (xy[0] != SkShader::kClamp_TileMode || xy[1] != SkShader::kClamp_TileMode))) {
-        // need non-clamp mode, but it's not supported for this draw,
-        // so enable custom shader logic to mimic
-        description->useShaderBasedWrap = true;
-        description->bitmapWrapS = gTileModes[xy[0]];
-        description->bitmapWrapT = gTileModes[xy[1]];
-
-        outData->wrapS = GL_CLAMP_TO_EDGE;
-        outData->wrapT = GL_CLAMP_TO_EDGE;
-    } else {
-        outData->wrapS = gTileModes[xy[0]];
-        outData->wrapT = gTileModes[xy[1]];
-    }
-
-    computeScreenSpaceMatrix(outData->textureTransform, SkMatrix::I(), shader.getLocalMatrix(),
-                             modelViewMatrix);
-    outData->textureDimension[0] = 1.0f / width;
-    outData->textureDimension[1] = 1.0f / height;
-
+    // DEAD CODE
     return true;
 }
 
@@ -287,9 +138,6 @@
     LOG_ALWAYS_FATAL_IF(!tryStoreBitmap(caches, bitmapShader, modelViewMatrix, textureUnit,
                                         description, &outData->bitmapData),
                         "failed storing bitmap shader data");
-    LOG_ALWAYS_FATAL_IF(!tryStoreGradient(caches, gradientShader, modelViewMatrix, textureUnit,
-                                          description, &outData->gradientData),
-                        "failing storing gradient shader data");
 }
 
 bool tryStoreCompose(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
@@ -323,12 +171,7 @@
 void SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix,
                        GLuint* textureUnit, ProgramDescription* description,
                        SkiaShaderData* outData) {
-    if (tryStoreGradient(caches, shader, modelViewMatrix, textureUnit, description,
-                         &outData->gradientData)) {
-        outData->skiaShaderType = kGradient_SkiaShaderType;
-        return;
-    }
-
+    // DEAD CODE
     if (tryStoreBitmap(caches, shader, modelViewMatrix, textureUnit, description,
                        &outData->bitmapData)) {
         outData->skiaShaderType = kBitmap_SkiaShaderType;
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
deleted file mode 100644
index c7d93da..0000000
--- a/libs/hwui/TessellationCache.cpp
+++ /dev/null
@@ -1,444 +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.
- */
-
-#include <utils/JenkinsHash.h>
-#include <utils/Trace.h>
-
-#include "Caches.h"
-#include "PathTessellator.h"
-#include "ShadowTessellator.h"
-#include "TessellationCache.h"
-
-#include "thread/Signal.h"
-#include "thread/Task.h"
-#include "thread/TaskProcessor.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache entries
-///////////////////////////////////////////////////////////////////////////////
-
-TessellationCache::Description::Description()
-        : type(Type::None)
-        , scaleX(1.0f)
-        , scaleY(1.0f)
-        , aa(false)
-        , cap(SkPaint::kDefault_Cap)
-        , style(SkPaint::kFill_Style)
-        , strokeWidth(1.0f) {
-    // Shape bits should be set to zeroes, because they are used for hash calculation.
-    memset(&shape, 0, sizeof(Shape));
-}
-
-TessellationCache::Description::Description(Type type, const Matrix4& transform,
-                                            const SkPaint& paint)
-        : type(type)
-        , aa(paint.isAntiAlias())
-        , cap(paint.getStrokeCap())
-        , style(paint.getStyle())
-        , strokeWidth(paint.getStrokeWidth()) {
-    PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY);
-    // Shape bits should be set to zeroes, because they are used for hash calculation.
-    memset(&shape, 0, sizeof(Shape));
-}
-
-bool TessellationCache::Description::operator==(const TessellationCache::Description& rhs) const {
-    if (type != rhs.type) return false;
-    if (scaleX != rhs.scaleX) return false;
-    if (scaleY != rhs.scaleY) return false;
-    if (aa != rhs.aa) return false;
-    if (cap != rhs.cap) return false;
-    if (style != rhs.style) return false;
-    if (strokeWidth != rhs.strokeWidth) return false;
-    if (type == Type::None) return true;
-    const Shape::RoundRect& lRect = shape.roundRect;
-    const Shape::RoundRect& rRect = rhs.shape.roundRect;
-
-    if (lRect.width != rRect.width) return false;
-    if (lRect.height != rRect.height) return false;
-    if (lRect.rx != rRect.rx) return false;
-    return lRect.ry == rRect.ry;
-}
-
-hash_t TessellationCache::Description::hash() const {
-    uint32_t hash = JenkinsHashMix(0, static_cast<int>(type));
-    hash = JenkinsHashMix(hash, aa);
-    hash = JenkinsHashMix(hash, cap);
-    hash = JenkinsHashMix(hash, style);
-    hash = JenkinsHashMix(hash, android::hash_type(strokeWidth));
-    hash = JenkinsHashMix(hash, android::hash_type(scaleX));
-    hash = JenkinsHashMix(hash, android::hash_type(scaleY));
-    hash = JenkinsHashMixBytes(hash, (uint8_t*)&shape, sizeof(Shape));
-    return JenkinsHashWhiten(hash);
-}
-
-void TessellationCache::Description::setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const {
-    matrix->loadScale(scaleX, scaleY, 1.0f);
-    paint->setAntiAlias(aa);
-    paint->setStrokeCap(cap);
-    paint->setStyle(style);
-    paint->setStrokeWidth(strokeWidth);
-}
-
-TessellationCache::ShadowDescription::ShadowDescription() : nodeKey(nullptr) {
-    memset(&matrixData, 0, sizeof(matrixData));
-}
-
-TessellationCache::ShadowDescription::ShadowDescription(const SkPath* nodeKey,
-                                                        const Matrix4* drawTransform)
-        : nodeKey(nodeKey) {
-    memcpy(&matrixData, drawTransform->data, sizeof(matrixData));
-}
-
-bool TessellationCache::ShadowDescription::operator==(
-        const TessellationCache::ShadowDescription& rhs) const {
-    return nodeKey == rhs.nodeKey && memcmp(&matrixData, &rhs.matrixData, sizeof(matrixData)) == 0;
-}
-
-hash_t TessellationCache::ShadowDescription::hash() const {
-    uint32_t hash = JenkinsHashMixBytes(0, (uint8_t*)&nodeKey, sizeof(const void*));
-    hash = JenkinsHashMixBytes(hash, (uint8_t*)&matrixData, sizeof(matrixData));
-    return JenkinsHashWhiten(hash);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// General purpose tessellation task processing
-///////////////////////////////////////////////////////////////////////////////
-
-class TessellationCache::TessellationTask : public Task<VertexBuffer*> {
-public:
-    TessellationTask(Tessellator tessellator, const Description& description)
-            : tessellator(tessellator), description(description) {}
-
-    ~TessellationTask() {}
-
-    Tessellator tessellator;
-    Description description;
-};
-
-class TessellationCache::TessellationProcessor : public TaskProcessor<VertexBuffer*> {
-public:
-    explicit TessellationProcessor(Caches& caches) : TaskProcessor<VertexBuffer*>(&caches.tasks) {}
-    ~TessellationProcessor() {}
-
-    virtual void onProcess(const sp<Task<VertexBuffer*> >& task) override {
-        TessellationTask* t = static_cast<TessellationTask*>(task.get());
-        ATRACE_NAME("shape tessellation");
-        VertexBuffer* buffer = t->tessellator(t->description);
-        t->setResult(buffer);
-    }
-};
-
-class TessellationCache::Buffer {
-public:
-    explicit Buffer(const sp<Task<VertexBuffer*> >& task) : mTask(task), mBuffer(nullptr) {}
-
-    ~Buffer() {
-        mTask.clear();
-        delete mBuffer;
-    }
-
-    unsigned int getSize() {
-        blockOnPrecache();
-        return mBuffer->getSize();
-    }
-
-    const VertexBuffer* getVertexBuffer() {
-        blockOnPrecache();
-        return mBuffer;
-    }
-
-private:
-    void blockOnPrecache() {
-        if (mTask != nullptr) {
-            mBuffer = mTask->getResult();
-            LOG_ALWAYS_FATAL_IF(mBuffer == nullptr, "Failed to precache");
-            mTask.clear();
-        }
-    }
-    sp<Task<VertexBuffer*> > mTask;
-    VertexBuffer* mBuffer;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Shadow tessellation task processing
-///////////////////////////////////////////////////////////////////////////////
-
-static void mapPointFakeZ(Vector3& point, const mat4* transformXY, const mat4* transformZ) {
-    // map z coordinate with true 3d matrix
-    point.z = transformZ->mapZ(point);
-
-    // map x,y coordinates with draw/Skia matrix
-    transformXY->mapPoint(point.x, point.y);
-}
-
-static void reverseVertexArray(Vertex* polygon, int len) {
-    int n = len / 2;
-    for (int i = 0; i < n; i++) {
-        Vertex tmp = polygon[i];
-        int k = len - 1 - i;
-        polygon[i] = polygon[k];
-        polygon[k] = tmp;
-    }
-}
-
-void tessellateShadows(const Matrix4* drawTransform, const Rect* localClip, bool isCasterOpaque,
-                       const SkPath* casterPerimeter, const Matrix4* casterTransformXY,
-                       const Matrix4* casterTransformZ, const Vector3& lightCenter,
-                       float lightRadius, VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer) {
-    // tessellate caster outline into a 2d polygon
-    std::vector<Vertex> casterVertices2d;
-    const float casterRefinementThreshold = 2.0f;
-    PathTessellator::approximatePathOutlineVertices(*casterPerimeter, casterRefinementThreshold,
-                                                    casterVertices2d);
-
-    // Shadow requires CCW for now. TODO: remove potential double-reverse
-    reverseVertexArray(&casterVertices2d.front(), casterVertices2d.size());
-
-    if (casterVertices2d.size() == 0) return;
-
-    // map 2d caster poly into 3d
-    const int casterVertexCount = casterVertices2d.size();
-    Vector3 casterPolygon[casterVertexCount];
-    float minZ = FLT_MAX;
-    float maxZ = -FLT_MAX;
-    for (int i = 0; i < casterVertexCount; i++) {
-        const Vertex& point2d = casterVertices2d[i];
-        casterPolygon[i] = (Vector3){point2d.x, point2d.y, 0};
-        mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
-        minZ = std::min(minZ, casterPolygon[i].z);
-        maxZ = std::max(maxZ, casterPolygon[i].z);
-    }
-
-    // map the centroid of the caster into 3d
-    Vector2 centroid = ShadowTessellator::centroid2d(
-            reinterpret_cast<const Vector2*>(&casterVertices2d.front()), casterVertexCount);
-    Vector3 centroid3d = {centroid.x, centroid.y, 0};
-    mapPointFakeZ(centroid3d, casterTransformXY, casterTransformZ);
-
-    // if the caster intersects the z=0 plane, lift it in Z so it doesn't
-    if (minZ < SHADOW_MIN_CASTER_Z) {
-        float casterLift = SHADOW_MIN_CASTER_Z - minZ;
-        for (int i = 0; i < casterVertexCount; i++) {
-            casterPolygon[i].z += casterLift;
-        }
-        centroid3d.z += casterLift;
-    }
-
-    // Check whether we want to draw the shadow at all by checking the caster's bounds against clip.
-    // We only have ortho projection, so we can just ignore the Z in caster for
-    // simple rejection calculation.
-    Rect casterBounds(casterPerimeter->getBounds());
-    casterTransformXY->mapRect(casterBounds);
-
-    // actual tessellation of both shadows
-    ShadowTessellator::tessellateAmbientShadow(isCasterOpaque, casterPolygon, casterVertexCount,
-                                               centroid3d, casterBounds, *localClip, maxZ,
-                                               ambientBuffer);
-
-    ShadowTessellator::tessellateSpotShadow(isCasterOpaque, casterPolygon, casterVertexCount,
-                                            centroid3d, *drawTransform, lightCenter, lightRadius,
-                                            casterBounds, *localClip, spotBuffer);
-}
-
-class ShadowProcessor : public TaskProcessor<TessellationCache::vertexBuffer_pair_t> {
-public:
-    explicit ShadowProcessor(Caches& caches)
-            : TaskProcessor<TessellationCache::vertexBuffer_pair_t>(&caches.tasks) {}
-    ~ShadowProcessor() {}
-
-    virtual void onProcess(const sp<Task<TessellationCache::vertexBuffer_pair_t> >& task) override {
-        TessellationCache::ShadowTask* t = static_cast<TessellationCache::ShadowTask*>(task.get());
-        ATRACE_NAME("shadow tessellation");
-
-        tessellateShadows(&t->drawTransform, &t->localClip, t->opaque, &t->casterPerimeter,
-                          &t->transformXY, &t->transformZ, t->lightCenter, t->lightRadius,
-                          t->ambientBuffer, t->spotBuffer);
-
-        t->setResult(TessellationCache::vertexBuffer_pair_t(&t->ambientBuffer, &t->spotBuffer));
-    }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache constructor/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-TessellationCache::TessellationCache()
-        : mMaxSize(MB(1))
-        , mCache(LruCache<Description, Buffer*>::kUnlimitedCapacity)
-        , mShadowCache(
-                  LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*>::kUnlimitedCapacity) {
-    mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
-    mShadowCache.setOnEntryRemovedListener(&mBufferPairRemovedListener);
-    mDebugEnabled = Properties::debugLevel & kDebugCaches;
-}
-
-TessellationCache::~TessellationCache() {
-    mCache.clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t TessellationCache::getSize() {
-    LruCache<Description, Buffer*>::Iterator iter(mCache);
-    uint32_t size = 0;
-    while (iter.next()) {
-        size += iter.value()->getSize();
-    }
-    return size;
-}
-
-uint32_t TessellationCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void TessellationCache::trim() {
-    uint32_t size = getSize();
-    while (size > mMaxSize) {
-        size -= mCache.peekOldestValue()->getSize();
-        mCache.removeOldest();
-    }
-    mShadowCache.clear();
-}
-
-void TessellationCache::clear() {
-    mCache.clear();
-    mShadowCache.clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void TessellationCache::BufferRemovedListener::operator()(Description& description,
-                                                          Buffer*& buffer) {
-    delete buffer;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Shadows
-///////////////////////////////////////////////////////////////////////////////
-
-void TessellationCache::precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
-                                        bool opaque, const SkPath* casterPerimeter,
-                                        const Matrix4* transformXY, const Matrix4* transformZ,
-                                        const Vector3& lightCenter, float lightRadius) {
-    ShadowDescription key(casterPerimeter, drawTransform);
-
-    if (mShadowCache.get(key)) return;
-    sp<ShadowTask> task = new ShadowTask(drawTransform, localClip, opaque, casterPerimeter,
-                                         transformXY, transformZ, lightCenter, lightRadius);
-    if (mShadowProcessor == nullptr) {
-        mShadowProcessor = new ShadowProcessor(Caches::getInstance());
-    }
-    mShadowProcessor->add(task);
-    task->incStrong(nullptr);  // not using sp<>s, so manually ref while in the cache
-    mShadowCache.put(key, task.get());
-}
-
-sp<TessellationCache::ShadowTask> TessellationCache::getShadowTask(
-        const Matrix4* drawTransform, const Rect& localClip, bool opaque,
-        const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
-        const Vector3& lightCenter, float lightRadius) {
-    ShadowDescription key(casterPerimeter, drawTransform);
-    ShadowTask* task = static_cast<ShadowTask*>(mShadowCache.get(key));
-    if (!task) {
-        precacheShadows(drawTransform, localClip, opaque, casterPerimeter, transformXY, transformZ,
-                        lightCenter, lightRadius);
-        task = static_cast<ShadowTask*>(mShadowCache.get(key));
-    }
-    LOG_ALWAYS_FATAL_IF(task == nullptr, "shadow not precached");
-    return task;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Tessellation precaching
-///////////////////////////////////////////////////////////////////////////////
-
-TessellationCache::Buffer* TessellationCache::getOrCreateBuffer(const Description& entry,
-                                                                Tessellator tessellator) {
-    Buffer* buffer = mCache.get(entry);
-    if (!buffer) {
-        // not cached, enqueue a task to fill the buffer
-        sp<TessellationTask> task = new TessellationTask(tessellator, entry);
-        buffer = new Buffer(task);
-
-        if (mProcessor == nullptr) {
-            mProcessor = new TessellationProcessor(Caches::getInstance());
-        }
-        mProcessor->add(task);
-        bool inserted = mCache.put(entry, buffer);
-        // Note to the static analyzer that this insert should always succeed.
-        LOG_ALWAYS_FATAL_IF(!inserted, "buffers shouldn't spontaneously appear in the cache");
-    }
-    return buffer;
-}
-
-static VertexBuffer* tessellatePath(const TessellationCache::Description& description,
-                                    const SkPath& path) {
-    Matrix4 matrix;
-    SkPaint paint;
-    description.setupMatrixAndPaint(&matrix, &paint);
-    VertexBuffer* buffer = new VertexBuffer();
-    PathTessellator::tessellatePath(path, &paint, matrix, *buffer);
-    return buffer;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// RoundRect
-///////////////////////////////////////////////////////////////////////////////
-
-static VertexBuffer* tessellateRoundRect(const TessellationCache::Description& description) {
-    SkRect rect =
-            SkRect::MakeWH(description.shape.roundRect.width, description.shape.roundRect.height);
-    float rx = description.shape.roundRect.rx;
-    float ry = description.shape.roundRect.ry;
-    if (description.style == SkPaint::kStrokeAndFill_Style) {
-        float outset = description.strokeWidth / 2;
-        rect.outset(outset, outset);
-        rx += outset;
-        ry += outset;
-    }
-    SkPath path;
-    path.addRoundRect(rect, rx, ry);
-    return tessellatePath(description, path);
-}
-
-TessellationCache::Buffer* TessellationCache::getRoundRectBuffer(const Matrix4& transform,
-                                                                 const SkPaint& paint, float width,
-                                                                 float height, float rx, float ry) {
-    Description entry(Description::Type::RoundRect, transform, paint);
-    entry.shape.roundRect.width = width;
-    entry.shape.roundRect.height = height;
-    entry.shape.roundRect.rx = rx;
-    entry.shape.roundRect.ry = ry;
-    return getOrCreateBuffer(entry, &tessellateRoundRect);
-}
-const VertexBuffer* TessellationCache::getRoundRect(const Matrix4& transform, const SkPaint& paint,
-                                                    float width, float height, float rx, float ry) {
-    return getRoundRectBuffer(transform, paint, width, height, rx, ry)->getVertexBuffer();
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h
deleted file mode 100644
index a0f0ed4..0000000
--- a/libs/hwui/TessellationCache.h
+++ /dev/null
@@ -1,225 +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.
- */
-
-#pragma once
-
-#include "Debug.h"
-#include "Matrix.h"
-#include "Rect.h"
-#include "Vector.h"
-#include "VertexBuffer.h"
-#include "thread/TaskProcessor.h"
-#include "utils/Macros.h"
-#include "utils/Pair.h"
-
-#include <SkPaint.h>
-#include <SkPath.h>
-
-#include <utils/LruCache.h>
-#include <utils/Mutex.h>
-#include <utils/StrongPointer.h>
-
-class SkBitmap;
-class SkCanvas;
-struct SkRect;
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-class VertexBuffer;
-
-///////////////////////////////////////////////////////////////////////////////
-// Classes
-///////////////////////////////////////////////////////////////////////////////
-
-class TessellationCache {
-public:
-    typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
-
-    struct Description {
-        HASHABLE_TYPE(Description);
-        enum class Type {
-            None,
-            RoundRect,
-        };
-
-        Type type;
-        float scaleX;
-        float scaleY;
-        bool aa;
-        SkPaint::Cap cap;
-        SkPaint::Style style;
-        float strokeWidth;
-        union Shape {
-            struct RoundRect {
-                float width;
-                float height;
-                float rx;
-                float ry;
-            } roundRect;
-        } shape;
-
-        Description();
-        Description(Type type, const Matrix4& transform, const SkPaint& paint);
-        void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
-    };
-
-    struct ShadowDescription {
-        HASHABLE_TYPE(ShadowDescription);
-        const SkPath* nodeKey;
-        float matrixData[16];
-
-        ShadowDescription();
-        ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform);
-    };
-
-    class ShadowTask : public Task<vertexBuffer_pair_t> {
-    public:
-        ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
-                   const SkPath* casterPerimeter, const Matrix4* transformXY,
-                   const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius)
-                : drawTransform(*drawTransform)
-                , localClip(localClip)
-                , opaque(opaque)
-                , casterPerimeter(*casterPerimeter)
-                , transformXY(*transformXY)
-                , transformZ(*transformZ)
-                , lightCenter(lightCenter)
-                , lightRadius(lightRadius) {}
-
-        /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
-         * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
-         * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
-         *
-         * These deep copies could be avoided, long term, by canceling or flushing outstanding
-         * tasks before tearing down single-frame LinearAllocators.
-         */
-        const Matrix4 drawTransform;
-        const Rect localClip;
-        bool opaque;
-        const SkPath casterPerimeter;
-        const Matrix4 transformXY;
-        const Matrix4 transformZ;
-        const Vector3 lightCenter;
-        const float lightRadius;
-        VertexBuffer ambientBuffer;
-        VertexBuffer spotBuffer;
-    };
-
-    TessellationCache();
-    ~TessellationCache();
-
-    /**
-     * Clears the cache. This causes all TessellationBuffers to be deleted.
-     */
-    void clear();
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-    /**
-     * Trims the contents of the cache, removing items until it's under its
-     * specified limit.
-     *
-     * Trimming is used for caches that support pre-caching from a worker
-     * thread. During pre-caching the maximum limit of the cache can be
-     * exceeded for the duration of the frame. It is therefore required to
-     * trim the cache at the end of the frame to keep the total amount of
-     * memory used under control.
-     *
-     * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
-     */
-    void trim();
-
-    // TODO: precache/get for Oval, Lines, Points, etc.
-
-    void precacheRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
-                           float height, float rx, float ry) {
-        getRoundRectBuffer(transform, paint, width, height, rx, ry);
-    }
-    const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
-                                     float height, float rx, float ry);
-
-    sp<ShadowTask> getShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
-                                 const SkPath* casterPerimeter, const Matrix4* transformXY,
-                                 const Matrix4* transformZ, const Vector3& lightCenter,
-                                 float lightRadius);
-
-private:
-    class Buffer;
-    class TessellationTask;
-    class TessellationProcessor;
-
-    typedef VertexBuffer* (*Tessellator)(const Description&);
-
-    void precacheShadows(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
-                         const SkPath* casterPerimeter, const Matrix4* transformXY,
-                         const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius);
-
-    Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
-                          float height);
-    Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
-                               float height, float rx, float ry);
-
-    Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);
-
-    const uint32_t mMaxSize;
-
-    bool mDebugEnabled;
-
-    mutable Mutex mLock;
-
-    ///////////////////////////////////////////////////////////////////////////////
-    // General tessellation caching
-    ///////////////////////////////////////////////////////////////////////////////
-    sp<TaskProcessor<VertexBuffer*> > mProcessor;
-    LruCache<Description, Buffer*> mCache;
-    class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
-        void operator()(Description& description, Buffer*& buffer) override;
-    };
-    BufferRemovedListener mBufferRemovedListener;
-
-    ///////////////////////////////////////////////////////////////////////////////
-    // Shadow tessellation caching
-    ///////////////////////////////////////////////////////////////////////////////
-    sp<TaskProcessor<vertexBuffer_pair_t> > mShadowProcessor;
-
-    // holds a pointer, and implicit strong ref to each shadow task of the frame
-    LruCache<ShadowDescription, Task<vertexBuffer_pair_t>*> mShadowCache;
-    class BufferPairRemovedListener
-            : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t>*> {
-        void operator()(ShadowDescription& description,
-                        Task<vertexBuffer_pair_t>*& bufferPairTask) override {
-            bufferPairTask->decStrong(nullptr);
-        }
-    };
-    BufferPairRemovedListener mBufferPairRemovedListener;
-
-};  // class TessellationCache
-
-void tessellateShadows(const Matrix4* drawTransform, const Rect* localClip, bool isCasterOpaque,
-                       const SkPath* casterPerimeter, const Matrix4* casterTransformXY,
-                       const Matrix4* casterTransformZ, const Vector3& lightCenter,
-                       float lightRadius, VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer);
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
deleted file mode 100644
index 9d365fb..0000000
--- a/libs/hwui/TextureCache.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2010 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 <GLES2/gl2.h>
-
-#include <utils/Mutex.h>
-
-#include "Caches.h"
-#include "DeviceInfo.h"
-#include "Properties.h"
-#include "Texture.h"
-#include "TextureCache.h"
-#include "hwui/Bitmap.h"
-#include "utils/TraceUtils.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-TextureCache::TextureCache()
-        : mCache(LruCache<uint32_t, Texture*>::kUnlimitedCapacity)
-        , mSize(0)
-        , mMaxSize(DeviceInfo::multiplyByResolution(4 * 6))  // 6 screen-sized RGBA_8888 bitmaps
-        , mFlushRate(.4f) {
-    mCache.setOnEntryRemovedListener(this);
-    mMaxTextureSize = DeviceInfo::get()->maxTextureSize();
-    mDebugEnabled = Properties::debugLevel & kDebugCaches;
-}
-
-TextureCache::~TextureCache() {
-    this->clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t TextureCache::getSize() {
-    return mSize;
-}
-
-uint32_t TextureCache::getMaxSize() {
-    return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void TextureCache::operator()(uint32_t&, Texture*& texture) {
-    // This will be called already locked
-    if (texture) {
-        mSize -= texture->bitmapSize;
-        TEXTURE_LOGD("TextureCache::callback: name, removed size, mSize = %d, %d, %d", texture->id,
-                     texture->bitmapSize, mSize);
-        if (mDebugEnabled) {
-            ALOGD("Texture deleted, size = %d", texture->bitmapSize);
-        }
-        texture->deleteTexture();
-        delete texture;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void TextureCache::resetMarkInUse(void* ownerToken) {
-    LruCache<uint32_t, Texture*>::Iterator iter(mCache);
-    while (iter.next()) {
-        if (iter.value()->isInUse == ownerToken) {
-            iter.value()->isInUse = nullptr;
-        }
-    }
-}
-
-bool TextureCache::canMakeTextureFromBitmap(Bitmap* bitmap) {
-    if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
-        ALOGW("Bitmap too large to be uploaded into a texture (%dx%d, max=%dx%d)", bitmap->width(),
-              bitmap->height(), mMaxTextureSize, mMaxTextureSize);
-        return false;
-    }
-    return true;
-}
-
-Texture* TextureCache::createTexture(Bitmap* bitmap) {
-    Texture* texture = new Texture(Caches::getInstance());
-    texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
-    texture->generation = bitmap->getGenerationID();
-    texture->upload(*bitmap);
-    return texture;
-}
-
-// Returns a prepared Texture* that either is already in the cache or can fit
-// in the cache (and is thus added to the cache)
-Texture* TextureCache::getCachedTexture(Bitmap* bitmap) {
-    if (bitmap->isHardware()) {
-        auto textureIterator = mHardwareTextures.find(bitmap->getStableID());
-        if (textureIterator == mHardwareTextures.end()) {
-            Texture* texture = createTexture(bitmap);
-            mHardwareTextures.insert(
-                    std::make_pair(bitmap->getStableID(), std::unique_ptr<Texture>(texture)));
-            if (mDebugEnabled) {
-                ALOGD("Texture created for hw bitmap size = %d", texture->bitmapSize);
-            }
-            return texture;
-        }
-        return textureIterator->second.get();
-    }
-
-    Texture* texture = mCache.get(bitmap->getStableID());
-
-    if (!texture) {
-        if (!canMakeTextureFromBitmap(bitmap)) {
-            return nullptr;
-        }
-
-        const uint32_t size = bitmap->rowBytes() * bitmap->height();
-        bool canCache = size < mMaxSize;
-        // Don't even try to cache a bitmap that's bigger than the cache
-        while (canCache && mSize + size > mMaxSize) {
-            Texture* oldest = mCache.peekOldestValue();
-            if (oldest && !oldest->isInUse) {
-                mCache.removeOldest();
-            } else {
-                canCache = false;
-            }
-        }
-
-        if (canCache) {
-            texture = createTexture(bitmap);
-            mSize += size;
-            TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
-                         bitmap, texture->id, size, mSize);
-            if (mDebugEnabled) {
-                ALOGD("Texture created, size = %d", size);
-            }
-            mCache.put(bitmap->getStableID(), texture);
-        }
-    } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) {
-        // Texture was in the cache but is dirty, re-upload
-        // TODO: Re-adjust the cache size if the bitmap's dimensions have changed
-        texture->upload(*bitmap);
-        texture->generation = bitmap->getGenerationID();
-    }
-
-    return texture;
-}
-
-bool TextureCache::prefetchAndMarkInUse(void* ownerToken, Bitmap* bitmap) {
-    Texture* texture = getCachedTexture(bitmap);
-    if (texture) {
-        texture->isInUse = ownerToken;
-    }
-    return texture;
-}
-
-bool TextureCache::prefetch(Bitmap* bitmap) {
-    return getCachedTexture(bitmap);
-}
-
-Texture* TextureCache::get(Bitmap* bitmap) {
-    Texture* texture = getCachedTexture(bitmap);
-
-    if (!texture) {
-        if (!canMakeTextureFromBitmap(bitmap)) {
-            return nullptr;
-        }
-        texture = createTexture(bitmap);
-        texture->cleanup = true;
-    }
-
-    return texture;
-}
-
-bool TextureCache::destroyTexture(uint32_t pixelRefStableID) {
-    auto hardwareIter = mHardwareTextures.find(pixelRefStableID);
-    if (hardwareIter != mHardwareTextures.end()) {
-        hardwareIter->second->deleteTexture();
-        mHardwareTextures.erase(hardwareIter);
-        return true;
-    }
-    return mCache.remove(pixelRefStableID);
-}
-
-void TextureCache::clear() {
-    mCache.clear();
-    for (auto& iter : mHardwareTextures) {
-        iter.second->deleteTexture();
-    }
-    mHardwareTextures.clear();
-    TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize);
-}
-
-void TextureCache::flush() {
-    if (mFlushRate >= 1.0f || mCache.size() == 0) return;
-    if (mFlushRate <= 0.0f) {
-        clear();
-        return;
-    }
-
-    uint32_t targetSize = uint32_t(mSize * mFlushRate);
-    TEXTURE_LOGD("TextureCache::flush: target size: %d", targetSize);
-
-    while (mSize > targetSize) {
-        mCache.removeOldest();
-    }
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
deleted file mode 100644
index 19e7bea..0000000
--- a/libs/hwui/TextureCache.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2010 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_TEXTURE_CACHE_H
-#define ANDROID_HWUI_TEXTURE_CACHE_H
-
-#include <SkBitmap.h>
-
-#include <cutils/compiler.h>
-
-#include <utils/LruCache.h>
-#include <utils/Mutex.h>
-
-#include "Debug.h"
-
-#include <unordered_map>
-#include <vector>
-
-namespace android {
-
-class Bitmap;
-
-namespace uirenderer {
-
-class Texture;
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_TEXTURES
-#define TEXTURE_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-#define TEXTURE_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Classes
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * A simple LRU texture cache. The cache has a maximum size expressed in bytes.
- * Any texture added to the cache causing the cache to grow beyond the maximum
- * allowed size will also cause the oldest texture to be kicked out.
- */
-class TextureCache : public OnEntryRemoved<uint32_t, Texture*> {
-public:
-    TextureCache();
-    ~TextureCache();
-
-    /**
-     * Used as a callback when an entry is removed from the cache.
-     * Do not invoke directly.
-     */
-    void operator()(uint32_t&, Texture*& texture) override;
-
-    /**
-     * Resets all Textures to not be marked as in use
-     */
-    void resetMarkInUse(void* ownerToken);
-
-    /**
-     * Attempts to precache the SkBitmap. Returns true if a Texture was successfully
-     * acquired for the bitmap, false otherwise. If a Texture was acquired it is
-     * marked as in use.
-     */
-    bool prefetchAndMarkInUse(void* ownerToken, Bitmap* bitmap);
-
-    /**
-     * Attempts to precache the SkBitmap. Returns true if a Texture was successfully
-     * acquired for the bitmap, false otherwise. Does not mark the Texture
-     * as in use and won't update currently in-use Textures.
-     */
-    bool prefetch(Bitmap* bitmap);
-
-    /**
-     * Returns the texture associated with the specified bitmap from within the cache.
-     * If the texture cannot be found in the cache, a new texture is generated.
-     */
-    Texture* get(Bitmap* bitmap);
-
-    /**
-     * Removes the texture associated with the specified pixelRef. Must be called from RenderThread
-     * Returns true if a texture was destroyed, false if no texture with that id was found
-     */
-    bool destroyTexture(uint32_t pixelRefStableID);
-
-    /**
-     * Clears the cache. This causes all textures to be deleted.
-     */
-    void clear();
-
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-    /**
-     * Partially flushes the cache. The amount of memory freed by a flush
-     * is defined by the flush rate.
-     */
-    void flush();
-
-private:
-    bool canMakeTextureFromBitmap(Bitmap* bitmap);
-
-    Texture* getCachedTexture(Bitmap* bitmap);
-    Texture* createTexture(Bitmap* bitmap);
-
-    LruCache<uint32_t, Texture*> mCache;
-
-    uint32_t mSize;
-    const uint32_t mMaxSize;
-    GLint mMaxTextureSize;
-
-    const float mFlushRate;
-
-    bool mDebugEnabled;
-
-    std::unordered_map<uint32_t, std::unique_ptr<Texture>> mHardwareTextures;
-};  // class TextureCache
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_TEXTURE_CACHE_H
diff --git a/libs/hwui/font/CachedGlyphInfo.h b/libs/hwui/font/CachedGlyphInfo.h
deleted file mode 100644
index 93bb823..0000000
--- a/libs/hwui/font/CachedGlyphInfo.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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_CACHED_GLYPH_INFO_H
-#define ANDROID_HWUI_CACHED_GLYPH_INFO_H
-
-namespace android {
-namespace uirenderer {
-
-class CacheTexture;
-
-struct CachedGlyphInfo {
-    // Has the cache been invalidated?
-    bool mIsValid;
-    // Location of the cached glyph in the bitmap
-    // in case we need to resize the texture or
-    // render to bitmap
-    uint32_t mStartX;
-    uint32_t mStartY;
-    uint32_t mBitmapWidth;
-    uint32_t mBitmapHeight;
-    // Also cache texture coords for the quad
-    float mBitmapMinU;
-    float mBitmapMinV;
-    float mBitmapMaxU;
-    float mBitmapMaxV;
-    // Minimize how much we call freetype
-    uint32_t mGlyphIndex;
-    float mAdvanceX;
-    float mAdvanceY;
-    // Values below contain a glyph's origin in the bitmap
-    int32_t mBitmapLeft;
-    int32_t mBitmapTop;
-    // Auto-kerning; represents a 2.6 fixed-point value with range [-1, 1].
-    int8_t mLsbDelta;
-    int8_t mRsbDelta;
-    CacheTexture* mCacheTexture;
-};
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_CACHED_GLYPH_INFO_H
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 5e33353..f173136 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -125,10 +125,7 @@
 }
 
 void RenderState::onBitmapDestroyed(uint32_t pixelRefId) {
-    if (mCaches && mCaches->textureCache.destroyTexture(pixelRefId)) {
-        glFlush();
-        GL_CHECKPOINT(MODERATE);
-    }
+    // DEAD CODE
 }
 
 void RenderState::setViewport(GLsizei width, GLsizei height) {
diff --git a/libs/hwui/tests/microbench/ShadowBench.cpp b/libs/hwui/tests/microbench/ShadowBench.cpp
deleted file mode 100644
index 12da783..0000000
--- a/libs/hwui/tests/microbench/ShadowBench.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2015 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 <benchmark/benchmark.h>
-
-#include "Matrix.h"
-#include "Rect.h"
-#include "TessellationCache.h"
-#include "Vector.h"
-#include "VertexBuffer.h"
-
-#include <SkPath.h>
-
-#include <memory>
-
-using namespace android;
-using namespace android::uirenderer;
-
-struct ShadowTestData {
-    Matrix4 drawTransform;
-    Rect localClip;
-    Matrix4 casterTransformXY;
-    Matrix4 casterTransformZ;
-    Vector3 lightCenter;
-    float lightRadius;
-};
-
-void createShadowTestData(ShadowTestData* out) {
-    static float SAMPLE_DRAW_TRANSFORM[] = {
-            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
-    };
-    static float SAMPLE_CASTERXY[] = {
-            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 32, 32, 0, 1,
-    };
-    static float SAMPLE_CASTERZ[] = {
-            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 32, 32, 32, 1,
-    };
-    static Rect SAMPLE_CLIP(0, 0, 1536, 2048);
-    static Vector3 SAMPLE_LIGHT_CENTER{768, -400, 1600};
-    static float SAMPLE_LIGHT_RADIUS = 1600;
-
-    out->drawTransform.load(SAMPLE_DRAW_TRANSFORM);
-    out->localClip = SAMPLE_CLIP;
-    out->casterTransformXY.load(SAMPLE_CASTERXY);
-    out->casterTransformZ.load(SAMPLE_CASTERZ);
-    out->lightCenter = SAMPLE_LIGHT_CENTER;
-    out->lightRadius = SAMPLE_LIGHT_RADIUS;
-}
-
-static inline void tessellateShadows(ShadowTestData& testData, bool opaque, const SkPath& shape,
-                                     VertexBuffer* ambient, VertexBuffer* spot) {
-    tessellateShadows(&testData.drawTransform, &testData.localClip, opaque, &shape,
-                      &testData.casterTransformXY, &testData.casterTransformZ, testData.lightCenter,
-                      testData.lightRadius, *ambient, *spot);
-}
-
-void BM_TessellateShadows_roundrect_opaque(benchmark::State& state) {
-    ShadowTestData shadowData;
-    createShadowTestData(&shadowData);
-    SkPath path;
-    path.addRoundRect(SkRect::MakeWH(100, 100), 5, 5);
-
-    while (state.KeepRunning()) {
-        VertexBuffer ambient;
-        VertexBuffer spot;
-        tessellateShadows(shadowData, true, path, &ambient, &spot);
-        benchmark::DoNotOptimize(&ambient);
-        benchmark::DoNotOptimize(&spot);
-    }
-}
-BENCHMARK(BM_TessellateShadows_roundrect_opaque);
-
-void BM_TessellateShadows_roundrect_translucent(benchmark::State& state) {
-    ShadowTestData shadowData;
-    createShadowTestData(&shadowData);
-    SkPath path;
-    path.reset();
-    path.addRoundRect(SkRect::MakeLTRB(0, 0, 100, 100), 5, 5);
-
-    while (state.KeepRunning()) {
-        std::unique_ptr<VertexBuffer> ambient(new VertexBuffer);
-        std::unique_ptr<VertexBuffer> spot(new VertexBuffer);
-        tessellateShadows(shadowData, false, path, ambient.get(), spot.get());
-        benchmark::DoNotOptimize(ambient.get());
-        benchmark::DoNotOptimize(spot.get());
-    }
-}
-BENCHMARK(BM_TessellateShadows_roundrect_translucent);
diff --git a/libs/hwui/utils/PaintUtils.h b/libs/hwui/utils/PaintUtils.h
index 233adae..f8e8a0a 100644
--- a/libs/hwui/utils/PaintUtils.h
+++ b/libs/hwui/utils/PaintUtils.h
@@ -20,6 +20,7 @@
 
 #include <SkColorFilter.h>
 #include <SkDrawLooper.h>
+#include <SkPaint.h>
 #include <SkShader.h>
 
 namespace android {