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 {
