diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index d716844..1ad40ec 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -210,8 +210,6 @@
         "DamageAccumulator.cpp",
         "DeferredLayerUpdater.cpp",
         "DeviceInfo.cpp",
-        "DisplayList.cpp",
-        "FrameBuilder.cpp",
         "FrameInfo.cpp",
         "FrameInfoVisualizer.cpp",
         "GlLayer.cpp",
@@ -237,7 +235,6 @@
         "Properties.cpp",
         "PropertyValuesAnimatorSet.cpp",
         "PropertyValuesHolder.cpp",
-        "RecordingCanvas.cpp",
         "RenderNode.cpp",
         "RenderProperties.cpp",
         "ResourceCache.cpp",
@@ -399,7 +396,6 @@
     srcs: [
         "tests/microbench/main.cpp",
         "tests/microbench/DisplayListCanvasBench.cpp",
-        "tests/microbench/FrameBuilderBench.cpp",
         "tests/microbench/LinearAllocatorBench.cpp",
         "tests/microbench/PathParserBench.cpp",
         "tests/microbench/RenderNodeBench.cpp",
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 42f4cf8..ed7b6eb 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -16,6 +16,8 @@
 #ifndef ANIMATOR_H
 #define ANIMATOR_H
 
+#include "CanvasProperty.h"
+
 #include <cutils/compiler.h>
 #include <utils/RefBase.h>
 #include <utils/StrongPointer.h>
@@ -31,8 +33,6 @@
 
 class AnimationContext;
 class BaseRenderNodeAnimator;
-class CanvasPropertyPrimitive;
-class CanvasPropertyPaint;
 class Interpolator;
 class RenderNode;
 class RenderProperties;
diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h
index ae8928e..72c9365 100644
--- a/libs/hwui/BakedOpRenderer.h
+++ b/libs/hwui/BakedOpRenderer.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include "BakedOpState.h"
+#include "Lighting.h"
 #include "Matrix.h"
 #include "utils/Macros.h"
 
@@ -42,16 +43,6 @@
 class BakedOpRenderer {
 public:
     typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&);
-    /**
-     * Position agnostic shadow lighting info. Used with all shadow ops in scene.
-     */
-    struct LightInfo {
-        LightInfo() : LightInfo(0, 0) {}
-        LightInfo(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha)
-                : ambientShadowAlpha(ambientShadowAlpha), spotShadowAlpha(spotShadowAlpha) {}
-        uint8_t ambientShadowAlpha;
-        uint8_t spotShadowAlpha;
-    };
 
     BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
                     const LightInfo& lightInfo)
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
deleted file mode 100644
index f1f0d2d..0000000
--- a/libs/hwui/DisplayList.cpp
+++ /dev/null
@@ -1,142 +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 <SkCanvas.h>
-#include <algorithm>
-
-#include <utils/Trace.h>
-
-#include "DamageAccumulator.h"
-#include "Debug.h"
-#include "DisplayList.h"
-#include "OpDumper.h"
-#include "RecordedOp.h"
-#include "RenderNode.h"
-#include "VectorDrawable.h"
-#include "renderthread/CanvasContext.h"
-
-namespace android {
-namespace uirenderer {
-
-DisplayList::DisplayList()
-        : projectionReceiveIndex(-1)
-        , stdAllocator(allocator)
-        , chunks(stdAllocator)
-        , ops(stdAllocator)
-        , children(stdAllocator)
-        , bitmapResources(stdAllocator)
-        , pathResources(stdAllocator)
-        , patchResources(stdAllocator)
-        , paints(stdAllocator)
-        , regions(stdAllocator)
-        , referenceHolders(stdAllocator)
-        , functors(stdAllocator)
-        , vectorDrawables(stdAllocator) {}
-
-DisplayList::~DisplayList() {
-    cleanupResources();
-}
-
-void DisplayList::cleanupResources() {
-    if (CC_UNLIKELY(patchResources.size())) {
-        ResourceCache& resourceCache = ResourceCache::getInstance();
-        resourceCache.lock();
-
-        for (size_t i = 0; i < patchResources.size(); i++) {
-            resourceCache.decrementRefcountLocked(patchResources[i]);
-        }
-
-        resourceCache.unlock();
-    }
-
-    for (size_t i = 0; i < pathResources.size(); i++) {
-        const SkPath* path = pathResources[i];
-        delete path;
-    }
-
-    for (auto& iter : functors) {
-        if (iter.listener) {
-            iter.listener->onGlFunctorReleased(iter.functor);
-        }
-    }
-
-    patchResources.clear();
-    pathResources.clear();
-    paints.clear();
-    regions.clear();
-}
-
-size_t DisplayList::addChild(NodeOpType* op) {
-    referenceHolders.push_back(op->renderNode);
-    size_t index = children.size();
-    children.push_back(op);
-    return index;
-}
-
-void DisplayList::syncContents() {
-    for (auto& iter : functors) {
-        (*iter.functor)(DrawGlInfo::kModeSync, nullptr);
-    }
-    for (auto& vectorDrawable : vectorDrawables) {
-        vectorDrawable->syncProperties();
-    }
-}
-
-void DisplayList::updateChildren(std::function<void(RenderNode*)> updateFn) {
-    for (auto&& child : children) {
-        updateFn(child->renderNode);
-    }
-}
-
-bool DisplayList::prepareListAndChildren(
-        TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
-        std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) {
-    info.prepareTextures = info.canvasContext.pinImages(bitmapResources);
-
-    for (auto&& op : children) {
-        RenderNode* childNode = op->renderNode;
-        info.damageAccumulator->pushTransform(&op->localMatrix);
-        bool childFunctorsNeedLayer =
-                functorsNeedLayer;  // TODO! || op->mRecordedWithPotentialStencilClip;
-        childFn(childNode, observer, info, childFunctorsNeedLayer);
-        info.damageAccumulator->popTransform();
-    }
-
-    bool isDirty = false;
-    for (auto& vectorDrawable : vectorDrawables) {
-        // If any vector drawable in the display list needs update, damage the node.
-        if (vectorDrawable->isDirty()) {
-            isDirty = true;
-        }
-        vectorDrawable->setPropertyChangeWillBeConsumed(true);
-    }
-    return isDirty;
-}
-
-void DisplayList::output(std::ostream& output, uint32_t level) {
-    for (auto&& op : getOps()) {
-        OpDumper::dump(*op, output, level + 1);
-        if (op->opId == RecordedOpId::RenderNodeOp) {
-            auto rnOp = reinterpret_cast<const RenderNodeOp*>(op);
-            rnOp->renderNode->output(output, level + 1);
-        } else {
-            output << std::endl;
-        }
-    }
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 7a9c65d..a952cc2 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -16,149 +16,20 @@
 
 #pragma once
 
-#include <SkCamera.h>
-#include <SkDrawable.h>
-#include <SkMatrix.h>
-
-#include <private/hwui/DrawGlInfo.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/LinearAllocator.h>
-#include <utils/RefBase.h>
-#include <utils/SortedVector.h>
-#include <utils/String8.h>
-
-#include <cutils/compiler.h>
-
-#include <androidfw/ResourceTypes.h>
-
-#include "CanvasProperty.h"
-#include "Debug.h"
-#include "GlFunctorLifecycleListener.h"
-#include "Matrix.h"
-#include "RenderProperties.h"
-#include "TreeInfo.h"
-#include "hwui/Bitmap.h"
-
-#include <vector>
-
-class SkBitmap;
-class SkPaint;
-class SkPath;
-class SkRegion;
+#include "pipeline/skia/SkiaDisplayList.h"
 
 namespace android {
 namespace uirenderer {
 
-struct ClipBase;
-class Rect;
-class Layer;
-
-struct RecordedOp;
-struct RenderNodeOp;
-
-typedef RecordedOp BaseOpType;
-typedef RenderNodeOp NodeOpType;
-
 namespace VectorDrawable {
 class Tree;
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
-struct FunctorContainer {
-    Functor* functor;
-    GlFunctorLifecycleListener* listener;
-};
-
 /**
  * Data structure that holds the list of commands used in display list stream
  */
-class DisplayList {
-    friend class RecordingCanvas;
-
-public:
-    struct Chunk {
-        // range of included ops in DisplayList::ops()
-        size_t beginOpIndex;
-        size_t endOpIndex;
-
-        // range of included children in DisplayList::children()
-        size_t beginChildIndex;
-        size_t endChildIndex;
-
-        // whether children with non-zero Z in the chunk should be reordered
-        bool reorderChildren;
-
-        // clip at the beginning of a reorder section, applied to reordered children
-        const ClipBase* reorderClip;
-    };
-
-    DisplayList();
-    virtual ~DisplayList();
-
-    // index of DisplayListOp restore, after which projected descendants should be drawn
-    int projectionReceiveIndex;
-
-    const LsaVector<Chunk>& getChunks() const { return chunks; }
-    const LsaVector<BaseOpType*>& getOps() const { return ops; }
-
-    const LsaVector<NodeOpType*>& getChildren() const { return children; }
-
-    const LsaVector<sk_sp<Bitmap>>& getBitmapResources() const { return bitmapResources; }
-
-    size_t addChild(NodeOpType* childOp);
-
-    void ref(VirtualLightRefBase* prop) { referenceHolders.push_back(prop); }
-
-    size_t getUsedSize() { return allocator.usedSize(); }
-
-    virtual bool isEmpty() const { return ops.empty(); }
-    virtual bool hasFunctor() const { return !functors.empty(); }
-    virtual bool hasVectorDrawables() const { return !vectorDrawables.empty(); }
-    virtual bool isSkiaDL() const { return false; }
-    virtual bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) {
-        return false;
-    }
-
-    virtual void syncContents();
-    virtual void updateChildren(std::function<void(RenderNode*)> updateFn);
-    virtual bool prepareListAndChildren(
-            TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
-            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn);
-
-    virtual void output(std::ostream& output, uint32_t level);
-
-protected:
-    // allocator into which all ops and LsaVector arrays allocated
-    LinearAllocator allocator;
-    LinearStdAllocator<void*> stdAllocator;
-
-private:
-    LsaVector<Chunk> chunks;
-    LsaVector<BaseOpType*> ops;
-
-    // list of Ops referring to RenderNode children for quick, non-drawing traversal
-    LsaVector<NodeOpType*> children;
-
-    // Resources - Skia objects + 9 patches referred to by this DisplayList
-    LsaVector<sk_sp<Bitmap>> bitmapResources;
-    LsaVector<const SkPath*> pathResources;
-    LsaVector<const Res_png_9patch*> patchResources;
-    LsaVector<std::unique_ptr<const SkPaint>> paints;
-    LsaVector<std::unique_ptr<const SkRegion>> regions;
-    LsaVector<sp<VirtualLightRefBase>> referenceHolders;
-
-    // List of functors
-    LsaVector<FunctorContainer> functors;
-
-    // List of VectorDrawables that need to be notified of pushStaging. Note that this list gets
-    // nothing
-    // but a callback during sync DisplayList, unlike the list of functors defined above, which
-    // gets special treatment exclusive for webview.
-    LsaVector<VectorDrawableRoot*> vectorDrawables;
-
-    void cleanupResources();
-};
+using DisplayList = skiapipeline::SkiaDisplayList;
 
 };  // namespace uirenderer
 };  // namespace android
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
deleted file mode 100644
index 575aea5..0000000
--- a/libs/hwui/FrameBuilder.cpp
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Copyright (C) 2016 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 "FrameBuilder.h"
-
-#include "DeferredLayerUpdater.h"
-#include "LayerUpdateQueue.h"
-#include "RenderNode.h"
-#include "VectorDrawable.h"
-#include "hwui/Canvas.h"
-#include "renderstate/OffscreenBufferPool.h"
-#include "utils/FatVector.h"
-#include "utils/PaintUtils.h"
-#include "utils/TraceUtils.h"
-
-#include <SkPathOps.h>
-#include <utils/TypeHelpers.h>
-
-namespace android {
-namespace uirenderer {
-
-FrameBuilder::FrameBuilder(const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight,
-                           const LightGeometry& lightGeometry, Caches& caches)
-        : mStdAllocator(mAllocator)
-        , mLayerBuilders(mStdAllocator)
-        , mLayerStack(mStdAllocator)
-        , mCanvasState(*this)
-        , mCaches(caches)
-        , mLightRadius(lightGeometry.radius)
-        , mDrawFbo0(true) {
-    // Prepare to defer Fbo0
-    auto fbo0 = mAllocator.create<LayerBuilder>(viewportWidth, viewportHeight, Rect(clip));
-    mLayerBuilders.push_back(fbo0);
-    mLayerStack.push_back(0);
-    mCanvasState.initializeSaveStack(viewportWidth, viewportHeight, clip.fLeft, clip.fTop,
-                                     clip.fRight, clip.fBottom, lightGeometry.center);
-}
-
-FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const LightGeometry& lightGeometry,
-                           Caches& caches)
-        : mStdAllocator(mAllocator)
-        , mLayerBuilders(mStdAllocator)
-        , mLayerStack(mStdAllocator)
-        , mCanvasState(*this)
-        , mCaches(caches)
-        , mLightRadius(lightGeometry.radius)
-        , mDrawFbo0(false) {
-    // TODO: remove, with each layer on its own save stack
-
-    // Prepare to defer Fbo0 (which will be empty)
-    auto fbo0 = mAllocator.create<LayerBuilder>(1, 1, Rect(1, 1));
-    mLayerBuilders.push_back(fbo0);
-    mLayerStack.push_back(0);
-    mCanvasState.initializeSaveStack(1, 1, 0, 0, 1, 1, lightGeometry.center);
-
-    deferLayers(layers);
-}
-
-void FrameBuilder::deferLayers(const LayerUpdateQueue& layers) {
-    // Render all layers to be updated, in order. Defer in reverse order, so that they'll be
-    // updated in the order they're passed in (mLayerBuilders are issued to Renderer in reverse)
-    for (int i = layers.entries().size() - 1; i >= 0; i--) {
-        RenderNode* layerNode = layers.entries()[i].renderNode.get();
-        // only schedule repaint if node still on layer - possible it may have been
-        // removed during a dropped frame, but layers may still remain scheduled so
-        // as not to lose info on what portion is damaged
-        OffscreenBuffer* layer = layerNode->getLayer();
-        if (CC_LIKELY(layer)) {
-            ATRACE_FORMAT("Optimize HW Layer DisplayList %s %ux%u", layerNode->getName(),
-                          layerNode->getWidth(), layerNode->getHeight());
-
-            Rect layerDamage = layers.entries()[i].damage;
-            // TODO: ensure layer damage can't be larger than layer
-            layerDamage.doIntersect(0, 0, layer->viewportWidth, layer->viewportHeight);
-            layerNode->computeOrdering();
-
-            // map current light center into RenderNode's coordinate space
-            Vector3 lightCenter = mCanvasState.currentSnapshot()->getRelativeLightCenter();
-            layer->inverseTransformInWindow.mapPoint3d(lightCenter);
-
-            saveForLayer(layerNode->getWidth(), layerNode->getHeight(), 0, 0, layerDamage,
-                         lightCenter, nullptr, layerNode);
-
-            if (layerNode->getDisplayList()) {
-                deferNodeOps(*layerNode);
-            }
-            restoreForLayer();
-        }
-    }
-}
-
-void FrameBuilder::deferRenderNode(RenderNode& renderNode) {
-    renderNode.computeOrdering();
-
-    mCanvasState.save(SaveFlags::MatrixClip);
-    deferNodePropsAndOps(renderNode);
-    mCanvasState.restore();
-}
-
-void FrameBuilder::deferRenderNode(float tx, float ty, Rect clipRect, RenderNode& renderNode) {
-    renderNode.computeOrdering();
-
-    mCanvasState.save(SaveFlags::MatrixClip);
-    mCanvasState.translate(tx, ty);
-    mCanvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-                          SkClipOp::kIntersect);
-    deferNodePropsAndOps(renderNode);
-    mCanvasState.restore();
-}
-
-static Rect nodeBounds(RenderNode& node) {
-    auto& props = node.properties();
-    return Rect(props.getLeft(), props.getTop(), props.getRight(), props.getBottom());
-}
-
-void FrameBuilder::deferRenderNodeScene(const std::vector<sp<RenderNode> >& nodes,
-                                        const Rect& contentDrawBounds) {
-    if (nodes.size() < 1) return;
-    if (nodes.size() == 1) {
-        if (!nodes[0]->nothingToDraw()) {
-            deferRenderNode(*nodes[0]);
-        }
-        return;
-    }
-    // It there are multiple render nodes, they are laid out as follows:
-    // #0 - backdrop (content + caption)
-    // #1 - content (local bounds are at (0,0), will be translated and clipped to backdrop)
-    // #2 - additional overlay nodes
-    // Usually the backdrop cannot be seen since it will be entirely covered by the content. While
-    // resizing however it might become partially visible. The following render loop will crop the
-    // backdrop against the content and draw the remaining part of it. It will then draw the content
-    // cropped to the backdrop (since that indicates a shrinking of the window).
-    //
-    // Additional nodes will be drawn on top with no particular clipping semantics.
-
-    // Usually the contents bounds should be mContentDrawBounds - however - we will
-    // move it towards the fixed edge to give it a more stable appearance (for the moment).
-    // If there is no content bounds we ignore the layering as stated above and start with 2.
-
-    // Backdrop bounds in render target space
-    const Rect backdrop = nodeBounds(*nodes[0]);
-
-    // Bounds that content will fill in render target space (note content node bounds may be bigger)
-    Rect content(contentDrawBounds.getWidth(), contentDrawBounds.getHeight());
-    content.translate(backdrop.left, backdrop.top);
-    if (!content.contains(backdrop) && !nodes[0]->nothingToDraw()) {
-        // Content doesn't entirely overlap backdrop, so fill around content (right/bottom)
-
-        // Note: in the future, if content doesn't snap to backdrop's left/top, this may need to
-        // also fill left/top. Currently, both 2up and freeform position content at the top/left of
-        // the backdrop, so this isn't necessary.
-        if (content.right < backdrop.right) {
-            // draw backdrop to right side of content
-            deferRenderNode(0, 0,
-                            Rect(content.right, backdrop.top, backdrop.right, backdrop.bottom),
-                            *nodes[0]);
-        }
-        if (content.bottom < backdrop.bottom) {
-            // draw backdrop to bottom of content
-            // Note: bottom fill uses content left/right, to avoid overdrawing left/right fill
-            deferRenderNode(0, 0,
-                            Rect(content.left, content.bottom, content.right, backdrop.bottom),
-                            *nodes[0]);
-        }
-    }
-
-    if (!nodes[1]->nothingToDraw()) {
-        if (!backdrop.isEmpty()) {
-            // content node translation to catch up with backdrop
-            float dx = contentDrawBounds.left - backdrop.left;
-            float dy = contentDrawBounds.top - backdrop.top;
-
-            Rect contentLocalClip = backdrop;
-            contentLocalClip.translate(dx, dy);
-            deferRenderNode(-dx, -dy, contentLocalClip, *nodes[1]);
-        } else {
-            deferRenderNode(*nodes[1]);
-        }
-    }
-
-    // remaining overlay nodes, simply defer
-    for (size_t index = 2; index < nodes.size(); index++) {
-        if (!nodes[index]->nothingToDraw()) {
-            deferRenderNode(*nodes[index]);
-        }
-    }
-}
-
-void FrameBuilder::onViewportInitialized() {}
-
-void FrameBuilder::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
-
-void FrameBuilder::deferNodePropsAndOps(RenderNode& node) {
-    const RenderProperties& properties = node.properties();
-    const Outline& outline = properties.getOutline();
-    if (properties.getAlpha() <= 0 || (outline.getShouldClip() && outline.isEmpty()) ||
-        properties.getScaleX() == 0 || properties.getScaleY() == 0) {
-        return;  // rejected
-    }
-
-    if (properties.getLeft() != 0 || properties.getTop() != 0) {
-        mCanvasState.translate(properties.getLeft(), properties.getTop());
-    }
-    if (properties.getStaticMatrix()) {
-        mCanvasState.concatMatrix(*properties.getStaticMatrix());
-    } else if (properties.getAnimationMatrix()) {
-        mCanvasState.concatMatrix(*properties.getAnimationMatrix());
-    }
-    if (properties.hasTransformMatrix()) {
-        if (properties.isTransformTranslateOnly()) {
-            mCanvasState.translate(properties.getTranslationX(), properties.getTranslationY());
-        } else {
-            mCanvasState.concatMatrix(*properties.getTransformMatrix());
-        }
-    }
-
-    const int width = properties.getWidth();
-    const int height = properties.getHeight();
-
-    Rect saveLayerBounds;  // will be set to non-empty if saveLayer needed
-    const bool isLayer = properties.effectiveLayerType() != LayerType::None;
-    int clipFlags = properties.getClippingFlags();
-    if (properties.getAlpha() < 1) {
-        if (isLayer) {
-            clipFlags &= ~CLIP_TO_BOUNDS;  // bounds clipping done by layer
-        }
-        if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering())) {
-            // simply scale rendering content's alpha
-            mCanvasState.scaleAlpha(properties.getAlpha());
-        } else {
-            // schedule saveLayer by initializing saveLayerBounds
-            saveLayerBounds.set(0, 0, width, height);
-            if (clipFlags) {
-                properties.getClippingRectForFlags(clipFlags, &saveLayerBounds);
-                clipFlags = 0;  // all clipping done by savelayer
-            }
-        }
-
-        if (CC_UNLIKELY(ATRACE_ENABLED() && properties.promotedToLayer())) {
-            // pretend alpha always causes savelayer to warn about
-            // performance problem affecting old versions
-            ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", node.getName(), width, height);
-        }
-    }
-    if (clipFlags) {
-        Rect clipRect;
-        properties.getClippingRectForFlags(clipFlags, &clipRect);
-        mCanvasState.clipRect(clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-                              SkClipOp::kIntersect);
-    }
-
-    if (properties.getRevealClip().willClip()) {
-        Rect bounds;
-        properties.getRevealClip().getBounds(&bounds);
-        mCanvasState.setClippingRoundRect(mAllocator, bounds,
-                                          properties.getRevealClip().getRadius());
-    } else if (properties.getOutline().willClip()) {
-        mCanvasState.setClippingOutline(mAllocator, &(properties.getOutline()));
-    }
-
-    bool quickRejected = mCanvasState.currentSnapshot()->getRenderTargetClip().isEmpty() ||
-                         (properties.getClipToBounds() &&
-                          mCanvasState.quickRejectConservative(0, 0, width, height));
-    if (!quickRejected) {
-        // not rejected, so defer render as either Layer, or direct (possibly wrapped in saveLayer)
-        if (node.getLayer()) {
-            // HW layer
-            LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(node);
-            BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp);
-            if (bakedOpState) {
-                // Node's layer already deferred, schedule it to render into parent layer
-                currentLayer().deferUnmergeableOp(mAllocator, bakedOpState, OpBatchType::Bitmap);
-            }
-        } else if (CC_UNLIKELY(!saveLayerBounds.isEmpty())) {
-            // draw DisplayList contents within temporary, since persisted layer could not be used.
-            // (temp layers are clipped to viewport, since they don't persist offscreen content)
-            SkPaint saveLayerPaint;
-            saveLayerPaint.setAlpha(properties.getAlpha());
-            deferBeginLayerOp(*mAllocator.create_trivial<BeginLayerOp>(
-                    saveLayerBounds, Matrix4::identity(),
-                    nullptr,  // no record-time clip - need only respect defer-time one
-                    &saveLayerPaint));
-            deferNodeOps(node);
-            deferEndLayerOp(*mAllocator.create_trivial<EndLayerOp>());
-        } else {
-            deferNodeOps(node);
-        }
-    }
-}
-
-typedef key_value_pair_t<float, const RenderNodeOp*> ZRenderNodeOpPair;
-
-template <typename V>
-static void buildZSortedChildList(V* zTranslatedNodes, const DisplayList& displayList,
-                                  const DisplayList::Chunk& chunk) {
-    if (chunk.beginChildIndex == chunk.endChildIndex) return;
-
-    for (size_t i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) {
-        RenderNodeOp* childOp = displayList.getChildren()[i];
-        RenderNode* child = childOp->renderNode;
-        float childZ = child->properties().getZ();
-
-        if (!MathUtils::isZero(childZ) && chunk.reorderChildren) {
-            zTranslatedNodes->push_back(ZRenderNodeOpPair(childZ, childOp));
-            childOp->skipInOrderDraw = true;
-        } else if (!child->properties().getProjectBackwards()) {
-            // regular, in order drawing DisplayList
-            childOp->skipInOrderDraw = false;
-        }
-    }
-
-    // Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order)
-    std::stable_sort(zTranslatedNodes->begin(), zTranslatedNodes->end());
-}
-
-template <typename V>
-static size_t findNonNegativeIndex(const V& zTranslatedNodes) {
-    for (size_t i = 0; i < zTranslatedNodes.size(); i++) {
-        if (zTranslatedNodes[i].key >= 0.0f) return i;
-    }
-    return zTranslatedNodes.size();
-}
-
-template <typename V>
-void FrameBuilder::defer3dChildren(const ClipBase* reorderClip, ChildrenSelectMode mode,
-                                   const V& zTranslatedNodes) {
-    const int size = zTranslatedNodes.size();
-    if (size == 0 || (mode == ChildrenSelectMode::Negative && zTranslatedNodes[0].key > 0.0f) ||
-        (mode == ChildrenSelectMode::Positive && zTranslatedNodes[size - 1].key < 0.0f)) {
-        // no 3d children to draw
-        return;
-    }
-
-    /**
-     * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
-     * with very similar Z heights to draw together.
-     *
-     * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
-     * underneath both, and neither's shadow is drawn on top of the other.
-     */
-    const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
-    size_t drawIndex, shadowIndex, endIndex;
-    if (mode == ChildrenSelectMode::Negative) {
-        drawIndex = 0;
-        endIndex = nonNegativeIndex;
-        shadowIndex = endIndex;  // draw no shadows
-    } else {
-        drawIndex = nonNegativeIndex;
-        endIndex = size;
-        shadowIndex = drawIndex;  // potentially draw shadow for each pos Z child
-    }
-
-    float lastCasterZ = 0.0f;
-    while (shadowIndex < endIndex || drawIndex < endIndex) {
-        if (shadowIndex < endIndex) {
-            const RenderNodeOp* casterNodeOp = zTranslatedNodes[shadowIndex].value;
-            const float casterZ = zTranslatedNodes[shadowIndex].key;
-            // attempt to render the shadow if the caster about to be drawn is its caster,
-            // OR if its caster's Z value is similar to the previous potential caster
-            if (shadowIndex == drawIndex || casterZ - lastCasterZ < 0.1f) {
-                deferShadow(reorderClip, *casterNodeOp);
-
-                lastCasterZ = casterZ;  // must do this even if current caster not casting a shadow
-                shadowIndex++;
-                continue;
-            }
-        }
-
-        const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
-        deferRenderNodeOpImpl(*childOp);
-        drawIndex++;
-    }
-}
-
-void FrameBuilder::deferShadow(const ClipBase* reorderClip, const RenderNodeOp& casterNodeOp) {
-    // DEAD CODE
-}
-
-void FrameBuilder::deferProjectedChildren(const RenderNode& renderNode) {
-    int count = mCanvasState.save(SaveFlags::MatrixClip);
-    const SkPath* projectionReceiverOutline = renderNode.properties().getOutline().getPath();
-
-    SkPath transformedMaskPath;  // on stack, since BakedOpState makes a deep copy
-    if (projectionReceiverOutline) {
-        // transform the mask for this projector into render target space
-        // TODO: consider combining both transforms by stashing transform instead of applying
-        SkMatrix skCurrentTransform;
-        mCanvasState.currentTransform()->copyTo(skCurrentTransform);
-        projectionReceiverOutline->transform(skCurrentTransform, &transformedMaskPath);
-        mCanvasState.setProjectionPathMask(&transformedMaskPath);
-    }
-
-    for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
-        RenderNodeOp* childOp = renderNode.mProjectedNodes[i];
-        RenderNode& childNode = *childOp->renderNode;
-
-        // Draw child if it has content, but ignore state in childOp - matrix already applied to
-        // transformFromCompositingAncestor, and record-time clip is ignored when projecting
-        if (!childNode.nothingToDraw()) {
-            int restoreTo = mCanvasState.save(SaveFlags::MatrixClip);
-
-            // Apply transform between ancestor and projected descendant
-            mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
-
-            deferNodePropsAndOps(childNode);
-
-            mCanvasState.restoreToCount(restoreTo);
-        }
-    }
-    mCanvasState.restoreToCount(count);
-}
-
-/**
- * Used to define a list of lambdas referencing private FrameBuilder::onXX::defer() methods.
- *
- * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas.
- * E.g. a BitmapOp op then would be dispatched to FrameBuilder::onBitmapOp(const BitmapOp&)
- */
-#define OP_RECEIVER(Type)                                       \
-    [](FrameBuilder& frameBuilder, const RecordedOp& op) {      \
-        frameBuilder.defer##Type(static_cast<const Type&>(op)); \
-    },
-void FrameBuilder::deferNodeOps(const RenderNode& renderNode) {
-    typedef void (*OpDispatcher)(FrameBuilder & frameBuilder, const RecordedOp& op);
-    static OpDispatcher receivers[] = BUILD_DEFERRABLE_OP_LUT(OP_RECEIVER);
-
-    // can't be null, since DL=null node rejection happens before deferNodePropsAndOps
-    const DisplayList& displayList = *(renderNode.getDisplayList());
-    for (auto& chunk : displayList.getChunks()) {
-        FatVector<ZRenderNodeOpPair, 16> zTranslatedNodes;
-        buildZSortedChildList(&zTranslatedNodes, displayList, chunk);
-
-        defer3dChildren(chunk.reorderClip, ChildrenSelectMode::Negative, zTranslatedNodes);
-        for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
-            const RecordedOp* op = displayList.getOps()[opIndex];
-            receivers[op->opId](*this, *op);
-
-            if (CC_UNLIKELY(!renderNode.mProjectedNodes.empty() &&
-                            displayList.projectionReceiveIndex >= 0 &&
-                            static_cast<int>(opIndex) == displayList.projectionReceiveIndex)) {
-                deferProjectedChildren(renderNode);
-            }
-        }
-        defer3dChildren(chunk.reorderClip, ChildrenSelectMode::Positive, zTranslatedNodes);
-    }
-}
-
-void FrameBuilder::deferRenderNodeOpImpl(const RenderNodeOp& op) {
-    if (op.renderNode->nothingToDraw()) return;
-    int count = mCanvasState.save(SaveFlags::MatrixClip);
-
-    // apply state from RecordedOp (clip first, since op's clip is transformed by current matrix)
-    mCanvasState.writableSnapshot()->applyClip(op.localClip,
-                                               *mCanvasState.currentSnapshot()->transform);
-    mCanvasState.concatMatrix(op.localMatrix);
-
-    // then apply state from node properties, and defer ops
-    deferNodePropsAndOps(*op.renderNode);
-
-    mCanvasState.restoreToCount(count);
-}
-
-void FrameBuilder::deferRenderNodeOp(const RenderNodeOp& op) {
-    if (!op.skipInOrderDraw) {
-        deferRenderNodeOpImpl(op);
-    }
-}
-
-/**
- * Defers an unmergeable, strokeable op, accounting correctly
- * for paint's style on the bounds being computed.
- */
-BakedOpState* FrameBuilder::deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
-                                              BakedOpState::StrokeBehavior strokeBehavior,
-                                              bool expandForPathTexture) {
-    // Note: here we account for stroke when baking the op
-    BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct(
-            mAllocator, *mCanvasState.writableSnapshot(), op, strokeBehavior, expandForPathTexture);
-    if (!bakedState) return nullptr;  // quick rejected
-
-    if (op.opId == RecordedOpId::RectOp && op.paint->getStyle() != SkPaint::kStroke_Style) {
-        bakedState->setupOpacity(op.paint);
-    }
-
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId);
-    return bakedState;
-}
-
-/**
- * Returns batch id for tessellatable shapes, based on paint. Checks to see if path effect/AA will
- * be used, since they trigger significantly different rendering paths.
- *
- * Note: not used for lines/points, since they don't currently support path effects.
- */
-static batchid_t tessBatchId(const RecordedOp& op) {
-    const SkPaint& paint = *(op.paint);
-    return paint.getPathEffect()
-                   ? OpBatchType::AlphaMaskTexture
-                   : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices);
-}
-
-void FrameBuilder::deferArcOp(const ArcOp& op) {
-    // Pass true below since arcs have a tendency to draw outside their expected bounds within
-    // their path textures. Passing true makes it more likely that we'll scissor, instead of
-    // corrupting the frame by drawing outside of clip bounds.
-    deferStrokeableOp(op, tessBatchId(op), BakedOpState::StrokeBehavior::StyleDefined, true);
-}
-
-static bool hasMergeableClip(const BakedOpState& state) {
-    return !state.computedState.clipState ||
-           state.computedState.clipState->mode == ClipMode::Rectangle;
-}
-
-void FrameBuilder::deferBitmapOp(const BitmapOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
-    if (!bakedState) return;  // quick rejected
-
-    if (op.bitmap->isOpaque()) {
-        bakedState->setupOpacity(op.paint);
-    }
-
-    // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
-    // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
-    // MergingDrawBatch::canMergeWith()
-    if (bakedState->computedState.transform.isSimple() &&
-        bakedState->computedState.transform.positiveScale() &&
-        PaintUtils::getBlendModeDirect(op.paint) == SkBlendMode::kSrcOver &&
-        op.bitmap->colorType() != kAlpha_8_SkColorType && hasMergeableClip(*bakedState)) {
-        mergeid_t mergeId = reinterpret_cast<mergeid_t>(op.bitmap->getGenerationID());
-        currentLayer().deferMergeableOp(mAllocator, bakedState, OpBatchType::Bitmap, mergeId);
-    } else {
-        currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
-    }
-}
-
-void FrameBuilder::deferBitmapMeshOp(const BitmapMeshOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
-}
-
-void FrameBuilder::deferBitmapRectOp(const BitmapRectOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
-}
-
-void FrameBuilder::deferVectorDrawableOp(const VectorDrawableOp& op) {
-    Bitmap& bitmap = op.vectorDrawable->getBitmapUpdateIfDirty();
-    SkPaint* paint = op.vectorDrawable->getPaint();
-    const BitmapRectOp* resolvedOp = mAllocator.create_trivial<BitmapRectOp>(
-            op.unmappedBounds, op.localMatrix, op.localClip, paint, &bitmap,
-            Rect(bitmap.width(), bitmap.height()));
-    deferBitmapRectOp(*resolvedOp);
-}
-
-void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) {
-    // allocate a temporary oval op (with mAllocator, so it persists until render), so the
-    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
-    float x = *(op.x);
-    float y = *(op.y);
-    float radius = *(op.radius);
-    Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius);
-    const OvalOp* resolvedOp = mAllocator.create_trivial<OvalOp>(unmappedBounds, op.localMatrix,
-                                                                 op.localClip, op.paint);
-    deferOvalOp(*resolvedOp);
-}
-
-void FrameBuilder::deferColorOp(const ColorOp& op) {
-    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
-}
-
-void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
-    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Functor);
-}
-
-void FrameBuilder::deferLinesOp(const LinesOp& op) {
-    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
-    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
-}
-
-void FrameBuilder::deferOvalOp(const OvalOp& op) {
-    deferStrokeableOp(op, tessBatchId(op));
-}
-
-void FrameBuilder::deferPatchOp(const PatchOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
-    if (!bakedState) return;  // quick rejected
-
-    if (bakedState->computedState.transform.isPureTranslate() &&
-        PaintUtils::getBlendModeDirect(op.paint) == SkBlendMode::kSrcOver &&
-        hasMergeableClip(*bakedState)) {
-        mergeid_t mergeId = reinterpret_cast<mergeid_t>(op.bitmap->getGenerationID());
-
-        // Only use the MergedPatch batchId when merged, so Bitmap+Patch don't try to merge together
-        currentLayer().deferMergeableOp(mAllocator, bakedState, OpBatchType::MergedPatch, mergeId);
-    } else {
-        // Use Bitmap batchId since Bitmap+Patch use same shader
-        currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
-    }
-}
-
-void FrameBuilder::deferPathOp(const PathOp& op) {
-    /*auto state = */deferStrokeableOp(op, OpBatchType::AlphaMaskTexture);
-}
-
-void FrameBuilder::deferPointsOp(const PointsOp& op) {
-    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
-    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
-}
-
-void FrameBuilder::deferRectOp(const RectOp& op) {
-    deferStrokeableOp(op, tessBatchId(op));
-}
-
-void FrameBuilder::deferRoundRectOp(const RoundRectOp& op) {
-    // DEAD CODE
-}
-
-void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) {
-    // allocate a temporary round rect op (with mAllocator, so it persists until render), so the
-    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
-    const RoundRectOp* resolvedOp = mAllocator.create_trivial<RoundRectOp>(
-            Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)), op.localMatrix, op.localClip,
-            op.paint, *op.rx, *op.ry);
-    deferRoundRectOp(*resolvedOp);
-}
-
-void FrameBuilder::deferSimpleRectsOp(const SimpleRectsOp& op) {
-    BakedOpState* bakedState = tryBakeOpState(op);
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
-}
-
-void FrameBuilder::deferTextOp(const TextOp& op) {
-    // DEAD CODE
-}
-
-void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) {
-    // DEAD CODE
-}
-
-void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) {
-    GlLayer* layer = static_cast<GlLayer*>(op.layerHandle->backingLayer());
-    if (CC_UNLIKELY(!layer || !layer->isRenderable())) return;
-
-    const TextureLayerOp* textureLayerOp = &op;
-    // Now safe to access transform (which was potentially unready at record time)
-    if (!layer->getTransform().isIdentity()) {
-        // non-identity transform present, so 'inject it' into op by copying + replacing matrix
-        Matrix4 combinedMatrix(op.localMatrix);
-        combinedMatrix.multiply(layer->getTransform());
-        textureLayerOp = mAllocator.create<TextureLayerOp>(op, combinedMatrix);
-    }
-    BakedOpState* bakedState = tryBakeOpState(*textureLayerOp);
-
-    if (!bakedState) return;  // quick rejected
-    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::TextureLayer);
-}
-
-void FrameBuilder::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, float contentTranslateX,
-                                float contentTranslateY, const Rect& repaintRect,
-                                const Vector3& lightCenter, const BeginLayerOp* beginLayerOp,
-                                RenderNode* renderNode) {
-    mCanvasState.save(SaveFlags::MatrixClip);
-    mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight);
-    mCanvasState.writableSnapshot()->roundRectClipState = nullptr;
-    mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter);
-    mCanvasState.writableSnapshot()->transform->loadTranslate(contentTranslateX, contentTranslateY,
-                                                              0);
-    mCanvasState.writableSnapshot()->setClip(repaintRect.left, repaintRect.top, repaintRect.right,
-                                             repaintRect.bottom);
-
-    // create a new layer repaint, and push its index on the stack
-    mLayerStack.push_back(mLayerBuilders.size());
-    auto newFbo = mAllocator.create<LayerBuilder>(layerWidth, layerHeight, repaintRect,
-                                                  beginLayerOp, renderNode);
-    mLayerBuilders.push_back(newFbo);
-}
-
-void FrameBuilder::restoreForLayer() {
-    // restore canvas, and pop finished layer off of the stack
-    mCanvasState.restore();
-    mLayerStack.pop_back();
-}
-
-// TODO: defer time rejection (when bounds become empty) + tests
-// Option - just skip layers with no bounds at playback + defer?
-void FrameBuilder::deferBeginLayerOp(const BeginLayerOp& op) {
-    uint32_t layerWidth = (uint32_t)op.unmappedBounds.getWidth();
-    uint32_t layerHeight = (uint32_t)op.unmappedBounds.getHeight();
-
-    auto previous = mCanvasState.currentSnapshot();
-    Vector3 lightCenter = previous->getRelativeLightCenter();
-
-    // Combine all transforms used to present saveLayer content:
-    // parent content transform * canvas transform * bounds offset
-    Matrix4 contentTransform(*(previous->transform));
-    contentTransform.multiply(op.localMatrix);
-    contentTransform.translate(op.unmappedBounds.left, op.unmappedBounds.top);
-
-    Matrix4 inverseContentTransform;
-    inverseContentTransform.loadInverse(contentTransform);
-
-    // map the light center into layer-relative space
-    inverseContentTransform.mapPoint3d(lightCenter);
-
-    // Clip bounds of temporary layer to parent's clip rect, so:
-    Rect saveLayerBounds(layerWidth, layerHeight);
-    //     1) transform Rect(width, height) into parent's space
-    //        note: left/top offsets put in contentTransform above
-    contentTransform.mapRect(saveLayerBounds);
-    //     2) intersect with parent's clip
-    saveLayerBounds.doIntersect(previous->getRenderTargetClip());
-    //     3) and transform back
-    inverseContentTransform.mapRect(saveLayerBounds);
-    saveLayerBounds.doIntersect(Rect(layerWidth, layerHeight));
-    saveLayerBounds.roundOut();
-
-    // if bounds are reduced, will clip the layer's area by reducing required bounds...
-    layerWidth = saveLayerBounds.getWidth();
-    layerHeight = saveLayerBounds.getHeight();
-    // ...and shifting drawing content to account for left/top side clipping
-    float contentTranslateX = -saveLayerBounds.left;
-    float contentTranslateY = -saveLayerBounds.top;
-
-    saveForLayer(layerWidth, layerHeight, contentTranslateX, contentTranslateY,
-                 Rect(layerWidth, layerHeight), lightCenter, &op, nullptr);
-}
-
-void FrameBuilder::deferEndLayerOp(const EndLayerOp& /* ignored */) {
-    const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp;
-    int finishedLayerIndex = mLayerStack.back();
-
-    restoreForLayer();
-
-    // saveLayer will clip & translate the draw contents, so we need
-    // to translate the drawLayer by how much the contents was translated
-    // TODO: Unify this with beginLayerOp so we don't have to calculate this
-    // twice
-    uint32_t layerWidth = (uint32_t)beginLayerOp.unmappedBounds.getWidth();
-    uint32_t layerHeight = (uint32_t)beginLayerOp.unmappedBounds.getHeight();
-
-    auto previous = mCanvasState.currentSnapshot();
-    Vector3 lightCenter = previous->getRelativeLightCenter();
-
-    // Combine all transforms used to present saveLayer content:
-    // parent content transform * canvas transform * bounds offset
-    Matrix4 contentTransform(*(previous->transform));
-    contentTransform.multiply(beginLayerOp.localMatrix);
-    contentTransform.translate(beginLayerOp.unmappedBounds.left, beginLayerOp.unmappedBounds.top);
-
-    Matrix4 inverseContentTransform;
-    inverseContentTransform.loadInverse(contentTransform);
-
-    // map the light center into layer-relative space
-    inverseContentTransform.mapPoint3d(lightCenter);
-
-    // Clip bounds of temporary layer to parent's clip rect, so:
-    Rect saveLayerBounds(layerWidth, layerHeight);
-    //     1) transform Rect(width, height) into parent's space
-    //        note: left/top offsets put in contentTransform above
-    contentTransform.mapRect(saveLayerBounds);
-    //     2) intersect with parent's clip
-    saveLayerBounds.doIntersect(previous->getRenderTargetClip());
-    //     3) and transform back
-    inverseContentTransform.mapRect(saveLayerBounds);
-    saveLayerBounds.doIntersect(Rect(layerWidth, layerHeight));
-    saveLayerBounds.roundOut();
-
-    Matrix4 localMatrix(beginLayerOp.localMatrix);
-    localMatrix.translate(saveLayerBounds.left, saveLayerBounds.top);
-
-    // record the draw operation into the previous layer's list of draw commands
-    // uses state from the associated beginLayerOp, since it has all the state needed for drawing
-    LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(
-            beginLayerOp.unmappedBounds, localMatrix, beginLayerOp.localClip, beginLayerOp.paint,
-            &(mLayerBuilders[finishedLayerIndex]->offscreenBuffer));
-    BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp);
-
-    if (bakedOpState) {
-        // Layer will be drawn into parent layer (which is now current, since we popped mLayerStack)
-        currentLayer().deferUnmergeableOp(mAllocator, bakedOpState, OpBatchType::Bitmap);
-    } else {
-        // Layer won't be drawn - delete its drawing batches to prevent it from doing any work
-        // TODO: need to prevent any render work from being done
-        // - create layerop earlier for reject purposes?
-        mLayerBuilders[finishedLayerIndex]->clear();
-        return;
-    }
-}
-
-void FrameBuilder::deferBeginUnclippedLayerOp(const BeginUnclippedLayerOp& op) {
-    Matrix4 boundsTransform(*(mCanvasState.currentSnapshot()->transform));
-    boundsTransform.multiply(op.localMatrix);
-
-    Rect dstRect(op.unmappedBounds);
-    boundsTransform.mapRect(dstRect);
-    dstRect.roundOut();
-    dstRect.doIntersect(mCanvasState.currentSnapshot()->getRenderTargetClip());
-
-    if (dstRect.isEmpty()) {
-        // Unclipped layer rejected - push a null op, so next EndUnclippedLayerOp is ignored
-        currentLayer().activeUnclippedSaveLayers.push_back(nullptr);
-    } else {
-        // Allocate a holding position for the layer object (copyTo will produce, copyFrom will
-        // consume)
-        OffscreenBuffer** layerHandle = mAllocator.create<OffscreenBuffer*>(nullptr);
-
-        /**
-         * First, defer an operation to copy out the content from the rendertarget into a layer.
-         */
-        auto copyToOp = mAllocator.create_trivial<CopyToLayerOp>(op, layerHandle);
-        BakedOpState* bakedState = BakedOpState::directConstruct(
-                mAllocator, &(currentLayer().repaintClip), dstRect, *copyToOp);
-        currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::CopyToLayer);
-
-        /**
-         * Defer a clear rect, so that clears from multiple unclipped layers can be drawn
-         * both 1) simultaneously, and 2) as long after the copyToLayer executes as possible
-         */
-        currentLayer().deferLayerClear(dstRect);
-
-        /**
-         * And stash an operation to copy that layer back under the rendertarget until
-         * a balanced EndUnclippedLayerOp is seen
-         */
-        auto copyFromOp = mAllocator.create_trivial<CopyFromLayerOp>(op, layerHandle);
-        bakedState = BakedOpState::directConstruct(mAllocator, &(currentLayer().repaintClip),
-                                                   dstRect, *copyFromOp);
-        currentLayer().activeUnclippedSaveLayers.push_back(bakedState);
-    }
-}
-
-void FrameBuilder::deferEndUnclippedLayerOp(const EndUnclippedLayerOp& /* ignored */) {
-    LOG_ALWAYS_FATAL_IF(currentLayer().activeUnclippedSaveLayers.empty(), "no layer to end!");
-
-    BakedOpState* copyFromLayerOp = currentLayer().activeUnclippedSaveLayers.back();
-    currentLayer().activeUnclippedSaveLayers.pop_back();
-    if (copyFromLayerOp) {
-        currentLayer().deferUnmergeableOp(mAllocator, copyFromLayerOp, OpBatchType::CopyFromLayer);
-    }
-}
-
-void FrameBuilder::finishDefer() {
-    // DEAD CODE
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h
deleted file mode 100644
index 974daf8..0000000
--- a/libs/hwui/FrameBuilder.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2016 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 "BakedOpState.h"
-#include "CanvasState.h"
-#include "DisplayList.h"
-#include "LayerBuilder.h"
-#include "RecordedOp.h"
-#include "utils/GLUtils.h"
-
-#include <unordered_map>
-#include <vector>
-
-struct SkRect;
-
-namespace android {
-namespace uirenderer {
-
-class BakedOpState;
-class LayerUpdateQueue;
-class OffscreenBuffer;
-class Rect;
-
-/**
- * Processes, optimizes, and stores rendering commands from RenderNodes and
- * LayerUpdateQueue, building content needed to render a frame.
- *
- * Resolves final drawing state for each operation (including clip, alpha and matrix), and then
- * reorder and merge each op as it is resolved for drawing efficiency. Each layer of content (either
- * from the LayerUpdateQueue, or temporary layers created by saveLayer operations in the
- * draw stream) will create different reorder contexts, each in its own LayerBuilder.
- *
- * Then the prepared or 'baked' drawing commands can be issued by calling the templated
- * replayBakedOps() function, which will dispatch them (including any created merged op collections)
- * to a Dispatcher and Renderer. See BakedOpDispatcher for how these baked drawing operations are
- * resolved into Glops and rendered via BakedOpRenderer.
- *
- * This class is also the authoritative source for traversing RenderNodes, both for standard op
- * traversal within a DisplayList, and for out of order RenderNode traversal for Z and projection.
- */
-class FrameBuilder : public CanvasStateClient {
-public:
-    struct LightGeometry {
-        Vector3 center;
-        float radius;
-    };
-
-    FrameBuilder(const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight,
-                 const LightGeometry& lightGeometry, Caches& caches);
-
-    FrameBuilder(const LayerUpdateQueue& layerUpdateQueue, const LightGeometry& lightGeometry,
-                 Caches& caches);
-
-    void deferLayers(const LayerUpdateQueue& layers);
-
-    void deferRenderNode(RenderNode& renderNode);
-
-    void deferRenderNode(float tx, float ty, Rect clipRect, RenderNode& renderNode);
-
-    void deferRenderNodeScene(const std::vector<sp<RenderNode> >& nodes,
-                              const Rect& contentDrawBounds);
-
-    virtual ~FrameBuilder() {}
-
-    /**
-     * replayBakedOps() is templated based on what class will receive ops being replayed.
-     *
-     * It constructs a lookup array of lambdas, which allows a recorded BakeOpState to use
-     * state->op->opId to lookup a receiver that will be called when the op is replayed.
-     */
-    template <typename StaticDispatcher, typename Renderer>
-    void replayBakedOps(Renderer& renderer) {
-        std::vector<OffscreenBuffer*> temporaryLayers;
-        finishDefer();
-/**
- * Defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to
- * dispatch the op via a method on a static dispatcher when the op is replayed.
- *
- * For example a BitmapOp would resolve, via the lambda lookup, to calling:
- *
- * StaticDispatcher::onBitmapOp(Renderer& renderer, const BitmapOp& op, const BakedOpState& state);
- */
-#define X(Type)                                                                   \
-    [](void* renderer, const BakedOpState& state) {                               \
-        StaticDispatcher::on##Type(*(static_cast<Renderer*>(renderer)),           \
-                                   static_cast<const Type&>(*(state.op)), state); \
-    },
-        static BakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
-#undef X
-
-/**
- * Defines a LUT of lambdas which allow merged arrays of BakedOpState* to be passed to a
- * static dispatcher when the group of merged ops is replayed.
- */
-#define X(Type)                                                                           \
-    [](void* renderer, const MergedBakedOpList& opList) {                                 \
-        StaticDispatcher::onMerged##Type##s(*(static_cast<Renderer*>(renderer)), opList); \
-    },
-        static MergedOpReceiver mergedReceivers[] = BUILD_MERGEABLE_OP_LUT(X);
-#undef X
-
-        // Relay through layers in reverse order, since layers
-        // later in the list will be drawn by earlier ones
-        for (int i = mLayerBuilders.size() - 1; i >= 1; i--) {
-            GL_CHECKPOINT(MODERATE);
-            LayerBuilder& layer = *(mLayerBuilders[i]);
-            if (layer.renderNode) {
-                // cached HW layer - can't skip layer if empty
-                renderer.startRepaintLayer(layer.offscreenBuffer, layer.repaintRect);
-                GL_CHECKPOINT(MODERATE);
-                layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-                GL_CHECKPOINT(MODERATE);
-                renderer.endLayer();
-            } else if (!layer.empty()) {
-                // save layer - skip entire layer if empty (in which case, LayerOp has null layer).
-                layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height);
-                temporaryLayers.push_back(layer.offscreenBuffer);
-                GL_CHECKPOINT(MODERATE);
-                layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-                GL_CHECKPOINT(MODERATE);
-                renderer.endLayer();
-            }
-        }
-
-        GL_CHECKPOINT(MODERATE);
-        if (CC_LIKELY(mDrawFbo0)) {
-            const LayerBuilder& fbo0 = *(mLayerBuilders[0]);
-            renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
-            GL_CHECKPOINT(MODERATE);
-            fbo0.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers);
-            GL_CHECKPOINT(MODERATE);
-            renderer.endFrame(fbo0.repaintRect);
-        }
-
-        for (auto& temporaryLayer : temporaryLayers) {
-            renderer.recycleTemporaryLayer(temporaryLayer);
-        }
-    }
-
-    void dump() const {
-        for (auto&& layer : mLayerBuilders) {
-            layer->dump();
-        }
-    }
-
-    ///////////////////////////////////////////////////////////////////
-    /// CanvasStateClient interface
-    ///////////////////////////////////////////////////////////////////
-    virtual void onViewportInitialized() override;
-    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
-    virtual GLuint getTargetFbo() const override { return 0; }
-
-private:
-    void finishDefer();
-    enum class ChildrenSelectMode { Negative, Positive };
-    void saveForLayer(uint32_t layerWidth, uint32_t layerHeight, float contentTranslateX,
-                      float contentTranslateY, const Rect& repaintRect, const Vector3& lightCenter,
-                      const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
-    void restoreForLayer();
-
-    LayerBuilder& currentLayer() { return *(mLayerBuilders[mLayerStack.back()]); }
-
-    BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) {
-        return BakedOpState::tryConstruct(mAllocator, *mCanvasState.writableSnapshot(), recordedOp);
-    }
-    BakedOpState* tryBakeUnboundedOpState(const RecordedOp& recordedOp) {
-        return BakedOpState::tryConstructUnbounded(mAllocator, *mCanvasState.writableSnapshot(),
-                                                   recordedOp);
-    }
-
-    // should always be surrounded by a save/restore pair, and not called if DisplayList is null
-    void deferNodePropsAndOps(RenderNode& node);
-
-    template <typename V>
-    void defer3dChildren(const ClipBase* reorderClip, ChildrenSelectMode mode,
-                         const V& zTranslatedNodes);
-
-    void deferShadow(const ClipBase* reorderClip, const RenderNodeOp& casterOp);
-
-    void deferProjectedChildren(const RenderNode& renderNode);
-
-    void deferNodeOps(const RenderNode& renderNode);
-
-    void deferRenderNodeOpImpl(const RenderNodeOp& op);
-
-    void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);
-
-    SkPath* createFrameAllocatedPath() { return mAllocator.create<SkPath>(); }
-
-    BakedOpState* deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
-                                    BakedOpState::StrokeBehavior strokeBehavior =
-                                            BakedOpState::StrokeBehavior::StyleDefined,
-                                    bool expandForPathTexture = false);
-
-/**
- * Declares all FrameBuilder::deferXXXXOp() methods for every RecordedOp type.
- *
- * These private methods are called from within deferImpl to defer each individual op
- * type differently.
- */
-#define X(Type) void defer##Type(const Type& op);
-    MAP_DEFERRABLE_OPS(X)
-#undef X
-
-    // contains single-frame objects, such as BakedOpStates, LayerBuilders, Batches
-    LinearAllocator mAllocator;
-    LinearStdAllocator<void*> mStdAllocator;
-
-    // List of every deferred layer's render state. Replayed in reverse order to render a frame.
-    LsaVector<LayerBuilder*> mLayerBuilders;
-
-    /*
-     * Stack of indices within mLayerBuilders representing currently active layers. If drawing
-     * layerA within a layerB, will contain, in order:
-     *  - 0 (representing FBO 0, always present)
-     *  - layerB's index
-     *  - layerA's index
-     *
-     * Note that this doesn't vector doesn't always map onto all values of mLayerBuilders. When a
-     * layer is finished deferring, it will still be represented in mLayerBuilders, but it's index
-     * won't be in mLayerStack. This is because it can be replayed, but can't have any more drawing
-     * ops added to it.
-    */
-    LsaVector<size_t> mLayerStack;
-
-    CanvasState mCanvasState;
-
-    Caches& mCaches;
-
-    float mLightRadius;
-
-    const bool mDrawFbo0;
-};
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/Lighting.h b/libs/hwui/Lighting.h
new file mode 100644
index 0000000..d972c21
--- /dev/null
+++ b/libs/hwui/Lighting.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 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 "Vector.h"
+
+namespace android {
+namespace uirenderer {
+
+struct LightGeometry {
+    Vector3 center;
+    float radius;
+};
+
+struct LightInfo {
+    LightInfo() : LightInfo(0, 0) {}
+    LightInfo(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha)
+            : ambientShadowAlpha(ambientShadowAlpha), spotShadowAlpha(spotShadowAlpha) {}
+    uint8_t ambientShadowAlpha;
+    uint8_t spotShadowAlpha;
+};
+
+};  // namespace uirenderer
+};  // namespace android
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
deleted file mode 100644
index e1df1e7..0000000
--- a/libs/hwui/RecordingCanvas.cpp
+++ /dev/null
@@ -1,631 +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 "RecordingCanvas.h"
-
-#include "DeferredLayerUpdater.h"
-#include "RecordedOp.h"
-#include "RenderNode.h"
-#include "VectorDrawable.h"
-#include "hwui/MinikinUtils.h"
-
-namespace android {
-namespace uirenderer {
-
-RecordingCanvas::RecordingCanvas(size_t width, size_t height)
-        : mState(*this), mResourceCache(ResourceCache::getInstance()) {
-    resetRecording(width, height);
-}
-
-RecordingCanvas::~RecordingCanvas() {
-    LOG_ALWAYS_FATAL_IF(mDisplayList, "Destroyed a RecordingCanvas during a record!");
-}
-
-void RecordingCanvas::resetRecording(int width, int height, RenderNode* node) {
-    LOG_ALWAYS_FATAL_IF(mDisplayList, "prepareDirty called a second time during a recording!");
-    mDisplayList = new DisplayList();
-
-    mState.initializeRecordingSaveStack(width, height);
-
-    mDeferredBarrierType = DeferredBarrierType::InOrder;
-}
-
-DisplayList* RecordingCanvas::finishRecording() {
-    restoreToCount(1);
-    mPaintMap.clear();
-    mRegionMap.clear();
-    mPathMap.clear();
-    DisplayList* displayList = mDisplayList;
-    mDisplayList = nullptr;
-    mSkiaCanvasProxy.reset(nullptr);
-    return displayList;
-}
-
-void RecordingCanvas::insertReorderBarrier(bool enableReorder) {
-    if (enableReorder) {
-        mDeferredBarrierType = DeferredBarrierType::OutOfOrder;
-        mDeferredBarrierClip = getRecordedClip();
-    } else {
-        mDeferredBarrierType = DeferredBarrierType::InOrder;
-        mDeferredBarrierClip = nullptr;
-    }
-}
-
-SkCanvas* RecordingCanvas::asSkCanvas() {
-    LOG_ALWAYS_FATAL_IF(!mDisplayList, "attempting to get an SkCanvas when we are not recording!");
-    if (!mSkiaCanvasProxy) {
-        mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
-    }
-
-    // SkCanvas instances default to identity transform, but should inherit
-    // the state of this Canvas; if this code was in the SkiaCanvasProxy
-    // constructor, we couldn't cache mSkiaCanvasProxy.
-    SkMatrix parentTransform;
-    getMatrix(&parentTransform);
-    mSkiaCanvasProxy.get()->setMatrix(parentTransform);
-
-    return mSkiaCanvasProxy.get();
-}
-
-// ----------------------------------------------------------------------------
-// CanvasStateClient implementation
-// ----------------------------------------------------------------------------
-
-void RecordingCanvas::onViewportInitialized() {}
-
-void RecordingCanvas::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {
-    if (removed.flags & Snapshot::kFlagIsFboLayer) {
-        addOp(alloc().create_trivial<EndLayerOp>());
-    } else if (removed.flags & Snapshot::kFlagIsLayer) {
-        addOp(alloc().create_trivial<EndUnclippedLayerOp>());
-    }
-}
-
-// ----------------------------------------------------------------------------
-// android/graphics/Canvas state operations
-// ----------------------------------------------------------------------------
-// Save (layer)
-int RecordingCanvas::save(SaveFlags::Flags flags) {
-    return mState.save((int)flags);
-}
-
-void RecordingCanvas::RecordingCanvas::restore() {
-    mState.restore();
-}
-
-void RecordingCanvas::restoreToCount(int saveCount) {
-    mState.restoreToCount(saveCount);
-}
-
-int RecordingCanvas::saveLayer(float left, float top, float right, float bottom,
-                               const SkPaint* paint, SaveFlags::Flags flags) {
-    // force matrix/clip isolation for layer
-    flags |= SaveFlags::MatrixClip;
-    bool clippedLayer = flags & SaveFlags::ClipToLayer;
-
-    const Snapshot& previous = *mState.currentSnapshot();
-
-    // initialize the snapshot as though it almost represents an FBO layer so deferred draw
-    // operations will be able to store and restore the current clip and transform info, and
-    // quick rejection will be correct (for display lists)
-
-    Rect unmappedBounds(left, top, right, bottom);
-    unmappedBounds.roundOut();
-
-    // determine clipped bounds relative to previous viewport.
-    Rect visibleBounds = unmappedBounds;
-    previous.transform->mapRect(visibleBounds);
-
-    if (CC_UNLIKELY(!clippedLayer && previous.transform->rectToRect() &&
-                    visibleBounds.contains(previous.getRenderTargetClip()))) {
-        // unlikely case where an unclipped savelayer is recorded with a clip it can use,
-        // as none of its unaffected/unclipped area is visible
-        clippedLayer = true;
-        flags |= SaveFlags::ClipToLayer;
-    }
-
-    visibleBounds.doIntersect(previous.getRenderTargetClip());
-    visibleBounds.snapToPixelBoundaries();
-    visibleBounds.doIntersect(Rect(previous.getViewportWidth(), previous.getViewportHeight()));
-
-    // Map visible bounds back to layer space, and intersect with parameter bounds
-    Rect layerBounds = visibleBounds;
-    if (CC_LIKELY(!layerBounds.isEmpty())) {
-        // if non-empty, can safely map by the inverse transform
-        Matrix4 inverse;
-        inverse.loadInverse(*previous.transform);
-        inverse.mapRect(layerBounds);
-        layerBounds.doIntersect(unmappedBounds);
-    }
-
-    int saveValue = mState.save((int)flags);
-    Snapshot& snapshot = *mState.writableSnapshot();
-
-    // layerBounds is in original bounds space, but clipped by current recording clip
-    if (!layerBounds.isEmpty() && !unmappedBounds.isEmpty()) {
-        if (CC_LIKELY(clippedLayer)) {
-            auto previousClip = getRecordedClip();  // capture before new snapshot clip has changed
-            if (addOp(alloc().create_trivial<BeginLayerOp>(
-                        unmappedBounds,
-                        *previous.transform,  // transform to *draw* with
-                        previousClip,         // clip to *draw* with
-                        refPaint(paint))) >= 0) {
-                snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer;
-                snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight());
-                snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f);
-
-                Rect clip = layerBounds;
-                clip.translate(-unmappedBounds.left, -unmappedBounds.top);
-                snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
-                snapshot.roundRectClipState = nullptr;
-                return saveValue;
-            }
-        } else {
-            if (addOp(alloc().create_trivial<BeginUnclippedLayerOp>(
-                        unmappedBounds, *mState.currentSnapshot()->transform, getRecordedClip(),
-                        refPaint(paint))) >= 0) {
-                snapshot.flags |= Snapshot::kFlagIsLayer;
-                return saveValue;
-            }
-        }
-    }
-
-    // Layer not needed, so skip recording it...
-    if (CC_LIKELY(clippedLayer)) {
-        // ... and set empty clip to reject inner content, if possible
-        snapshot.resetClip(0, 0, 0, 0);
-    }
-    return saveValue;
-}
-
-// Matrix
-void RecordingCanvas::rotate(float degrees) {
-    if (degrees == 0) return;
-
-    mState.rotate(degrees);
-}
-
-void RecordingCanvas::scale(float sx, float sy) {
-    if (sx == 1 && sy == 1) return;
-
-    mState.scale(sx, sy);
-}
-
-void RecordingCanvas::skew(float sx, float sy) {
-    mState.skew(sx, sy);
-}
-
-void RecordingCanvas::translate(float dx, float dy) {
-    if (dx == 0 && dy == 0) return;
-
-    mState.translate(dx, dy, 0);
-}
-
-// Clip
-bool RecordingCanvas::getClipBounds(SkRect* outRect) const {
-    *outRect = mState.getLocalClipBounds().toSkRect();
-    return !(outRect->isEmpty());
-}
-bool RecordingCanvas::quickRejectRect(float left, float top, float right, float bottom) const {
-    return mState.quickRejectConservative(left, top, right, bottom);
-}
-bool RecordingCanvas::quickRejectPath(const SkPath& path) const {
-    SkRect bounds = path.getBounds();
-    return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
-}
-bool RecordingCanvas::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
-    return mState.clipRect(left, top, right, bottom, op);
-}
-bool RecordingCanvas::clipPath(const SkPath* path, SkClipOp op) {
-    return mState.clipPath(path, op);
-}
-
-// ----------------------------------------------------------------------------
-// android/graphics/Canvas draw operations
-// ----------------------------------------------------------------------------
-void RecordingCanvas::drawColor(int color, SkBlendMode mode) {
-    addOp(alloc().create_trivial<ColorOp>(getRecordedClip(), color, mode));
-}
-
-void RecordingCanvas::drawPaint(const SkPaint& paint) {
-    SkRect bounds;
-    if (getClipBounds(&bounds)) {
-        drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint);
-    }
-}
-
-static Rect calcBoundsOfPoints(const float* points, int floatCount) {
-    Rect unmappedBounds(points[0], points[1], points[0], points[1]);
-    for (int i = 2; i < floatCount; i += 2) {
-        unmappedBounds.expandToCover(points[i], points[i + 1]);
-    }
-    return unmappedBounds;
-}
-
-// Geometry
-void RecordingCanvas::drawPoints(const float* points, int floatCount, const SkPaint& paint) {
-    if (CC_UNLIKELY(floatCount < 2 || paint.nothingToDraw())) return;
-    floatCount &= ~0x1;  // round down to nearest two
-
-    addOp(alloc().create_trivial<PointsOp>(
-            calcBoundsOfPoints(points, floatCount), *mState.currentSnapshot()->transform,
-            getRecordedClip(), refPaint(&paint), refBuffer<float>(points, floatCount), floatCount));
-}
-
-void RecordingCanvas::drawLines(const float* points, int floatCount, const SkPaint& paint) {
-    if (CC_UNLIKELY(floatCount < 4 || paint.nothingToDraw())) return;
-    floatCount &= ~0x3;  // round down to nearest four
-
-    addOp(alloc().create_trivial<LinesOp>(
-            calcBoundsOfPoints(points, floatCount), *mState.currentSnapshot()->transform,
-            getRecordedClip(), refPaint(&paint), refBuffer<float>(points, floatCount), floatCount));
-}
-
-void RecordingCanvas::drawRect(float left, float top, float right, float bottom,
-                               const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    addOp(alloc().create_trivial<RectOp>(Rect(left, top, right, bottom),
-                                         *(mState.currentSnapshot()->transform), getRecordedClip(),
-                                         refPaint(&paint)));
-}
-
-void RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint) {
-    if (rects == nullptr) return;
-
-    Vertex* rectData = (Vertex*)mDisplayList->allocator.create_trivial_array<Vertex>(vertexCount);
-    Vertex* vertex = rectData;
-
-    float left = FLT_MAX;
-    float top = FLT_MAX;
-    float right = FLT_MIN;
-    float bottom = FLT_MIN;
-    for (int index = 0; index < vertexCount; index += 4) {
-        float l = rects[index + 0];
-        float t = rects[index + 1];
-        float r = rects[index + 2];
-        float b = rects[index + 3];
-
-        Vertex::set(vertex++, l, t);
-        Vertex::set(vertex++, r, t);
-        Vertex::set(vertex++, l, b);
-        Vertex::set(vertex++, r, b);
-
-        left = std::min(left, l);
-        top = std::min(top, t);
-        right = std::max(right, r);
-        bottom = std::max(bottom, b);
-    }
-    addOp(alloc().create_trivial<SimpleRectsOp>(
-            Rect(left, top, right, bottom), *(mState.currentSnapshot()->transform),
-            getRecordedClip(), refPaint(paint), rectData, vertexCount));
-}
-
-void RecordingCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    if (paint.getStyle() == SkPaint::kFill_Style &&
-        (!paint.isAntiAlias() || mState.currentTransform()->isSimple())) {
-        int count = 0;
-        Vector<float> rects;
-        SkRegion::Iterator it(region);
-        while (!it.done()) {
-            const SkIRect& r = it.rect();
-            rects.push(r.fLeft);
-            rects.push(r.fTop);
-            rects.push(r.fRight);
-            rects.push(r.fBottom);
-            count += 4;
-            it.next();
-        }
-        drawSimpleRects(rects.array(), count, &paint);
-    } else {
-        SkRegion::Iterator it(region);
-        while (!it.done()) {
-            const SkIRect& r = it.rect();
-            drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
-            it.next();
-        }
-    }
-}
-
-void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom, float rx,
-                                    float ry, const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    if (CC_LIKELY(MathUtils::isPositive(rx) || MathUtils::isPositive(ry))) {
-        addOp(alloc().create_trivial<RoundRectOp>(Rect(left, top, right, bottom),
-                                                  *(mState.currentSnapshot()->transform),
-                                                  getRecordedClip(), refPaint(&paint), rx, ry));
-    } else {
-        drawRect(left, top, right, bottom, paint);
-    }
-}
-
-void RecordingCanvas::drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
-                                    CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
-                                    CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-                                    CanvasPropertyPaint* paint) {
-    mDisplayList->ref(left);
-    mDisplayList->ref(top);
-    mDisplayList->ref(right);
-    mDisplayList->ref(bottom);
-    mDisplayList->ref(rx);
-    mDisplayList->ref(ry);
-    mDisplayList->ref(paint);
-    refBitmapsInShader(paint->value.getShader());
-    addOp(alloc().create_trivial<RoundRectPropsOp>(
-            *(mState.currentSnapshot()->transform), getRecordedClip(), &paint->value, &left->value,
-            &top->value, &right->value, &bottom->value, &rx->value, &ry->value));
-}
-
-void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
-    // TODO: move to Canvas.h
-    if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return;
-
-    drawOval(x - radius, y - radius, x + radius, y + radius, paint);
-}
-
-void RecordingCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-                                 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
-    mDisplayList->ref(x);
-    mDisplayList->ref(y);
-    mDisplayList->ref(radius);
-    mDisplayList->ref(paint);
-    refBitmapsInShader(paint->value.getShader());
-    addOp(alloc().create_trivial<CirclePropsOp>(*(mState.currentSnapshot()->transform),
-                                                getRecordedClip(), &paint->value, &x->value,
-                                                &y->value, &radius->value));
-}
-
-void RecordingCanvas::drawOval(float left, float top, float right, float bottom,
-                               const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    addOp(alloc().create_trivial<OvalOp>(Rect(left, top, right, bottom),
-                                         *(mState.currentSnapshot()->transform), getRecordedClip(),
-                                         refPaint(&paint)));
-}
-
-void RecordingCanvas::drawArc(float left, float top, float right, float bottom, float startAngle,
-                              float sweepAngle, bool useCenter, const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    if (fabs(sweepAngle) >= 360.0f) {
-        drawOval(left, top, right, bottom, paint);
-    } else {
-        addOp(alloc().create_trivial<ArcOp>(
-                Rect(left, top, right, bottom), *(mState.currentSnapshot()->transform),
-                getRecordedClip(), refPaint(&paint), startAngle, sweepAngle, useCenter));
-    }
-}
-
-void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
-    if (CC_UNLIKELY(paint.nothingToDraw())) return;
-
-    addOp(alloc().create_trivial<PathOp>(Rect(path.getBounds()),
-                                         *(mState.currentSnapshot()->transform), getRecordedClip(),
-                                         refPaint(&paint), refPath(&path)));
-}
-
-void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
-    mDisplayList->ref(tree);
-    mDisplayList->vectorDrawables.push_back(tree);
-    addOp(alloc().create_trivial<VectorDrawableOp>(
-            tree, Rect(tree->stagingProperties()->getBounds()),
-            *(mState.currentSnapshot()->transform), getRecordedClip()));
-}
-
-// Bitmap-based
-void RecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
-    save(SaveFlags::Matrix);
-    translate(left, top);
-    drawBitmap(bitmap, paint);
-    restore();
-}
-
-void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) {
-    if (matrix.isIdentity()) {
-        drawBitmap(bitmap, paint);
-    } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) &&
-               MathUtils::isPositive(matrix.getScaleX()) &&
-               MathUtils::isPositive(matrix.getScaleY())) {
-        // SkMatrix::isScaleTranslate() not available in L
-        SkRect src;
-        SkRect dst;
-        bitmap.getBounds(&src);
-        matrix.mapRect(&dst, src);
-        drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom, dst.fLeft, dst.fTop,
-                   dst.fRight, dst.fBottom, paint);
-    } else {
-        save(SaveFlags::Matrix);
-        concat(matrix);
-        drawBitmap(bitmap, paint);
-        restore();
-    }
-}
-
-void RecordingCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
-                                 float srcBottom, float dstLeft, float dstTop, float dstRight,
-                                 float dstBottom, const SkPaint* paint) {
-    if (srcLeft == 0 && srcTop == 0 && srcRight == bitmap.width() && srcBottom == bitmap.height() &&
-        (srcBottom - srcTop == dstBottom - dstTop) && (srcRight - srcLeft == dstRight - dstLeft)) {
-        // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        save(SaveFlags::Matrix);
-        translate(dstLeft, dstTop);
-        drawBitmap(bitmap, paint);
-        restore();
-    } else {
-        addOp(alloc().create_trivial<BitmapRectOp>(
-                Rect(dstLeft, dstTop, dstRight, dstBottom), *(mState.currentSnapshot()->transform),
-                getRecordedClip(), refPaint(paint), refBitmap(bitmap),
-                Rect(srcLeft, srcTop, srcRight, srcBottom)));
-    }
-}
-
-void RecordingCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
-                                     const float* vertices, const int* colors,
-                                     const SkPaint* paint) {
-    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
-    addOp(alloc().create_trivial<BitmapMeshOp>(
-            calcBoundsOfPoints(vertices, vertexCount * 2), *(mState.currentSnapshot()->transform),
-            getRecordedClip(), refPaint(paint), refBitmap(bitmap), meshWidth, meshHeight,
-            refBuffer<float>(vertices, vertexCount * 2),  // 2 floats per vertex
-            refBuffer<int>(colors, vertexCount)));        // 1 color per vertex
-}
-
-void RecordingCanvas::drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& patch,
-                                    float dstLeft, float dstTop, float dstRight, float dstBottom,
-                                    const SkPaint* paint) {
-    addOp(alloc().create_trivial<PatchOp>(Rect(dstLeft, dstTop, dstRight, dstBottom),
-                                          *(mState.currentSnapshot()->transform), getRecordedClip(),
-                                          refPaint(paint), refBitmap(bitmap), refPatch(&patch)));
-}
-
-double RecordingCanvas::drawAnimatedImage(AnimatedImageDrawable*) {
-    // Unimplemented
-    return 0;
-}
-
-// Text
-void RecordingCanvas::drawGlyphs(ReadGlyphFunc glyphFunc, int glyphCount, const SkPaint& paint,
-                                 float x, float y, float boundsLeft, float boundsTop,
-                                 float boundsRight, float boundsBottom, float totalAdvance) {
-    if (glyphCount <= 0 || paint.nothingToDraw()) return;
-    uint16_t* glyphs = (glyph_t*)alloc().alloc<glyph_t>(glyphCount * sizeof(glyph_t));
-    float* positions = (float*)alloc().alloc<float>(2 * glyphCount * sizeof(float));
-    glyphFunc(glyphs, positions);
-
-    // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
-    addOp(alloc().create_trivial<TextOp>(Rect(boundsLeft, boundsTop, boundsRight, boundsBottom),
-                                         *(mState.currentSnapshot()->transform), getRecordedClip(),
-                                         refPaint(&paint), glyphs, positions, glyphCount, x, y));
-    drawTextDecorations(x, y, totalAdvance, paint);
-}
-
-void RecordingCanvas::drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
-                                       const SkPaint& paint, const SkPath& path, size_t start,
-                                       size_t end) {
-    uint16_t glyphs[1];
-    for (size_t i = start; i < end; i++) {
-        glyphs[0] = layout.getGlyphId(i);
-        float x = hOffset + layout.getX(i);
-        float y = vOffset + layout.getY(i);
-        if (paint.nothingToDraw()) return;
-        const uint16_t* tempGlyphs = refBuffer<glyph_t>(glyphs, 1);
-        addOp(alloc().create_trivial<TextOnPathOp>(*(mState.currentSnapshot()->transform),
-                                                   getRecordedClip(), refPaint(&paint), tempGlyphs,
-                                                   1, refPath(&path), x, y));
-    }
-}
-
-void RecordingCanvas::drawBitmap(Bitmap& bitmap, const SkPaint* paint) {
-    addOp(alloc().create_trivial<BitmapOp>(Rect(bitmap.width(), bitmap.height()),
-                                           *(mState.currentSnapshot()->transform),
-                                           getRecordedClip(), refPaint(paint), refBitmap(bitmap)));
-}
-
-void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
-    auto&& stagingProps = renderNode->stagingProperties();
-    RenderNodeOp* op = alloc().create_trivial<RenderNodeOp>(
-            Rect(stagingProps.getWidth(), stagingProps.getHeight()),
-            *(mState.currentSnapshot()->transform), getRecordedClip(), renderNode);
-    int opIndex = addOp(op);
-    if (CC_LIKELY(opIndex >= 0)) {
-        int childIndex = mDisplayList->addChild(op);
-
-        // update the chunk's child indices
-        DisplayList::Chunk& chunk = mDisplayList->chunks.back();
-        chunk.endChildIndex = childIndex + 1;
-
-        if (renderNode->stagingProperties().isProjectionReceiver()) {
-            // use staging property, since recording on UI thread
-            mDisplayList->projectionReceiveIndex = opIndex;
-        }
-    }
-}
-
-void RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
-    // We ref the DeferredLayerUpdater due to its thread-safe ref-counting semantics.
-    mDisplayList->ref(layerHandle);
-
-    LOG_ALWAYS_FATAL_IF(layerHandle->getBackingLayerApi() != Layer::Api::OpenGL);
-    // Note that the backing layer has *not* yet been updated, so don't trust
-    // its width, height, transform, etc...!
-    addOp(alloc().create_trivial<TextureLayerOp>(
-            Rect(layerHandle->getWidth(), layerHandle->getHeight()),
-            *(mState.currentSnapshot()->transform), getRecordedClip(), layerHandle));
-}
-
-void RecordingCanvas::callDrawGLFunction(Functor* functor, GlFunctorLifecycleListener* listener) {
-    mDisplayList->functors.push_back({functor, listener});
-    mDisplayList->ref(listener);
-    addOp(alloc().create_trivial<FunctorOp>(*(mState.currentSnapshot()->transform),
-                                            getRecordedClip(), functor));
-}
-
-int RecordingCanvas::addOp(RecordedOp* op) {
-    // skip op with empty clip
-    if (op->localClip && op->localClip->rect.isEmpty()) {
-        // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
-        // and held by renderthread isn't affected by clip rejection.
-        // Could rewind alloc here if desired, but callers would have to not touch op afterwards.
-        return -1;
-    }
-
-    int insertIndex = mDisplayList->ops.size();
-    mDisplayList->ops.push_back(op);
-    if (mDeferredBarrierType != DeferredBarrierType::None) {
-        // op is first in new chunk
-        mDisplayList->chunks.emplace_back();
-        DisplayList::Chunk& newChunk = mDisplayList->chunks.back();
-        newChunk.beginOpIndex = insertIndex;
-        newChunk.endOpIndex = insertIndex + 1;
-        newChunk.reorderChildren = (mDeferredBarrierType == DeferredBarrierType::OutOfOrder);
-        newChunk.reorderClip = mDeferredBarrierClip;
-
-        int nextChildIndex = mDisplayList->children.size();
-        newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
-        mDeferredBarrierType = DeferredBarrierType::None;
-    } else {
-        // standard case - append to existing chunk
-        mDisplayList->chunks.back().endOpIndex = insertIndex + 1;
-    }
-    return insertIndex;
-}
-
-void RecordingCanvas::refBitmapsInShader(const SkShader* shader) {
-    if (!shader) return;
-
-    // If this paint has an SkShader that has an SkBitmap add
-    // it to the bitmap pile
-    SkBitmap bitmap;
-    SkShader::TileMode xy[2];
-    if (shader->isABitmap(&bitmap, nullptr, xy)) {
-        Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
-        refBitmap(*hwuiBitmap);
-        return;
-    }
-    SkShader::ComposeRec rec;
-    if (shader->asACompose(&rec)) {
-        refBitmapsInShader(rec.fShaderA);
-        refBitmapsInShader(rec.fShaderB);
-        return;
-    }
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
deleted file mode 100644
index e663402..0000000
--- a/libs/hwui/RecordingCanvas.h
+++ /dev/null
@@ -1,320 +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.
- */
-
-#ifndef ANDROID_HWUI_RECORDING_CANVAS_H
-#define ANDROID_HWUI_RECORDING_CANVAS_H
-
-#include "CanvasState.h"
-#include "DisplayList.h"
-#include "ResourceCache.h"
-#include "SkiaCanvasProxy.h"
-#include "Snapshot.h"
-#include "hwui/Bitmap.h"
-#include "hwui/Canvas.h"
-#include "utils/LinearAllocator.h"
-#include "utils/Macros.h"
-
-#include <SkDrawFilter.h>
-#include <SkPaint.h>
-#include <SkTLazy.h>
-
-#include <vector>
-
-namespace android {
-namespace uirenderer {
-
-struct ClipBase;
-class DeferredLayerUpdater;
-struct RecordedOp;
-
-class ANDROID_API RecordingCanvas : public Canvas, public CanvasStateClient {
-    enum class DeferredBarrierType {
-        None,
-        InOrder,
-        OutOfOrder,
-    };
-
-public:
-    RecordingCanvas(size_t width, size_t height);
-    virtual ~RecordingCanvas();
-
-    virtual void resetRecording(int width, int height, RenderNode* node = nullptr) override;
-    virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override;
-    // ----------------------------------------------------------------------------
-    // MISC HWUI OPERATIONS - TODO: CATEGORIZE
-    // ----------------------------------------------------------------------------
-    virtual void insertReorderBarrier(bool enableReorder) override;
-
-    virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
-    virtual void drawRenderNode(RenderNode* renderNode) override;
-    virtual void callDrawGLFunction(Functor* functor,
-                                    GlFunctorLifecycleListener* listener) override;
-
-    // ----------------------------------------------------------------------------
-    // CanvasStateClient interface
-    // ----------------------------------------------------------------------------
-    virtual void onViewportInitialized() override;
-    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
-    virtual GLuint getTargetFbo() const override { return -1; }
-
-    // ----------------------------------------------------------------------------
-    // HWUI Canvas draw operations
-    // ----------------------------------------------------------------------------
-
-    virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
-                               CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
-                               CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-                               CanvasPropertyPaint* paint) override;
-    virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-                            CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override;
-
-    // ----------------------------------------------------------------------------
-    // android/graphics/Canvas interface
-    // ----------------------------------------------------------------------------
-    virtual SkCanvas* asSkCanvas() override;
-
-    virtual void setBitmap(const SkBitmap& bitmap) override {
-        LOG_ALWAYS_FATAL("RecordingCanvas is not backed by a bitmap.");
-    }
-
-    virtual bool isOpaque() override { return false; }
-    virtual int width() override { return mState.getWidth(); }
-    virtual int height() override { return mState.getHeight(); }
-
-    // ----------------------------------------------------------------------------
-    // android/graphics/Canvas state operations
-    // ----------------------------------------------------------------------------
-    // Save (layer)
-    virtual int getSaveCount() const override { return mState.getSaveCount(); }
-    virtual int save(SaveFlags::Flags flags) override;
-    virtual void restore() override;
-    virtual void restoreToCount(int saveCount) override;
-
-    virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
-                          SaveFlags::Flags flags) override;
-    virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
-                               SaveFlags::Flags flags) override {
-        SkPaint paint;
-        paint.setAlpha(alpha);
-        return saveLayer(left, top, right, bottom, &paint, flags);
-    }
-
-    // Matrix
-    virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
-    virtual void setMatrix(const SkMatrix& matrix) override { mState.setMatrix(matrix); }
-
-    virtual void concat(const SkMatrix& matrix) override { mState.concatMatrix(matrix); }
-    virtual void rotate(float degrees) override;
-    virtual void scale(float sx, float sy) override;
-    virtual void skew(float sx, float sy) override;
-    virtual void translate(float dx, float dy) override;
-
-    // Clip
-    virtual bool getClipBounds(SkRect* outRect) const override;
-    virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
-    virtual bool quickRejectPath(const SkPath& path) const override;
-
-    virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
-    virtual bool clipPath(const SkPath* path, SkClipOp op) override;
-
-    // Misc
-    virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); }
-    virtual void setDrawFilter(SkDrawFilter* filter) override {
-        mDrawFilter.reset(SkSafeRef(filter));
-    }
-
-    // ----------------------------------------------------------------------------
-    // android/graphics/Canvas draw operations
-    // ----------------------------------------------------------------------------
-    virtual void drawColor(int color, SkBlendMode mode) override;
-    virtual void drawPaint(const SkPaint& paint) override;
-
-    // Geometry
-    virtual void drawPoint(float x, float y, const SkPaint& paint) override {
-        float points[2] = {x, y};
-        drawPoints(points, 2, paint);
-    }
-    virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) override;
-    virtual void drawLine(float startX, float startY, float stopX, float stopY,
-                          const SkPaint& paint) override {
-        float points[4] = {startX, startY, stopX, stopY};
-        drawLines(points, 4, paint);
-    }
-    virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) override;
-    virtual void drawRect(float left, float top, float right, float bottom,
-                          const SkPaint& paint) override;
-    virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
-    virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
-                               const SkPaint& paint) override;
-    virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
-    virtual void drawOval(float left, float top, float right, float bottom,
-                          const SkPaint& paint) override;
-    virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
-                         float sweepAngle, bool useCenter, const SkPaint& paint) override;
-    virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint)
-            override { /* RecordingCanvas does not support drawVertices(); ignore */
-    }
-
-    virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
-
-    // Bitmap-based
-    virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
-    virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
-    virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
-                            float srcBottom, float dstLeft, float dstTop, float dstRight,
-                            float dstBottom, const SkPaint* paint) override;
-    virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
-                                const float* vertices, const int* colors,
-                                const SkPaint* paint) override;
-    virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
-                               float dstTop, float dstRight, float dstBottom,
-                               const SkPaint* paint) override;
-    virtual double drawAnimatedImage(AnimatedImageDrawable*) override;
-
-    // Text
-    virtual bool drawTextAbsolutePos() const override { return false; }
-
-protected:
-    virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
-                            float y, float boundsLeft, float boundsTop, float boundsRight,
-                            float boundsBottom, float totalAdvance) override;
-    virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
-                                  const SkPaint& paint, const SkPath& path, size_t start,
-                                  size_t end) override;
-
-private:
-    const ClipBase* getRecordedClip() {
-        return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc());
-    }
-
-    void drawBitmap(Bitmap& bitmap, const SkPaint* paint);
-    void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
-
-    int addOp(RecordedOp* op);
-    // ----------------------------------------------------------------------------
-    // lazy object copy
-    // ----------------------------------------------------------------------------
-    LinearAllocator& alloc() { return mDisplayList->allocator; }
-
-    void refBitmapsInShader(const SkShader* shader);
-
-    template <class T>
-    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
-        if (!srcBuffer) return nullptr;
-
-        T* dstBuffer = (T*)mDisplayList->allocator.alloc<T>(count * sizeof(T));
-        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
-        return dstBuffer;
-    }
-
-    inline const SkPath* refPath(const SkPath* path) {
-        if (!path) return nullptr;
-
-        // The points/verbs within the path are refcounted so this copy operation
-        // is inexpensive and maintains the generationID of the original path.
-        const SkPath* cachedPath = new SkPath(*path);
-        mDisplayList->pathResources.push_back(cachedPath);
-        return cachedPath;
-    }
-
-    /**
-     * Returns a RenderThread-safe, const copy of the SkPaint parameter passed in
-     * (with deduping based on paint hash / equality check)
-     */
-    inline const SkPaint* refPaint(const SkPaint* paint) {
-        if (!paint) return nullptr;
-
-        // If there is a draw filter apply it here and store the modified paint
-        // so that we don't need to modify the paint every time we access it.
-        SkTLazy<SkPaint> filteredPaint;
-        if (mDrawFilter.get()) {
-            filteredPaint.set(*paint);
-            mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
-            paint = filteredPaint.get();
-        }
-
-        // compute the hash key for the paint and check the cache.
-        const uint32_t key = paint->getHash();
-        const SkPaint* cachedPaint = mPaintMap.valueFor(key);
-        // In the unlikely event that 2 unique paints have the same hash we do a
-        // object equality check to ensure we don't erroneously dedup them.
-        if (cachedPaint == nullptr || *cachedPaint != *paint) {
-            cachedPaint = new SkPaint(*paint);
-            mDisplayList->paints.emplace_back(cachedPaint);
-            // replaceValueFor() performs an add if the entry doesn't exist
-            mPaintMap.replaceValueFor(key, cachedPaint);
-            refBitmapsInShader(cachedPaint->getShader());
-        }
-
-        return cachedPaint;
-    }
-
-    inline const SkRegion* refRegion(const SkRegion* region) {
-        if (!region) {
-            return region;
-        }
-
-        const SkRegion* cachedRegion = mRegionMap.valueFor(region);
-        // TODO: Add generation ID to SkRegion
-        if (cachedRegion == nullptr) {
-            std::unique_ptr<const SkRegion> copy(new SkRegion(*region));
-            cachedRegion = copy.get();
-            mDisplayList->regions.push_back(std::move(copy));
-
-            // replaceValueFor() performs an add if the entry doesn't exist
-            mRegionMap.replaceValueFor(region, cachedRegion);
-        }
-
-        return cachedRegion;
-    }
-
-    inline Bitmap* refBitmap(Bitmap& bitmap) {
-        // Note that this assumes the bitmap is immutable. There are cases this won't handle
-        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
-        // contents, and drawing again. The only fix would be to always copy it the first time,
-        // which doesn't seem worth the extra cycles for this unlikely case.
-
-        // this is required because sk_sp's ctor adopts the pointer,
-        // but does not increment the refcount,
-        bitmap.ref();
-        mDisplayList->bitmapResources.emplace_back(&bitmap);
-        return &bitmap;
-    }
-
-    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
-        mDisplayList->patchResources.push_back(patch);
-        mResourceCache.incrementRefcount(patch);
-        return patch;
-    }
-
-    DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
-    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
-    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
-
-    CanvasState mState;
-    std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
-    ResourceCache& mResourceCache;
-    DeferredBarrierType mDeferredBarrierType = DeferredBarrierType::None;
-    const ClipBase* mDeferredBarrierClip = nullptr;
-    DisplayList* mDisplayList = nullptr;
-    sk_sp<SkDrawFilter> mDrawFilter;
-};  // class RecordingCanvas
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_RECORDING_CANVAS_H
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 62b80c43..e903900 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -381,78 +381,6 @@
     }
 }
 
-/**
- * Organizes the DisplayList hierarchy to prepare for background projection reordering.
- *
- * This should be called before a call to defer() or drawDisplayList()
- *
- * Each DisplayList that serves as a 3d root builds its list of composited children,
- * which are flagged to not draw in the standard draw loop.
- */
-void RenderNode::computeOrdering() {
-    ATRACE_CALL();
-    mProjectedNodes.clear();
-
-    // TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
-    // transform properties are applied correctly to top level children
-    if (mDisplayList == nullptr) return;
-    for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
-        RenderNodeOp* childOp = mDisplayList->getChildren()[i];
-        childOp->renderNode->computeOrderingImpl(childOp, &mProjectedNodes, &mat4::identity());
-    }
-}
-
-void RenderNode::computeOrderingImpl(
-        RenderNodeOp* opState, std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface,
-        const mat4* transformFromProjectionSurface) {
-    mProjectedNodes.clear();
-    if (mDisplayList == nullptr || mDisplayList->isEmpty()) return;
-
-    // TODO: should avoid this calculation in most cases
-    // TODO: just calculate single matrix, down to all leaf composited elements
-    Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface);
-    localTransformFromProjectionSurface.multiply(opState->localMatrix);
-
-    if (properties().getProjectBackwards()) {
-        // composited projectee, flag for out of order draw, save matrix, and store in proj surface
-        opState->skipInOrderDraw = true;
-        opState->transformFromCompositingAncestor = localTransformFromProjectionSurface;
-        compositedChildrenOfProjectionSurface->push_back(opState);
-    } else {
-        // standard in order draw
-        opState->skipInOrderDraw = false;
-    }
-
-    if (mDisplayList->getChildren().size() > 0) {
-        const bool isProjectionReceiver = mDisplayList->projectionReceiveIndex >= 0;
-        bool haveAppliedPropertiesToProjection = false;
-        for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
-            RenderNodeOp* childOp = mDisplayList->getChildren()[i];
-            RenderNode* child = childOp->renderNode;
-
-            std::vector<RenderNodeOp*>* projectionChildren = nullptr;
-            const mat4* projectionTransform = nullptr;
-            if (isProjectionReceiver && !child->properties().getProjectBackwards()) {
-                // if receiving projections, collect projecting descendant
-
-                // Note that if a direct descendant is projecting backwards, we pass its
-                // grandparent projection collection, since it shouldn't project onto its
-                // parent, where it will already be drawing.
-                projectionChildren = &mProjectedNodes;
-                projectionTransform = &mat4::identity();
-            } else {
-                if (!haveAppliedPropertiesToProjection) {
-                    applyViewPropertyTransforms(localTransformFromProjectionSurface);
-                    haveAppliedPropertiesToProjection = true;
-                }
-                projectionChildren = compositedChildrenOfProjectionSurface;
-                projectionTransform = &localTransformFromProjectionSurface;
-            }
-            child->computeOrderingImpl(childOp, projectionChildren, projectionTransform);
-        }
-    }
-}
-
 const SkPath* RenderNode::getClippedOutline(const SkRect& clipRect) const {
     const SkPath* outlinePath = properties().getOutline().getPath();
     const uint32_t outlineID = outlinePath->getGenerationID();
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 1e0d4e2..45a53f9 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -48,8 +48,6 @@
 namespace uirenderer {
 
 class CanvasState;
-class DisplayListOp;
-class FrameBuilder;
 class OffscreenBuffer;
 class Rect;
 class SkiaShader;
@@ -76,7 +74,6 @@
  */
 class RenderNode : public VirtualLightRefBase {
     friend class TestUtils;  // allow TestUtils to access syncDisplayList / syncProperties
-    friend class FrameBuilder;
 
 public:
     enum DirtyPropertyMask {
@@ -104,8 +101,6 @@
 
     ANDROID_API void setStagingDisplayList(DisplayList* newData);
 
-    void computeOrdering();
-
     ANDROID_API void output();
     ANDROID_API int getDebugSize();
 
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index da52a95..e84b9ac 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -718,6 +718,8 @@
 }  // namespace VectorDrawable
 
 typedef VectorDrawable::Path::Data PathData;
+typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
+
 }  // namespace uirenderer
 }  // namespace android
 
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index b453227..30f6f12 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -19,7 +19,6 @@
 #include "MinikinUtils.h"
 #include "Paint.h"
 #include "Properties.h"
-#include "RecordingCanvas.h"
 #include "RenderNode.h"
 #include "Typeface.h"
 #include "pipeline/skia/SkiaRecordingCanvas.h"
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index f341cf9..341b0c5 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -44,8 +44,16 @@
 class CanvasPropertyPaint;
 class CanvasPropertyPrimitive;
 class DeferredLayerUpdater;
-class DisplayList;
 class RenderNode;
+
+namespace skiapipeline {
+class SkiaDisplayList;
+}
+
+/**
+ * Data structure that holds the list of commands used in display list stream
+ */
+using DisplayList = skiapipeline::SkiaDisplayList;
 }
 
 namespace SaveFlags {
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
index af57d7d..d9e65c9 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "GlFunctorLifecycleListener.h"
+
 #include <SkCanvas.h>
 #include <SkDrawable.h>
 
@@ -25,8 +27,6 @@
 namespace android {
 namespace uirenderer {
 
-class GlFunctorLifecycleListener;
-
 namespace skiapipeline {
 
 /**
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 6c04d78..1b816fe 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -25,6 +25,19 @@
 namespace uirenderer {
 namespace skiapipeline {
 
+RenderNodeDrawable::RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer,
+                                       bool inReorderingSection)
+        : mRenderNode(node)
+        , mRecordedTransform(canvas->getTotalMatrix())
+        , mComposeLayer(composeLayer)
+        , mInReorderingSection(inReorderingSection) {}
+
+RenderNodeDrawable::~RenderNodeDrawable() {
+    // Just here to move the destructor into the cpp file where we can access RenderNode.
+
+    // TODO: Detangle the header nightmare.
+}
+
 void RenderNodeDrawable::drawBackwardsProjectedNodes(SkCanvas* canvas,
                                                      const SkiaDisplayList& displayList,
                                                      int nestLevel) {
@@ -115,7 +128,6 @@
         return;
     }
 
-    SkASSERT(renderNode->getDisplayList()->isSkiaDL());
     SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
 
     SkAutoCanvasRestore acr(canvas, true);
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index ef21cd8..6594bd22 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -47,11 +47,9 @@
      *      layer into the canvas.
      */
     explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true,
-                                bool inReorderingSection = false)
-            : mRenderNode(node)
-            , mRecordedTransform(canvas->getTotalMatrix())
-            , mComposeLayer(composeLayer)
-            , mInReorderingSection(inReorderingSection) {}
+                                bool inReorderingSection = false);
+
+    ~RenderNodeDrawable();
 
     /**
      * Draws into the canvas this render node and its children. If the node is marked as a
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 818ec11..58b9242 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -16,10 +16,11 @@
 
 #pragma once
 
-#include "DisplayList.h"
 #include "hwui/AnimatedImageDrawable.h"
 #include "GLFunctorDrawable.h"
 #include "RenderNodeDrawable.h"
+#include "TreeInfo.h"
+#include "utils/LinearAllocator.h"
 
 #include <SkLiteDL.h>
 #include <SkLiteRecorder.h>
@@ -28,8 +29,17 @@
 namespace android {
 namespace uirenderer {
 
+namespace renderthread {
+class CanvasContext;
+}
+
 class Outline;
 
+namespace VectorDrawable {
+class Tree;
+};
+typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
+
 namespace skiapipeline {
 
 /**
@@ -38,10 +48,14 @@
  * runtime.  The downside of this inheritance is that we pay for the overhead
  * of the parent class construction/destruction without any real benefit.
  */
-class SkiaDisplayList : public DisplayList {
+class SkiaDisplayList {
 public:
-    SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
-    virtual ~SkiaDisplayList() {
+    // index of DisplayListOp restore, after which projected descendants should be drawn
+    int projectionReceiveIndex = -1;
+
+    size_t getUsedSize() { return allocator.usedSize(); }
+
+    ~SkiaDisplayList() {
         /* Given that we are using a LinearStdAllocator to store some of the
          * SkDrawable contents we must ensure that any other object that is
          * holding a reference to those drawables is destroyed prior to their
@@ -68,29 +82,27 @@
         return allocator.create<T>(std::forward<Params>(params)...);
     }
 
-    bool isSkiaDL() const override { return true; }
-
     /**
      * Returns true if the DisplayList does not have any recorded content
      */
-    bool isEmpty() const override { return mDisplayList.empty(); }
+    bool isEmpty() const { return mDisplayList.empty(); }
 
     /**
      * Returns true if this list directly contains a GLFunctor drawing command.
      */
-    bool hasFunctor() const override { return !mChildFunctors.empty(); }
+    bool hasFunctor() const { return !mChildFunctors.empty(); }
 
     /**
      * Returns true if this list directly contains a VectorDrawable drawing command.
      */
-    bool hasVectorDrawables() const override { return !mVectorDrawables.empty(); }
+    bool hasVectorDrawables() const { return !mVectorDrawables.empty(); }
 
     /**
      * Attempts to reset and reuse this DisplayList.
      *
      * @return true if the displayList will be reused and therefore should not be deleted
      */
-    bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) override;
+    bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context);
 
     /**
      * ONLY to be called by RenderNode::syncDisplayList so that we can notify any
@@ -99,7 +111,7 @@
      * NOTE: This function can be folded into RenderNode when we no longer need
      *       to subclass from DisplayList
      */
-    void syncContents() override;
+    void syncContents();
 
     /**
      * ONLY to be called by RenderNode::prepareTree in order to prepare this
@@ -116,12 +128,12 @@
 
     bool prepareListAndChildren(
             TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
-            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) override;
+            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn);
 
     /**
      *  Calls the provided function once for each child of this DisplayList
      */
-    void updateChildren(std::function<void(RenderNode*)> updateFn) override;
+    void updateChildren(std::function<void(RenderNode*)> updateFn);
 
     /**
      *  Returns true if there is a child render node that is a projection receiver.
@@ -134,7 +146,9 @@
 
     void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }
 
-    void output(std::ostream& output, uint32_t level) override;
+    void output(std::ostream& output, uint32_t level);
+
+    LinearAllocator allocator;
 
     /**
      * We use std::deque here because (1) we need to iterate through these
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index cfcfd2b..15277f1 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -25,6 +25,7 @@
 #include "renderstate/RenderState.h"
 #include "renderthread/EglManager.h"
 #include "renderthread/Frame.h"
+#include "utils/GLUtils.h"
 #include "utils/TraceUtils.h"
 
 #include <GrBackendSurface.h>
@@ -58,10 +59,10 @@
 }
 
 bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-                              const FrameBuilder::LightGeometry& lightGeometry,
+                              const LightGeometry& lightGeometry,
                               LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
                               bool opaque, bool wideColorGamut,
-                              const BakedOpRenderer::LightInfo& lightInfo,
+                              const LightInfo& lightInfo,
                               const std::vector<sp<RenderNode>>& renderNodes,
                               FrameInfoVisualizer* profiler) {
     mEglManager.damageFrame(frame, dirty);
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index ef5d934..04b68f5 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -33,9 +33,9 @@
     renderthread::MakeCurrentResult makeCurrent() override;
     renderthread::Frame getFrame() override;
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-              const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+              const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
               const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
-              const BakedOpRenderer::LightInfo& lightInfo,
+              const LightInfo& lightInfo,
               const std::vector<sp<RenderNode> >& renderNodes,
               FrameInfoVisualizer* profiler) override;
     bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index d66cba1..988981d 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -81,9 +81,9 @@
     mVectorDrawables.clear();
 }
 
-void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
+void SkiaPipeline::renderLayers(const LightGeometry& lightGeometry,
                                 LayerUpdateQueue* layerUpdateQueue, bool opaque,
-                                bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo) {
+                                bool wideColorGamut, const LightInfo& lightInfo) {
     updateLighting(lightGeometry, lightInfo);
     ATRACE_NAME("draw layers");
     renderVectorDrawableCache();
@@ -103,7 +103,6 @@
         // as not to lose info on what portion is damaged
         if (CC_LIKELY(layerNode->getLayerSurface() != nullptr)) {
             SkASSERT(layerNode->getLayerSurface());
-            SkASSERT(layerNode->getDisplayList()->isSkiaDL());
             SkiaDisplayList* displayList = (SkiaDisplayList*)layerNode->getDisplayList();
             if (!displayList || displayList->isEmpty()) {
                 SkDEBUGF(("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName()));
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 38ad9c0..8c9c803 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include <SkSurface.h>
-#include "FrameBuilder.h"
+#include "Lighting.h"
 #include "hwui/AnimatedImageDrawable.h"
 #include "renderthread/CanvasContext.h"
 #include "renderthread/IRenderPipeline.h"
@@ -42,9 +42,9 @@
     void unpinImages() override;
     void onPrepareTree() override;
 
-    void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
+    void renderLayers(const LightGeometry& lightGeometry,
                       LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
-                      const BakedOpRenderer::LightInfo& lightInfo) override;
+                      const LightInfo& lightInfo) override;
 
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
                              bool wideColorGamut, ErrorHandler* errorHandler) override;
@@ -97,8 +97,8 @@
         return mLightCenter;
     }
 
-    static void updateLighting(const FrameBuilder::LightGeometry& lightGeometry,
-                               const BakedOpRenderer::LightInfo& lightInfo) {
+    static void updateLighting(const LightGeometry& lightGeometry,
+                               const LightInfo& lightInfo) {
         mLightRadius = lightGeometry.radius;
         mAmbientShadowAlpha = lightInfo.ambientShadowAlpha;
         mSpotShadowAlpha = lightInfo.spotShadowAlpha;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 5825060..b2519fe 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -62,10 +62,10 @@
 }
 
 bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-                              const FrameBuilder::LightGeometry& lightGeometry,
+                              const LightGeometry& lightGeometry,
                               LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
                               bool opaque, bool wideColorGamut,
-                              const BakedOpRenderer::LightInfo& lightInfo,
+                              const LightInfo& lightInfo,
                               const std::vector<sp<RenderNode>>& renderNodes,
                               FrameInfoVisualizer* profiler) {
     sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface();
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 03b4c79..7806b42 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -31,9 +31,9 @@
     renderthread::MakeCurrentResult makeCurrent() override;
     renderthread::Frame getFrame() override;
     bool draw(const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-              const FrameBuilder::LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+              const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
               const Rect& contentDrawBounds, bool opaque, bool wideColorGamut,
-              const BakedOpRenderer::LightInfo& lightInfo,
+              const LightInfo& lightInfo,
               const std::vector<sp<RenderNode> >& renderNodes,
               FrameInfoVisualizer* profiler) override;
     bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index f173136..a60e2b5 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -18,6 +18,7 @@
 #include "DeferredLayerUpdater.h"
 #include "GlLayer.h"
 #include "VkLayer.h"
+#include "Snapshot.h"
 
 #include "renderthread/CanvasContext.h"
 #include "renderthread/EglManager.h"
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index aaef85a..358b842 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -16,10 +16,8 @@
 
 #pragma once
 
-#include "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
 #include "DamageAccumulator.h"
-#include "FrameBuilder.h"
+#include "Lighting.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
 #include "FrameMetricsReporter.h"
@@ -231,8 +229,8 @@
 
     bool mOpaque;
     bool mWideColorGamut = false;
-    BakedOpRenderer::LightInfo mLightInfo;
-    FrameBuilder::LightGeometry mLightGeometry = {{0, 0, 0}, 0};
+    LightInfo mLightInfo;
+    LightGeometry mLightGeometry = {{0, 0, 0}, 0};
 
     bool mHaveNewSurface = false;
     DamageAccumulator mDamageAccumulator;
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index d8c43e0..0037a0f 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -32,7 +32,6 @@
 namespace uirenderer {
 
 class DeferredLayerUpdater;
-class DisplayList;
 class RenderNode;
 
 namespace renderthread {
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index b1de497..b94a758 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -17,7 +17,10 @@
 #pragma once
 
 #include "FrameInfoVisualizer.h"
+#include "LayerUpdateQueue.h"
 #include "SwapBehavior.h"
+#include "hwui/Bitmap.h"
+#include "thread/TaskManager.h"
 
 #include <SkRect.h>
 #include <utils/RefBase.h>
@@ -50,9 +53,9 @@
     virtual MakeCurrentResult makeCurrent() = 0;
     virtual Frame getFrame() = 0;
     virtual bool draw(const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
-                      const FrameBuilder::LightGeometry& lightGeometry,
+                      const LightGeometry& lightGeometry,
                       LayerUpdateQueue* layerUpdateQueue, const Rect& contentDrawBounds,
-                      bool opaque, bool wideColorGamut, const BakedOpRenderer::LightInfo& lightInfo,
+                      bool opaque, bool wideColorGamut, const LightInfo& lightInfo,
                       const std::vector<sp<RenderNode>>& renderNodes,
                       FrameInfoVisualizer* profiler) = 0;
     virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
@@ -64,9 +67,9 @@
     virtual bool isSurfaceReady() = 0;
     virtual bool isContextReady() = 0;
     virtual void onDestroyHardwareResources() = 0;
-    virtual void renderLayers(const FrameBuilder::LightGeometry& lightGeometry,
+    virtual void renderLayers(const LightGeometry& lightGeometry,
                               LayerUpdateQueue* layerUpdateQueue, bool opaque, bool wideColorGamut,
-                              const BakedOpRenderer::LightInfo& lightInfo) = 0;
+                              const LightInfo& lightInfo) = 0;
     virtual TaskManager* getTaskManager() = 0;
     virtual bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
                                      bool wideColorGamut, ErrorHandler* errorHandler) = 0;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 0caf59b..4d1e1e8 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -66,10 +66,7 @@
 
 bool RenderProxy::loadSystemProperties() {
     return mRenderThread.queue().runSync([this]() -> bool {
-        bool needsRedraw = false;
-        if (Caches::hasInstance()) {
-            needsRedraw = Properties::load();
-        }
+        bool needsRedraw = Properties::load();
         if (mContext->profiler().consumeProperties()) {
             needsRedraw = true;
         }
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index ca5a88b..13fb528 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -29,7 +29,6 @@
 #include <renderthread/RenderThread.h>
 
 #include <RecordedOp.h>
-#include <RecordingCanvas.h>
 
 #include <memory>
 
@@ -335,16 +334,10 @@
         }
         auto displayList = node->getDisplayList();
         if (displayList) {
-            if (displayList->isSkiaDL()) {
-                for (auto&& childDr : static_cast<skiapipeline::SkiaDisplayList*>(
-                                              const_cast<DisplayList*>(displayList))
-                                              ->mChildNodes) {
-                    syncHierarchyPropertiesAndDisplayListImpl(childDr.getRenderNode());
-                }
-            } else {
-                for (auto&& childOp : displayList->getChildren()) {
-                    syncHierarchyPropertiesAndDisplayListImpl(childOp->renderNode);
-                }
+            for (auto&& childDr : static_cast<skiapipeline::SkiaDisplayList*>(
+                                          const_cast<DisplayList*>(displayList))
+                                          ->mChildNodes) {
+                syncHierarchyPropertiesAndDisplayListImpl(childDr.getRenderNode());
             }
         }
     }
diff --git a/libs/hwui/tests/common/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h
index 792312a..6f76a50 100644
--- a/libs/hwui/tests/common/scenes/TestSceneBase.h
+++ b/libs/hwui/tests/common/scenes/TestSceneBase.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include "RecordingCanvas.h"
+#include "hwui/Canvas.h"
 #include "RenderNode.h"
 #include "tests/common/TestContext.h"
 #include "tests/common/TestScene.h"
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 0aaf773..9388c20 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -16,8 +16,10 @@
 
 #include <benchmark/benchmark.h>
 
+#include "CanvasState.h"
 #include "DisplayList.h"
-#include "RecordingCanvas.h"
+#include "hwui/Canvas.h"
+#include "pipeline/skia/SkiaDisplayList.h"
 #include "tests/common/TestUtils.h"
 
 using namespace android;
@@ -25,7 +27,7 @@
 
 void BM_DisplayList_alloc(benchmark::State& benchState) {
     while (benchState.KeepRunning()) {
-        auto displayList = new DisplayList();
+        auto displayList = new skiapipeline::SkiaDisplayList();
         benchmark::DoNotOptimize(displayList);
         delete displayList;
     }
@@ -34,7 +36,7 @@
 
 void BM_DisplayList_alloc_theoretical(benchmark::State& benchState) {
     while (benchState.KeepRunning()) {
-        auto displayList = new char[sizeof(DisplayList)];
+        auto displayList = new char[sizeof(skiapipeline::SkiaDisplayList)];
         benchmark::DoNotOptimize(displayList);
         delete[] displayList;
     }
diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp
deleted file mode 100644
index b621766..0000000
--- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2016 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 "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "BakedOpState.h"
-#include "FrameBuilder.h"
-#include "LayerUpdateQueue.h"
-#include "RecordedOp.h"
-#include "RecordingCanvas.h"
-#include "Vector.h"
-#include "tests/common/TestContext.h"
-#include "tests/common/TestScene.h"
-#include "tests/common/TestUtils.h"
-
-#include <vector>
-
-using namespace android;
-using namespace android::uirenderer;
-using namespace android::uirenderer::renderthread;
-using namespace android::uirenderer::test;
-
-const FrameBuilder::LightGeometry sLightGeometry = {{100, 100, 100}, 50};
-const BakedOpRenderer::LightInfo sLightInfo = {128, 128};
-
-static sp<RenderNode> createTestNode() {
-    auto node = TestUtils::createNode<RecordingCanvas>(
-            0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) {
-                sk_sp<Bitmap> bitmap(TestUtils::createBitmap(10, 10));
-                SkPaint paint;
-
-                // Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
-                // Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
-                canvas.save(SaveFlags::MatrixClip);
-                for (int i = 0; i < 30; i++) {
-                    canvas.translate(0, 10);
-                    canvas.drawRect(0, 0, 10, 10, paint);
-                    canvas.drawBitmap(*bitmap, 5, 0, nullptr);
-                }
-                canvas.restore();
-            });
-    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
-    return node;
-}
-
-void BM_FrameBuilder_defer(benchmark::State& state) {
-    TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        auto node = createTestNode();
-        while (state.KeepRunning()) {
-            FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry,
-                                      Caches::getInstance());
-            frameBuilder.deferRenderNode(*node);
-            benchmark::DoNotOptimize(&frameBuilder);
-        }
-    });
-}
-BENCHMARK(BM_FrameBuilder_defer);
-
-void BM_FrameBuilder_deferAndRender(benchmark::State& state) {
-    TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        auto node = createTestNode();
-
-        RenderState& renderState = thread.renderState();
-        Caches& caches = Caches::getInstance();
-
-        while (state.KeepRunning()) {
-            FrameBuilder frameBuilder(SkRect::MakeWH(100, 200), 100, 200, sLightGeometry, caches);
-            frameBuilder.deferRenderNode(*node);
-
-            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
-            frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-            benchmark::DoNotOptimize(&renderer);
-        }
-    });
-}
-BENCHMARK(BM_FrameBuilder_deferAndRender);
-
-static sp<RenderNode> getSyncedSceneNode(const char* sceneName) {
-    gDisplay = getBuiltInDisplay();  // switch to real display if present
-
-    TestContext testContext;
-    TestScene::Options opts;
-    std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
-
-    sp<RenderNode> rootNode = TestUtils::createNode<RecordingCanvas>(
-            0, 0, gDisplay.w, gDisplay.h,
-            [&scene](RenderProperties& props, RecordingCanvas& canvas) {
-                scene->createContent(gDisplay.w, gDisplay.h, canvas);
-            });
-
-    TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
-    return rootNode;
-}
-
-static auto SCENES = {
-        "listview",
-};
-
-void BM_FrameBuilder_defer_scene(benchmark::State& state) {
-    TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range(0));
-        state.SetLabel(sceneName);
-        auto node = getSyncedSceneNode(sceneName);
-        while (state.KeepRunning()) {
-            FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w,
-                                      gDisplay.h, sLightGeometry, Caches::getInstance());
-            frameBuilder.deferRenderNode(*node);
-            benchmark::DoNotOptimize(&frameBuilder);
-        }
-    });
-}
-BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1);
-
-void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) {
-    TestUtils::runOnRenderThread([&state](RenderThread& thread) {
-        const char* sceneName = *(SCENES.begin() + state.range(0));
-        state.SetLabel(sceneName);
-        auto node = getSyncedSceneNode(sceneName);
-
-        RenderState& renderState = thread.renderState();
-        Caches& caches = Caches::getInstance();
-
-        while (state.KeepRunning()) {
-            FrameBuilder frameBuilder(SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w,
-                                      gDisplay.h, sLightGeometry, Caches::getInstance());
-            frameBuilder.deferRenderNode(*node);
-
-            BakedOpRenderer renderer(caches, renderState, true, false, sLightInfo);
-            frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-            benchmark::DoNotOptimize(&renderer);
-        }
-    });
-}
-BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1);
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index 2e4de0b..634ceff 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -16,7 +16,6 @@
 
 #include "tests/common/TestUtils.h"
 
-#include <RecordingCanvas.h>
 #include <SkBlurDrawLooper.h>
 #include <SkCanvasStateUtils.h>
 #include <SkPicture.h>
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index 42a92fc..26b6000 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -167,10 +167,10 @@
     ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
 
     bool opaque = true;
-    FrameBuilder::LightGeometry lightGeometry;
+    LightGeometry lightGeometry;
     lightGeometry.radius = 1.0f;
     lightGeometry.center = {0.0f, 0.0f, 0.0f};
-    BakedOpRenderer::LightInfo lightInfo;
+    LightInfo lightInfo;
     auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread);
     pipeline->renderLayers(lightGeometry, &layerUpdateQueue, opaque, false, lightInfo);
     ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorRED);
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index 700d3b3..8ac6e1f 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -17,7 +17,6 @@
 
 #include "AnimationContext.h"
 #include "IContextFactory.h"
-#include "RecordingCanvas.h"
 #include "RenderNode.h"
 #include "SkTypes.h"
 #include "gui/BufferQueue.h"
@@ -25,6 +24,7 @@
 #include "gui/IGraphicBufferConsumer.h"
 #include "gui/IGraphicBufferProducer.h"
 #include "gui/Surface.h"
+#include "hwui/Canvas.h"
 #include "renderthread/RenderProxy.h"
 
 #include <cutils/memory.h>
@@ -81,7 +81,7 @@
         android::uirenderer::Vector3 lightVector{lightX, -200.0f, 800.0f};
         mProxy->setup(800.0f, 255 * 0.075f, 255 * 0.15f);
         mProxy->setLightCenter(lightVector);
-        mCanvas.reset(new android::uirenderer::RecordingCanvas(mSize.width(), mSize.height()));
+        mCanvas.reset(Canvas::create_recording_canvas(mSize.width(), mSize.height(), mRootNode.get()));
     }
 
     SkCanvas* prepareToDraw() {
@@ -155,7 +155,7 @@
 private:
     std::unique_ptr<android::uirenderer::RenderNode> mRootNode;
     std::unique_ptr<android::uirenderer::renderthread::RenderProxy> mProxy;
-    std::unique_ptr<android::uirenderer::RecordingCanvas> mCanvas;
+    std::unique_ptr<android::Canvas> mCanvas;
     android::sp<android::IGraphicBufferProducer> mProducer;
     android::sp<android::IGraphicBufferConsumer> mConsumer;
     android::sp<android::CpuConsumer> mCpuConsumer;
