diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 4fe866f..06eb829 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -18,6 +18,12 @@
     hwui/MinikinUtils.cpp \
     hwui/PaintImpl.cpp \
     hwui/Typeface.cpp \
+    pipeline/skia/GLFunctorDrawable.cpp \
+    pipeline/skia/LayerDrawable.cpp \
+    pipeline/skia/RenderNodeDrawable.cpp \
+    pipeline/skia/ReorderBarrierDrawables.cpp \
+    pipeline/skia/SkiaDisplayList.cpp \
+    pipeline/skia/SkiaRecordingCanvas.cpp \
     renderstate/Blend.cpp \
     renderstate/MeshState.cpp \
     renderstate/OffscreenBufferPool.cpp \
@@ -94,7 +100,6 @@
     ShadowTessellator.cpp \
     SkiaCanvas.cpp \
     SkiaCanvasProxy.cpp \
-    SkiaDisplayList.cpp \
     SkiaShader.cpp \
     Snapshot.cpp \
     SpotShadow.cpp \
@@ -169,6 +174,7 @@
 hwui_c_includes += \
     external/skia/include/private \
     external/skia/src/core \
+    external/skia/src/effects \
     external/harfbuzz_ng/src \
     external/freetype/include
 
@@ -284,6 +290,7 @@
     tests/unit/MeshStateTests.cpp \
     tests/unit/OffscreenBufferPoolTests.cpp \
     tests/unit/OpDumperTests.cpp \
+    tests/unit/RenderNodeDrawableTests.cpp \
     tests/unit/RecordingCanvasTests.cpp \
     tests/unit/RenderNodeTests.cpp \
     tests/unit/RenderPropertiesTests.cpp \
diff --git a/libs/hwui/NinePatchUtils.h b/libs/hwui/NinePatchUtils.h
index 7a271b7..e989a46 100644
--- a/libs/hwui/NinePatchUtils.h
+++ b/libs/hwui/NinePatchUtils.h
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#pragma once
+
 namespace android {
 namespace NinePatchUtils {
 
@@ -34,5 +36,61 @@
     }
 }
 
+static inline int NumDistinctRects(const SkCanvas::Lattice& lattice) {
+    int xRects;
+    if (lattice.fXCount > 0) {
+        xRects = (0 == lattice.fXDivs[0]) ? lattice.fXCount : lattice.fXCount + 1;
+    } else {
+        xRects = 1;
+    }
+
+    int yRects;
+    if (lattice.fYCount > 0) {
+        yRects = (0 == lattice.fYDivs[0]) ? lattice.fYCount : lattice.fYCount + 1;
+    } else {
+        yRects = 1;
+    }
+    return xRects * yRects;
+}
+
+static inline void SetLatticeFlags(SkCanvas::Lattice* lattice, SkCanvas::Lattice::Flags* flags,
+        int numFlags, const Res_png_9patch& chunk) {
+    lattice->fFlags = flags;
+    sk_bzero(flags, numFlags * sizeof(SkCanvas::Lattice::Flags));
+
+    bool needPadRow = lattice->fYCount > 0 && 0 == lattice->fYDivs[0];
+    bool needPadCol = lattice->fXCount > 0 && 0 == lattice->fXDivs[0];
+
+    int yCount = lattice->fYCount;
+    if (needPadRow) {
+        // Skip flags for the degenerate first row of rects.
+        flags += lattice->fXCount + 1;
+        yCount--;
+    }
+
+    int i = 0;
+    bool setFlags = false;
+    for (int y = 0; y < yCount + 1; y++) {
+        for (int x = 0; x < lattice->fXCount + 1; x++) {
+            if (0 == x && needPadCol) {
+                // First rect of each column is degenerate, skip the flag.
+                flags++;
+                continue;
+            }
+
+            if (0 == chunk.getColors()[i++]) {
+                *flags = SkCanvas::Lattice::kTransparent_Flags;
+                setFlags = true;
+            }
+
+            flags++;
+        }
+    }
+
+    if (!setFlags) {
+        lattice->fFlags = nullptr;
+    }
+}
+
 }; // namespace NinePatchUtils
 }; // namespace android
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index a05c744..3819c5e 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -32,7 +32,7 @@
 #include "DisplayList.h"
 #include "Matrix.h"
 #include "RenderProperties.h"
-#include "SkiaDisplayList.h"
+#include "pipeline/skia/SkiaDisplayList.h"
 
 #include <vector>
 
@@ -50,7 +50,6 @@
 class FrameBuilder;
 class OffscreenBuffer;
 class Rect;
-class SkiaDisplayList;
 class SkiaShader;
 struct RenderNodeOp;
 
@@ -61,6 +60,10 @@
 class RenderNode;
 }
 
+namespace skiapipeline {
+    class SkiaDisplayList;
+}
+
 /**
  * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
  *
@@ -294,14 +297,14 @@
      * Detach and transfer ownership of an already allocated displayList for use
      * in recording updated content for this renderNode
      */
-    std::unique_ptr<SkiaDisplayList> detachAvailableList() {
+    std::unique_ptr<skiapipeline::SkiaDisplayList> detachAvailableList() {
         return std::move(mAvailableDisplayList);
     }
 
     /**
      * Attach unused displayList to this node for potential future reuse.
      */
-    void attachAvailableList(SkiaDisplayList* skiaDisplayList) {
+    void attachAvailableList(skiapipeline::SkiaDisplayList* skiaDisplayList) {
         mAvailableDisplayList.reset(skiaDisplayList);
     }
 
@@ -337,7 +340,7 @@
      *  2) It is replaced with the displayList from the next completed frame
      *  3) It is detached and used to to record a new displayList for a later frame
      */
-    std::unique_ptr<SkiaDisplayList> mAvailableDisplayList;
+    std::unique_ptr<skiapipeline::SkiaDisplayList> mAvailableDisplayList;
 
     /**
      * An offscreen rendering target used to contain the contents this RenderNode
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c48b4dc..b6ac48f 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -21,6 +21,7 @@
 #include "VectorDrawable.h"
 #include "hwui/Bitmap.h"
 #include "hwui/MinikinUtils.h"
+#include "pipeline/skia/AnimatedDrawables.h"
 
 #include <SkDrawable.h>
 #include <SkDevice.h>
@@ -57,6 +58,8 @@
     mCanvas.reset(new SkCanvas(bitmap));
 }
 
+SkiaCanvas::~SkiaCanvas() {}
+
 void SkiaCanvas::reset(SkCanvas* skiaCanvas) {
     mCanvas.reset(SkRef(skiaCanvas));
     mSaveStack.reset(nullptr);
@@ -671,62 +674,6 @@
                          indexCount, tmpPaint);
 }
 
-static inline int num_distinct_rects(const SkCanvas::Lattice& lattice) {
-    int xRects;
-    if (lattice.fXCount > 0) {
-        xRects = (0 == lattice.fXDivs[0]) ? lattice.fXCount : lattice.fXCount + 1;
-    } else {
-        xRects = 1;
-    }
-
-    int yRects;
-    if (lattice.fYCount > 0) {
-        yRects = (0 == lattice.fYDivs[0]) ? lattice.fYCount : lattice.fYCount + 1;
-    } else {
-        yRects = 1;
-    }
-    return xRects * yRects;
-}
-
-static inline void set_lattice_flags(SkCanvas::Lattice* lattice, SkCanvas::Lattice::Flags* flags,
-                                     int numFlags, const Res_png_9patch& chunk) {
-    lattice->fFlags = flags;
-    sk_bzero(flags, numFlags * sizeof(SkCanvas::Lattice::Flags));
-
-    bool needPadRow = lattice->fYCount > 0 && 0 == lattice->fYDivs[0];
-    bool needPadCol = lattice->fXCount > 0 && 0 == lattice->fXDivs[0];
-
-    int yCount = lattice->fYCount;
-    if (needPadRow) {
-        // Skip flags for the degenerate first row of rects.
-        flags += lattice->fXCount + 1;
-        yCount--;
-    }
-
-    int i = 0;
-    bool setFlags = false;
-    for (int y = 0; y < yCount + 1; y++) {
-        for (int x = 0; x < lattice->fXCount + 1; x++) {
-            if (0 == x && needPadCol) {
-                // First rect of each column is degenerate, skip the flag.
-                flags++;
-                continue;
-            }
-
-            if (0 == chunk.getColors()[i++]) {
-                *flags = SkCanvas::Lattice::kTransparent_Flags;
-                setFlags = true;
-            }
-
-            flags++;
-        }
-    }
-
-    if (!setFlags) {
-        lattice->fFlags = nullptr;
-    }
-}
-
 void SkiaCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
         float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
 
@@ -738,7 +685,7 @@
 
     lattice.fFlags = nullptr;
     int numFlags = 0;
-    if (chunk.numColors > 0 && chunk.numColors == num_distinct_rects(lattice)) {
+    if (chunk.numColors > 0 && chunk.numColors == NinePatchUtils::NumDistinctRects(lattice)) {
         // We can expect the framework to give us a color for every distinct rect.
         // Skia requires a flag for every rect.
         numFlags = (lattice.fXCount + 1) * (lattice.fYCount + 1);
@@ -746,7 +693,7 @@
 
     SkAutoSTMalloc<25, SkCanvas::Lattice::Flags> flags(numFlags);
     if (numFlags > 0) {
-        set_lattice_flags(&lattice, flags.get(), numFlags, chunk);
+        NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk);
     }
 
     lattice.fBounds = nullptr;
@@ -820,69 +767,18 @@
 // Canvas draw operations: Animations
 // ----------------------------------------------------------------------------
 
-class AnimatedRoundRect : public SkDrawable {
- public:
-    AnimatedRoundRect(uirenderer::CanvasPropertyPrimitive* left,
-            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
-            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
-            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* p) :
-            mLeft(left), mTop(top), mRight(right), mBottom(bottom), mRx(rx), mRy(ry), mPaint(p) {}
-
- protected:
-     virtual SkRect onGetBounds() override {
-         return SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
-     }
-     virtual void onDraw(SkCanvas* canvas) override {
-         SkRect rect = SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
-         canvas->drawRoundRect(rect, mRx->value, mRy->value, mPaint->value);
-     }
-
- private:
-    sp<uirenderer::CanvasPropertyPrimitive> mLeft;
-    sp<uirenderer::CanvasPropertyPrimitive> mTop;
-    sp<uirenderer::CanvasPropertyPrimitive> mRight;
-    sp<uirenderer::CanvasPropertyPrimitive> mBottom;
-    sp<uirenderer::CanvasPropertyPrimitive> mRx;
-    sp<uirenderer::CanvasPropertyPrimitive> mRy;
-    sp<uirenderer::CanvasPropertyPaint> mPaint;
-};
-
-class AnimatedCircle : public SkDrawable {
- public:
-    AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
-            uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) :
-            mX(x), mY(y), mRadius(radius), mPaint(paint) {}
-
- protected:
-     virtual SkRect onGetBounds() override {
-         const float x = mX->value;
-         const float y = mY->value;
-         const float radius = mRadius->value;
-         return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
-     }
-     virtual void onDraw(SkCanvas* canvas) override {
-         canvas->drawCircle(mX->value, mY->value, mRadius->value, mPaint->value);
-     }
-
- private:
-    sp<uirenderer::CanvasPropertyPrimitive> mX;
-    sp<uirenderer::CanvasPropertyPrimitive> mY;
-    sp<uirenderer::CanvasPropertyPrimitive> mRadius;
-    sp<uirenderer::CanvasPropertyPaint> mPaint;
-};
-
 void SkiaCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
         uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
         uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
         uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
-    sk_sp<AnimatedRoundRect> drawable(
-            new AnimatedRoundRect(left, top, right, bottom, rx, ry, paint));
+    sk_sp<uirenderer::skiapipeline::AnimatedRoundRect> drawable(
+            new uirenderer::skiapipeline::AnimatedRoundRect(left, top, right, bottom, rx, ry, paint));
     mCanvas->drawDrawable(drawable.get());
 }
 
 void SkiaCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
         uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint) {
-    sk_sp<AnimatedCircle> drawable(new AnimatedCircle(x, y, radius, paint));
+    sk_sp<uirenderer::skiapipeline::AnimatedCircle> drawable(new uirenderer::skiapipeline::AnimatedCircle(x, y, radius, paint));
     mCanvas->drawDrawable(drawable.get());
 }
 
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index d1edff9..a0cdfcb 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -40,6 +40,8 @@
      */
     explicit SkiaCanvas(SkCanvas* canvas);
 
+    virtual ~SkiaCanvas();
+
     virtual SkCanvas* asSkCanvas() override {
         return mCanvas.get();
     }
diff --git a/libs/hwui/SkiaDrawables.h b/libs/hwui/SkiaDrawables.h
deleted file mode 100644
index a1ceeaa..0000000
--- a/libs/hwui/SkiaDrawables.h
+++ /dev/null
@@ -1,102 +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 "Layer.h"
-#include "RenderNode.h"
-
-#include <SkCanvas.h>
-#include <SkDrawable.h>
-#include <SkMatrix.h>
-
-#include <utils/RefBase.h>
-#include <utils/FatVector.h>
-#include <utils/Functor.h>
-
-namespace android {
-
-class Functor;
-
-namespace uirenderer {
-
-
-class RenderProperties;
-class OffscreenBuffer;
-class GlFunctorLifecycleListener;
-class SkiaDisplayList;
-
-/**
- * This drawable wraps a RenderNode and enables it to be recorded into a list
- * of Skia drawing commands.
- */
-class RenderNodeDrawable : public SkDrawable {
-public:
-    explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas)
-            : mRenderNode(node)
-            , mRecordedTransform(canvas->getTotalMatrix()) {}
-
-    /**
-     * The renderNode (and its properties) that is to be drawn
-     */
-    RenderNode* getRenderNode() const { return mRenderNode.get(); }
-
-    /**
-     * Returns the transform on the canvas at time of recording and is used for
-     * computing total transform without rerunning DL contents.
-     */
-    const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
-
-protected:
-    virtual SkRect onGetBounds() override {
-        // We don't want to enable a record time quick reject because the properties
-        // of the RenderNode may be updated on subsequent frames.
-        return SkRect::MakeLargest();
-    }
-    virtual void onDraw(SkCanvas* canvas) override { /* TODO */ }
-
-private:
-    sp<RenderNode> mRenderNode;
-    const SkMatrix mRecordedTransform;
-};
-
-/**
- * This drawable wraps a OpenGL functor enabling it to be recorded into a list
- * of Skia drawing commands.
- */
-class GLFunctorDrawable : public SkDrawable {
-public:
-    GLFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
-            : mFunctor(functor)
-            , mListener(listener) {
-        canvas->getClipBounds(&mBounds);
-    }
-    virtual ~GLFunctorDrawable() {}
-
-    void syncFunctor() const { (*mFunctor)(DrawGlInfo::kModeSync, nullptr); }
-
- protected:
-    virtual SkRect onGetBounds() override { return mBounds; }
-    virtual void onDraw(SkCanvas* canvas) override { /* TODO */ }
-
- private:
-     Functor* mFunctor;
-     sp<GlFunctorLifecycleListener> mListener;
-     SkRect mBounds;
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
new file mode 100644
index 0000000..44c494f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -0,0 +1,90 @@
+/*
+ * 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 "CanvasProperty.h"
+#include <utils/RefBase.h>
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class AnimatedRoundRect : public SkDrawable {
+public:
+    AnimatedRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* p)
+            : mLeft(left)
+            , mTop(top)
+            , mRight(right)
+            , mBottom(bottom)
+            , mRx(rx)
+            , mRy(ry)
+            , mPaint(p) {}
+
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+    }
+    virtual void onDraw(SkCanvas* canvas) override {
+        SkRect rect = SkRect::MakeLTRB(mLeft->value, mTop->value, mRight->value, mBottom->value);
+        canvas->drawRoundRect(rect, mRx->value, mRy->value, mPaint->value);
+    }
+
+private:
+    sp<uirenderer::CanvasPropertyPrimitive> mLeft;
+    sp<uirenderer::CanvasPropertyPrimitive> mTop;
+    sp<uirenderer::CanvasPropertyPrimitive> mRight;
+    sp<uirenderer::CanvasPropertyPrimitive> mBottom;
+    sp<uirenderer::CanvasPropertyPrimitive> mRx;
+    sp<uirenderer::CanvasPropertyPrimitive> mRy;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+class AnimatedCircle : public SkDrawable {
+public:
+    AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
+            uirenderer::CanvasPropertyPrimitive* radius, uirenderer::CanvasPropertyPaint* paint)
+            : mX(x)
+            , mY(y)
+            , mRadius(radius)
+            , mPaint(paint) {}
+
+protected:
+    virtual SkRect onGetBounds() override {
+        const float x = mX->value;
+        const float y = mY->value;
+        const float radius = mRadius->value;
+        return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
+    }
+    virtual void onDraw(SkCanvas* canvas) override {
+        canvas->drawCircle(mX->value, mY->value, mRadius->value, mPaint->value);
+    }
+
+private:
+    sp<uirenderer::CanvasPropertyPrimitive> mX;
+    sp<uirenderer::CanvasPropertyPrimitive> mY;
+    sp<uirenderer::CanvasPropertyPrimitive> mRadius;
+    sp<uirenderer::CanvasPropertyPaint> mPaint;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
new file mode 100644
index 0000000..fb2134c
--- /dev/null
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "GLFunctorDrawable.h"
+#include "GlFunctorLifecycleListener.h"
+#include "RenderNode.h"
+#include "SkClipStack.h"
+#include <private/hwui/DrawGlInfo.h>
+#include <SkPath.h>
+#include <GrContext.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+GLFunctorDrawable::~GLFunctorDrawable() {
+    if(mListener.get() != nullptr) {
+        mListener->onGlFunctorReleased(mFunctor);
+    }
+}
+
+void GLFunctorDrawable::syncFunctor() const {
+    (*mFunctor)(DrawGlInfo::kModeSync, nullptr);
+}
+
+static void setScissor(int viewportHeight, const SkIRect& clip) {
+    SkASSERT(!clip.isEmpty());
+    // transform to Y-flipped GL space, and prevent negatives
+    GLint y = viewportHeight - clip.fBottom;
+    GLint height = (viewportHeight - clip.fTop) - y;
+    glScissor(clip.fLeft, y, clip.width(), height);
+}
+
+void GLFunctorDrawable::onDraw(SkCanvas* canvas) {
+    if (canvas->getGrContext() == nullptr) {
+        SkDEBUGF(("Attempting to draw GLFunctor into an unsupported surface"));
+        return;
+    }
+
+    canvas->flush();
+
+    SkImageInfo canvasInfo = canvas->imageInfo();
+    SkMatrix44 mat4(canvas->getTotalMatrix());
+
+    SkIRect ibounds;
+    canvas->getClipDeviceBounds(&ibounds);
+
+    DrawGlInfo info;
+    info.clipLeft = ibounds.fLeft;
+    info.clipTop = ibounds.fTop;
+    info.clipRight = ibounds.fRight;
+    info.clipBottom = ibounds.fBottom;
+    //   info.isLayer = hasLayer();
+    info.isLayer = false;
+    info.width = canvasInfo.width();
+    info.height = canvasInfo.height();
+    mat4.asColMajorf(&info.transform[0]);
+
+    //apply a simple clip with a scissor or a complex clip with a stencil
+    SkRegion clipRegion;
+    SkPath path;
+    canvas->getClipStack()->asPath(&path);
+    clipRegion.setPath(path, SkRegion(ibounds));
+    if (CC_UNLIKELY(clipRegion.isComplex())) {
+        //It is only a temporary solution to use a scissor to draw the stencil.
+        //There is a bug 31489986 to implement efficiently non-rectangular clips.
+        glDisable(GL_SCISSOR_TEST);
+        glDisable(GL_STENCIL_TEST);
+        glStencilMask(0xff);
+        glClearStencil(0);
+        glClear(GL_STENCIL_BUFFER_BIT);
+        glEnable(GL_SCISSOR_TEST);
+        SkRegion::Cliperator it(clipRegion, ibounds);
+        while (!it.done()) {
+            setScissor(info.height, it.rect());
+            glClearStencil(0x1);
+            glClear(GL_STENCIL_BUFFER_BIT);
+            it.next();
+        }
+        glDisable(GL_SCISSOR_TEST);
+        glStencilFunc(GL_EQUAL, 0x1, 0xff);
+        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+        glEnable(GL_STENCIL_TEST);
+    } else if (clipRegion.isEmpty()) {
+        glDisable(GL_STENCIL_TEST);
+        glDisable(GL_SCISSOR_TEST);
+    } else {
+        glDisable(GL_STENCIL_TEST);
+        glEnable(GL_SCISSOR_TEST);
+        setScissor(info.height, clipRegion.getBounds());
+    }
+
+    (*mFunctor)(DrawGlInfo::kModeDraw, &info);
+
+    canvas->getGrContext()->resetContext();
+ }
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
new file mode 100644
index 0000000..bf39dad
--- /dev/null
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -0,0 +1,59 @@
+/*
+ * 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 <SkCanvas.h>
+#include <SkDrawable.h>
+
+#include <utils/RefBase.h>
+#include <utils/Functor.h>
+
+namespace android {
+namespace uirenderer {
+
+class GlFunctorLifecycleListener;
+
+namespace skiapipeline {
+
+/**
+ * This drawable wraps a OpenGL functor enabling it to be recorded into a list
+ * of Skia drawing commands.
+ */
+class GLFunctorDrawable : public SkDrawable {
+public:
+    GLFunctorDrawable(Functor* functor, GlFunctorLifecycleListener* listener, SkCanvas* canvas)
+            : mFunctor(functor)
+            , mListener(listener) {
+        canvas->getClipBounds(&mBounds);
+    }
+    virtual ~GLFunctorDrawable();
+
+    void syncFunctor() const;
+
+ protected:
+    virtual SkRect onGetBounds() override { return mBounds; }
+    virtual void onDraw(SkCanvas* canvas) override;
+
+ private:
+     Functor* mFunctor;
+     sp<GlFunctorLifecycleListener> mListener;
+     SkRect mBounds;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
new file mode 100644
index 0000000..f8a181f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "LayerDrawable.h"
+#include "gl/GrGLTypes.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+void LayerDrawable::onDraw(SkCanvas* canvas) {
+    // transform the matrix based on the layer
+    int saveCount = -1;
+    if (!mLayer->getTransform().isIdentity()) {
+        saveCount = canvas->save();
+        SkMatrix transform;
+        mLayer->getTransform().copyTo(transform);
+        canvas->concat(transform);
+    }
+    GrGLTextureInfo externalTexture;
+    externalTexture.fTarget = mLayer->getRenderTarget();
+    externalTexture.fID = mLayer->getTextureId();
+    GrContext* context = canvas->getGrContext();
+    GrBackendTextureDesc textureDescription;
+    textureDescription.fWidth = mLayer->getWidth();
+    textureDescription.fHeight = mLayer->getHeight();
+    textureDescription.fConfig = kRGBA_8888_GrPixelConfig;
+    textureDescription.fOrigin = kTopLeft_GrSurfaceOrigin;
+    textureDescription.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture);
+    sk_sp<SkImage> layerImage(SkImage::NewFromTexture(context, textureDescription));
+    if (layerImage) {
+        SkPaint paint;
+        paint.setAlpha(mLayer->getAlpha());
+        paint.setBlendMode(mLayer->getMode());
+        paint.setColorFilter(mLayer->getColorFilter());
+        canvas->drawImage(layerImage, 0, 0, &paint);
+    }
+    // restore the original matrix
+    if (saveCount >= 0) {
+        canvas->restoreToCount(saveCount);
+    }
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
new file mode 100644
index 0000000..91e2744
--- /dev/null
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -0,0 +1,48 @@
+/*
+ * 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 "Layer.h"
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/*
+ * Draws a layer backed by an OpenGL texture into a SkCanvas.
+ */
+class LayerDrawable : public SkDrawable {
+ public:
+    explicit LayerDrawable(Layer* layer)
+            : mLayer(layer) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         return SkRect::MakeWH(mLayer->getWidth(), mLayer->getHeight());
+     }
+     virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    sp<Layer> mLayer;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
new file mode 100644
index 0000000..cefa893
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -0,0 +1,252 @@
+/*
+ * 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 "RenderNodeDrawable.h"
+#include "RenderNode.h"
+#include "SkiaDisplayList.h"
+#include "SkiaFrameRenderer.h"
+#include "utils/TraceUtils.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+static void clipOutline(const Outline& outline, SkCanvas* canvas, const SkRect* pendingClip) {
+    SkASSERT(outline.willClip());
+    Rect possibleRect;
+    float radius;
+    LOG_ALWAYS_FATAL_IF(!outline.getAsRoundRect(&possibleRect, &radius),
+            "clipping outlines should be at most roundedRects");
+    SkRect rect = possibleRect.toSkRect();
+    if (radius != 0.0f) {
+        if (pendingClip && !pendingClip->contains(rect)) {
+            canvas->clipRect(*pendingClip);
+        }
+        canvas->clipRRect(SkRRect::MakeRectXY(rect, radius, radius), SkRegion::kIntersect_Op, true);
+    } else {
+        if (pendingClip) {
+            (void)rect.intersect(*pendingClip);
+        }
+        canvas->clipRect(rect);
+    }
+}
+
+const RenderProperties& RenderNodeDrawable::getNodeProperties() const {
+    return mRenderNode->properties();
+}
+
+void RenderNodeDrawable::onDraw(SkCanvas* canvas) {
+    //negative and positive Z order are drawn out of order
+    if (MathUtils::isZero(mRenderNode->properties().getZ())) {
+        this->forceDraw(canvas);
+    }
+}
+
+void RenderNodeDrawable::forceDraw(SkCanvas* canvas) {
+    RenderNode* renderNode = mRenderNode.get();
+    if (SkiaFrameRenderer::skpCaptureEnabled()) {
+        SkRect dimensions = SkRect::MakeWH(renderNode->getWidth(), renderNode->getHeight());
+        canvas->drawAnnotation(dimensions, renderNode->getName(), nullptr);
+    }
+
+    // We only respect the nothingToDraw check when we are composing a layer. This
+    // ensures that we paint the layer even if it is not currently visible in the
+    // event that the properties change and it becomes visible.
+    if (!renderNode->isRenderable() || (renderNode->nothingToDraw() && mComposeLayer)) {
+        return;
+    }
+
+    SkASSERT(renderNode->getDisplayList()->isSkiaDL());
+    SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    const RenderProperties& properties = this->getNodeProperties();
+    if (displayList->mIsProjectionReceiver) {
+        // this node is a projection receiver. We will gather the projected nodes as we draw our
+        // children, and then draw them on top of this node's content.
+        std::vector<ProjectedChild> newList;
+        for (auto& child : displayList->mChildNodes) {
+            // our direct children are not supposed to project into us (nodes project to, at the
+            // nearest, their grandparents). So we "delay" the list's activation one level by
+            // passing it into mNextProjectedChildrenTarget rather than mProjectedChildrenTarget.
+            child.mProjectedChildrenTarget = mNextProjectedChildrenTarget;
+            child.mNextProjectedChildrenTarget = &newList;
+        }
+        // draw ourselves and our children. As a side effect, this will add projected nodes to
+        // newList.
+        this->drawContent(canvas);
+        bool willClip = properties.getOutline().willClip();
+        if (willClip) {
+            canvas->save();
+            clipOutline(properties.getOutline(), canvas, nullptr);
+        }
+        // draw the collected projected nodes
+        for (auto& projectedChild : newList) {
+            canvas->setMatrix(projectedChild.matrix);
+            projectedChild.node->drawContent(canvas);
+        }
+        if (willClip) {
+            canvas->restore();
+        }
+    } else {
+        if (properties.getProjectBackwards() && mProjectedChildrenTarget) {
+            // We are supposed to project this node, so add it to the list and do not actually draw
+            // yet. It will be drawn by its projection receiver.
+            mProjectedChildrenTarget->push_back({ this, canvas->getTotalMatrix() });
+            return;
+        }
+        for (auto& child : displayList->mChildNodes) {
+            // storing these values in the nodes themselves is a bit ugly; they should "really" be
+            // function parameters, but we have to go through the preexisting draw() method and
+            // therefore cannot add additional parameters to it
+            child.mProjectedChildrenTarget = mNextProjectedChildrenTarget;
+            child.mNextProjectedChildrenTarget = mNextProjectedChildrenTarget;
+        }
+        this->drawContent(canvas);
+    }
+    mProjectedChildrenTarget = nullptr;
+    mNextProjectedChildrenTarget = nullptr;
+}
+
+static bool layerNeedsPaint(const LayerProperties& properties,
+                            float alphaMultiplier, SkPaint* paint) {
+    if (alphaMultiplier < 1.0f
+            || properties.alpha() < 255
+            || properties.xferMode() != SkBlendMode::kSrcOver
+            || properties.colorFilter() != nullptr) {
+        paint->setAlpha(properties.alpha() * alphaMultiplier);
+        paint->setBlendMode(properties.xferMode());
+        paint->setColorFilter(properties.colorFilter());
+        return true;
+    }
+    return false;
+}
+
+void RenderNodeDrawable::drawContent(SkCanvas* canvas) const {
+    RenderNode* renderNode = mRenderNode.get();
+    float alphaMultiplier = 1.0f;
+    const RenderProperties& properties = renderNode->properties();
+
+    // If we are drawing the contents of layer, we don't want to apply any of
+    // the RenderNode's properties during this pass. Those will all be applied
+    // when the layer is composited.
+    if (mComposeLayer) {
+        setViewProperties(properties, canvas, &alphaMultiplier);
+    }
+
+    //TODO should we let the bound of the drawable do this for us?
+    const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
+    bool quickRejected = properties.getClipToBounds() && canvas->quickReject(bounds);
+    if (!quickRejected) {
+        SkiaDisplayList* displayList = (SkiaDisplayList*)renderNode->getDisplayList();
+        const LayerProperties& layerProperties = properties.layerProperties();
+        // composing a hardware layer
+        if (renderNode->getLayerSurface() && mComposeLayer) {
+            SkASSERT(properties.effectiveLayerType() == LayerType::RenderLayer);
+            SkPaint* paint = nullptr;
+            SkPaint tmpPaint;
+            if (layerNeedsPaint(layerProperties, alphaMultiplier, &tmpPaint)) {
+                paint = &tmpPaint;
+            }
+            renderNode->getLayerSurface()->draw(canvas, 0, 0, paint);
+        // composing a software layer with alpha
+        } else if (properties.effectiveLayerType() == LayerType::Software) {
+            SkPaint paint;
+            bool needsLayer = layerNeedsPaint(layerProperties, alphaMultiplier, &paint);
+            if (needsLayer) {
+                canvas->saveLayer(bounds, &paint);
+            }
+            canvas->drawDrawable(displayList->mDrawable.get());
+            if (needsLayer) {
+                canvas->restore();
+            }
+        } else {
+            canvas->drawDrawable(displayList->mDrawable.get());
+        }
+    }
+}
+
+void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
+        float* alphaMultiplier) {
+    if (properties.getLeft() != 0 || properties.getTop() != 0) {
+        canvas->translate(properties.getLeft(), properties.getTop());
+    }
+    if (properties.getStaticMatrix()) {
+        canvas->concat(*properties.getStaticMatrix());
+    } else if (properties.getAnimationMatrix()) {
+        canvas->concat(*properties.getAnimationMatrix());
+    }
+    if (properties.hasTransformMatrix()) {
+        if (properties.isTransformTranslateOnly()) {
+            canvas->translate(properties.getTranslationX(), properties.getTranslationY());
+        } else {
+            canvas->concat(*properties.getTransformMatrix());
+        }
+    }
+    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())) {
+            *alphaMultiplier = properties.getAlpha();
+        } else {
+            // savelayer needed to create an offscreen buffer
+            Rect layerBounds(0, 0, properties.getWidth(), properties.getHeight());
+            if (clipFlags) {
+                properties.getClippingRectForFlags(clipFlags, &layerBounds);
+                clipFlags = 0; // all clipping done by savelayer
+            }
+            SkRect bounds = SkRect::MakeLTRB(layerBounds.left, layerBounds.top,
+                    layerBounds.right, layerBounds.bottom);
+            canvas->saveLayerAlpha(&bounds, (int) (properties.getAlpha() * 255));
+        }
+
+        if (CC_UNLIKELY(ATRACE_ENABLED() && properties.promotedToLayer())) {
+            // pretend alpha always causes savelayer to warn about
+            // performance problem affecting old versions
+            ATRACE_FORMAT("alpha caused saveLayer %dx%d", properties.getWidth(),
+                    properties.getHeight());
+        }
+    }
+
+    const SkRect* pendingClip = nullptr;
+    SkRect clipRect;
+
+    if (clipFlags) {
+        Rect tmpRect;
+        properties.getClippingRectForFlags(clipFlags, &tmpRect);
+        clipRect = tmpRect.toSkRect();
+        pendingClip = &clipRect;
+    }
+
+    if (properties.getRevealClip().willClip()) {
+        canvas->clipPath(*properties.getRevealClip().getPath(), SkRegion::kIntersect_Op, true);
+    } else if (properties.getOutline().willClip()) {
+        clipOutline(properties.getOutline(), canvas, pendingClip);
+        pendingClip = nullptr;
+    }
+
+    if (pendingClip) {
+        canvas->clipRect(*pendingClip);
+    }
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
new file mode 100644
index 0000000..0762f37
--- /dev/null
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -0,0 +1,148 @@
+/*
+ * 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 <SkCanvas.h>
+#include <SkDrawable.h>
+#include <SkMatrix.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace uirenderer {
+
+class RenderNode;
+class RenderProperties;
+
+namespace skiapipeline {
+
+/**
+ * This drawable wraps a RenderNode and enables it to be recorded into a list
+ * of Skia drawing commands.
+ */
+class RenderNodeDrawable : public SkDrawable {
+public:
+    /**
+     * This struct contains a pointer to a node that is to be
+     * projected into the drawing order of its closest ancestor
+     * (excluding its parent) that is marked as a projection
+     * receiver. The matrix is used to ensure that the node is
+     * drawn with same matrix as it would have prior to projection.
+     */
+    struct ProjectedChild {
+        const RenderNodeDrawable* node;
+        const SkMatrix matrix;
+    };
+
+    /**
+     * Creates a new RenderNodeDrawable backed by a render node.
+     *
+     * @param node that has to be drawn
+     * @param canvas is a recording canvas used to extract its matrix
+     * @param composeLayer if the node's layer type is RenderLayer this flag determines whether
+     *      we should draw into the contents of the layer or compose the existing contents of the
+     *      layer into the canvas.
+     */
+    explicit RenderNodeDrawable(RenderNode* node, SkCanvas* canvas, bool composeLayer = true)
+            : mRenderNode(node)
+            , mRecordedTransform(canvas->getTotalMatrix())
+            , mComposeLayer(composeLayer) {}
+
+    /**
+     * Draws into the canvas this render node and its children. If the node is marked as a
+     * projection receiver then all projected children (excluding direct children) will be drawn
+     * last. Any projected node not matching those requirements will not be drawn by this function.
+     */
+    void forceDraw(SkCanvas* canvas);
+
+    /**
+     * Returns readonly render properties for this render node.
+     */
+    const RenderProperties& getNodeProperties() const;
+
+    /**
+     * The renderNode (and its properties) that is to be drawn
+     */
+    RenderNode* getRenderNode() const { return mRenderNode.get(); }
+
+    /**
+     * Returns the transform on the canvas at time of recording and is used for
+     * computing total transform without rerunning DL contents.
+     */
+    const SkMatrix& getRecordedMatrix() const { return mRecordedTransform; }
+
+protected:
+    /*
+     * Return the (conservative) bounds of what the drawable will draw.
+     */
+    virtual SkRect onGetBounds() override {
+        // We don't want to enable a record time quick reject because the properties
+        // of the RenderNode may be updated on subsequent frames.
+        return SkRect::MakeLargest();
+    }
+    /**
+     * This function draws into a canvas as forceDraw, but does nothing if the render node has a
+     * non-zero elevation.
+     */
+    virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    /*
+     * Render node that is wrapped by this class.
+     */
+    sp<RenderNode> mRenderNode;
+
+    /**
+     * Applies the rendering properties of a view onto a SkCanvas.
+     */
+    static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas,
+            float* alphaMultiplier);
+
+    /**
+     * Stores transform on the canvas at time of recording and is used for
+     * computing total transform without rerunning DL contents.
+     */
+    const SkMatrix mRecordedTransform;
+
+    /**
+     * If mRenderNode's layer type is RenderLayer this flag determines whether we
+     * should draw into the contents of the layer or compose the existing contents
+     * of the layer into the canvas.
+     */
+    const bool mComposeLayer;
+
+    /**
+     * List to which we will add any projected children we encounter while walking our descendents.
+     * This pointer is valid only while the node (including its children) is actively being drawn.
+     */
+    std::vector<ProjectedChild>* mProjectedChildrenTarget = nullptr;
+
+    /**
+     * The value to which we should set our children's mProjectedChildrenTarget. We use two pointers
+     * (mProjectedChildrenTarget and mNextProjectedChildrenTarget) because we need to skip over our
+     * parent when looking for a projection receiver.
+     */
+    std::vector<ProjectedChild>* mNextProjectedChildrenTarget = nullptr;
+
+    /*
+     *  Draw the content into a canvas, depending on the render node layer type and mComposeLayer.
+     */
+    void drawContent(SkCanvas* canvas) const;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
new file mode 100644
index 0000000..8d77938
--- /dev/null
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -0,0 +1,704 @@
+/*
+ * 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 "ReorderBarrierDrawables.h"
+#include "RenderNode.h"
+#include "SkiaDisplayList.h"
+#include "SkiaFrameRenderer.h"
+
+#include <SkBlurMask.h>
+#include <SkBlurMaskFilter.h>
+#include <SkGaussianEdgeShader.h>
+#include <SkPathOps.h>
+#include <SkRRectsGaussianEdgeShader.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+StartReorderBarrierDrawable::StartReorderBarrierDrawable(SkiaDisplayList* data)
+        : mEndChildIndex(0)
+        , mBeginChildIndex(data->mChildNodes.size())
+        , mDisplayList(data) {
+}
+
+void StartReorderBarrierDrawable::onDraw(SkCanvas* canvas) {
+    if (mChildren.empty()) {
+        //mChildren is allocated and initialized only the first time onDraw is called and cached for
+        //subsequent calls
+        mChildren.reserve(mEndChildIndex - mBeginChildIndex + 1);
+        for (unsigned int i = mBeginChildIndex; i <= mEndChildIndex; i++) {
+            mChildren.push_back(const_cast<RenderNodeDrawable*>(&mDisplayList->mChildNodes[i]));
+        }
+    }
+    std::stable_sort(mChildren.begin(), mChildren.end(),
+        [](RenderNodeDrawable* a, RenderNodeDrawable* b) {
+            const float aZValue = a->getNodeProperties().getZ();
+            const float bZValue = b->getNodeProperties().getZ();
+            return aZValue < bZValue;
+        });
+
+    SkASSERT(!mChildren.empty());
+
+    size_t drawIndex = 0;
+    const size_t endIndex = mChildren.size();
+    while (drawIndex < endIndex) {
+        RenderNodeDrawable* childNode = mChildren[drawIndex];
+        SkASSERT(childNode);
+        const float casterZ = childNode->getNodeProperties().getZ();
+        if (casterZ >= -NON_ZERO_EPSILON) { //draw only children with negative Z
+            return;
+        }
+        childNode->forceDraw(canvas);
+        drawIndex++;
+    }
+}
+
+EndReorderBarrierDrawable::EndReorderBarrierDrawable(StartReorderBarrierDrawable* startBarrier)
+        : mStartBarrier(startBarrier) {
+    mStartBarrier->mEndChildIndex = mStartBarrier->mDisplayList->mChildNodes.size() - 1;
+}
+
+#define SHADOW_DELTA 0.1f
+
+void EndReorderBarrierDrawable::onDraw(SkCanvas* canvas) {
+    auto& zChildren = mStartBarrier->mChildren;
+    SkASSERT(!zChildren.empty());
+
+    /**
+     * 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.
+     */
+    size_t drawIndex = 0;
+
+    const size_t endIndex = zChildren.size();
+    while (drawIndex < endIndex     //draw only children with positive Z
+            && zChildren[drawIndex]->getNodeProperties().getZ() <= NON_ZERO_EPSILON) drawIndex++;
+    size_t shadowIndex = drawIndex;
+
+    float lastCasterZ = 0.0f;
+    while (shadowIndex < endIndex || drawIndex < endIndex) {
+        if (shadowIndex < endIndex) {
+            const float casterZ = zChildren[shadowIndex]->getNodeProperties().getZ();
+
+            // 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 < SHADOW_DELTA) {
+                this->drawShadow(canvas, zChildren[shadowIndex]);
+                lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
+                shadowIndex++;
+                continue;
+            }
+        }
+
+        RenderNodeDrawable* childNode = zChildren[drawIndex];
+        SkASSERT(childNode);
+        childNode->forceDraw(canvas);
+
+        drawIndex++;
+    }
+}
+
+/**
+ * @param canvas             the destination for the shadow draws
+ * @param shape              the shape casting the shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param draw               the function used to draw 'shape'
+ */
+template <typename Shape, typename F>
+static void DrawAmbientShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
+        float ambientAlpha, F&& draw) {
+    if (ambientAlpha <= 0) {
+        return;
+    }
+
+    const float kHeightFactor = 1.f/128.f;
+    const float kGeomFactor = 64;
+
+    float umbraAlpha = 1 / (1 + SkMaxScalar(casterZValue*kHeightFactor, 0));
+    float radius = casterZValue*kHeightFactor*kGeomFactor;
+
+    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
+            SkBlurMask::ConvertRadiusToSigma(radius), SkBlurMaskFilter::kNone_BlurFlag);
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setMaskFilter(std::move(mf));
+    paint.setARGB(ambientAlpha*umbraAlpha, 0, 0, 0);
+
+    draw(shape, paint);
+}
+
+/**
+ * @param canvas             the destination for the shadow draws
+ * @param shape              the shape casting the shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param lightPos           the position of the light casting the shadow
+ * @param lightWidth
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param draw               the function used to draw 'shape'
+ */
+template <typename Shape, typename F>
+static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
+        float spotAlpha, F&& draw) {
+    if (spotAlpha <= 0) {
+        return;
+    }
+
+    const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+    float zRatio = casterZValue / (lightPos.z - casterZValue);
+    // clamp
+    if (zRatio < 0.0f) {
+        zRatio = 0.0f;
+    } else if (zRatio > 0.95f) {
+        zRatio = 0.95f;
+    }
+
+    float blurRadius = SkiaFrameRenderer::getLightRadius()*zRatio;
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
+            SkBlurMask::ConvertRadiusToSigma(blurRadius), SkBlurMaskFilter::kNone_BlurFlag);
+
+    SkPaint paint;
+    paint.setAntiAlias(true);
+    paint.setMaskFilter(std::move(mf));
+    paint.setARGB(spotAlpha, 0, 0, 0);
+
+    // approximate projection by translating and scaling projected offset of bounds center
+    // TODO: compute the actual 2D projection
+    SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+    canvas->scale(scale, scale);
+    SkPoint center = SkPoint::Make(shape.getBounds().centerX(), shape.getBounds().centerY());
+    SkMatrix ctmInverse;
+    if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+        ALOGW("Matrix is degenerate. Will not render shadow!");
+        return;
+    }
+    SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+    ctmInverse.mapPoints(&lightPos2D, 1);
+    canvas->translate(zRatio*(center.fX - lightPos2D.fX), zRatio*(center.fY - lightPos2D.fY));
+
+    draw(shape, paint);
+}
+
+#define MAX_BLUR_RADIUS 16383.75f
+#define MAX_PAD         64
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
+ * @param casterZValue       the Z value of the caster RRect
+ * @param scaleFactor        the scale needed to map from src-space to device-space
+ * @param canvas             the destination for the shadow draws
+ */
+static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius,
+        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue,
+        SkScalar scaleFactor, SkCanvas* canvas) {
+    SkASSERT(cornerRadius >= 0.0f);
+
+    // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space
+    const SkScalar minRadius = 0.5f / scaleFactor;
+
+    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
+            SkScalarHalf(casterRect.height()));
+    const bool isRect = casterCornerRadius <= minRadius;
+
+    sk_sp<SkShader> edgeShader(SkGaussianEdgeShader::Make());
+
+    if (ambientAlpha > 0.0f) {
+        static const float kHeightFactor = 1.0f / 128.0f;
+        static const float kGeomFactor = 64.0f;
+
+        SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
+        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
+        if (srcSpaceAmbientRadius*scaleFactor > MAX_BLUR_RADIUS) {
+            srcSpaceAmbientRadius = MAX_BLUR_RADIUS/scaleFactor;
+        }
+        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
+        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
+
+        // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius
+        // to get our stroke shape.
+        SkScalar ambientPathOutset = std::max(ambientOffset - srcSpaceAmbientRadius * 0.5f,
+                minRadius);
+
+        SkRRect ambientRRect;
+        const SkRect temp = casterRect.makeOutset(ambientPathOutset, ambientPathOutset);
+        if (isOval) {
+            ambientRRect = SkRRect::MakeOval(temp);
+        } else if (isRect) {
+            ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset);
+        } else {
+            ambientRRect = SkRRect::MakeRectXY(temp, casterCornerRadius + ambientPathOutset,
+                    casterCornerRadius + ambientPathOutset);
+        }
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+        paint.setStyle(SkPaint::kStroke_Style);
+        // we outset the stroke a little to cover up AA on the interior edge
+        float pad = 0.5f;
+        paint.setStrokeWidth(srcSpaceAmbientRadius + 2.0f * pad);
+        // handle scale of radius and pad due to CTM
+        pad *= scaleFactor;
+        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
+        SkASSERT(devSpaceAmbientRadius <= MAX_BLUR_RADIUS);
+        SkASSERT(pad < MAX_PAD);
+        // convert devSpaceAmbientRadius to 14.2 fixed point and place in the R & G components
+        // convert pad to 6.2 fixed point and place in the B component
+        uint16_t iDevSpaceAmbientRadius = (uint16_t)(4.0f * devSpaceAmbientRadius);
+        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, iDevSpaceAmbientRadius >> 8,
+                iDevSpaceAmbientRadius & 0xff, (unsigned char)(4.0f * pad)));
+
+        paint.setShader(edgeShader);
+        canvas->drawRRect(ambientRRect, paint);
+    }
+
+    if (spotAlpha > 0.0f) {
+        const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+        float zRatio = casterZValue / (lightPos.z - casterZValue);
+        // clamp
+        if (zRatio < 0.0f) {
+            zRatio = 0.0f;
+        } else if (zRatio > 0.95f) {
+            zRatio = 0.95f;
+        }
+
+        const SkScalar lightWidth = SkiaFrameRenderer::getLightRadius();
+        SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
+        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
+        if (srcSpaceSpotRadius*scaleFactor > MAX_BLUR_RADIUS) {
+            srcSpaceSpotRadius = MAX_BLUR_RADIUS/scaleFactor;
+        }
+
+        SkRRect spotRRect;
+        if (isOval) {
+            spotRRect = SkRRect::MakeOval(casterRect);
+        } else if (isRect) {
+            spotRRect = SkRRect::MakeRectXY(casterRect, minRadius, minRadius);
+        } else {
+            spotRRect = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
+        }
+
+        SkRRect spotShadowRRect;
+        // Compute the scale and translation for the spot shadow.
+        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+        spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect);
+
+        SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(),
+                                       spotShadowRRect.rect().centerY());
+        SkMatrix ctmInverse;
+        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+            ALOGW("Matrix is degenerate. Will not render spot shadow!");
+            return;
+        }
+        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+        ctmInverse.mapPoints(&lightPos2D, 1);
+        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
+                zRatio*(center.fY - lightPos2D.fY));
+
+        SkAutoCanvasRestore acr(canvas, true);
+
+        // We want to extend the stroked area in so that it meets up with the caster
+        // geometry. The stroked geometry will, by definition already be inset half the
+        // stroke width but we also have to account for the scaling.
+        // We also add 1/2 to cover up AA on the interior edge.
+        SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(casterRect.fLeft),
+                SkTAbs(casterRect.fRight)), SkTMax(SkTAbs(casterRect.fTop),
+                SkTAbs(casterRect.fBottom)));
+        SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) +
+                scaleOffset + 0.5f;
+
+        // Compute area
+        SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount;
+        SkScalar strokedArea = 2.0f*strokeWidth * (spotShadowRRect.width()
+                + spotShadowRRect.height());
+        SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius)
+                * (spotShadowRRect.width() + srcSpaceSpotRadius);
+
+        SkPaint paint;
+        paint.setAntiAlias(true);
+
+        // If the area of the stroked geometry is larger than the fill geometry, just fill it.
+        if (strokedArea > filledArea || casterAlpha < 1.0f) {
+            paint.setStyle(SkPaint::kStrokeAndFill_Style);
+            paint.setStrokeWidth(srcSpaceSpotRadius);
+        } else {
+            // Since we can't have unequal strokes, inset the shadow rect so the inner
+            // and outer edges of the stroke will land where we want.
+            SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount/2.0f, insetAmount/2.0f);
+            SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount/2.0f,
+                    minRadius);
+            spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad);
+            paint.setStyle(SkPaint::kStroke_Style);
+            paint.setStrokeWidth(strokeWidth);
+        }
+
+        // handle scale of radius and pad due to CTM
+        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
+        SkASSERT(devSpaceSpotRadius <= MAX_BLUR_RADIUS);
+
+        const SkScalar devSpaceSpotPad = 0;
+        SkASSERT(devSpaceSpotPad < MAX_PAD);
+
+        // convert devSpaceSpotRadius to 14.2 fixed point and place in the R & G
+        // components convert devSpaceSpotPad to 6.2 fixed point and place in the B component
+        uint16_t iDevSpaceSpotRadius = (uint16_t)(4.0f * devSpaceSpotRadius);
+        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, iDevSpaceSpotRadius >> 8,
+                iDevSpaceSpotRadius & 0xff, (unsigned char)(4.0f * devSpaceSpotPad)));
+        paint.setShader(edgeShader);
+
+        canvas->translate(spotOffset.fX, spotOffset.fY);
+        canvas->drawRRect(spotShadowRRect, paint);
+    }
+}
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterZValue       the Z value of the caster RRect
+ * @param scaleFactor        the scale needed to map from src-space to device-space
+ * @param clipRR             the oval or rect with which the drawn roundrect must be intersected
+ * @param canvas             the destination for the shadow draws
+ */
+static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius,
+        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor,
+        const SkRRect& clipRR, SkCanvas* canvas) {
+    SkASSERT(cornerRadius >= 0.0f);
+
+    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
+            SkScalarHalf(casterRect.height()));
+
+    if (ambientAlpha > 0.0f) {
+        static const float kHeightFactor = 1.0f / 128.0f;
+        static const float kGeomFactor = 64.0f;
+
+        const SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
+        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
+
+        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
+        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
+
+        const SkRect srcSpaceAmbientRect = casterRect.makeOutset(ambientOffset, ambientOffset);
+        SkRect devSpaceAmbientRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceAmbientRect, srcSpaceAmbientRect);
+
+        SkRRect devSpaceAmbientRRect;
+        if (isOval) {
+            devSpaceAmbientRRect = SkRRect::MakeOval(devSpaceAmbientRect);
+        } else {
+            const SkScalar devSpaceCornerRadius = scaleFactor * (casterCornerRadius + ambientOffset);
+            devSpaceAmbientRRect = SkRRect::MakeRectXY(devSpaceAmbientRect, devSpaceCornerRadius,
+                    devSpaceCornerRadius);
+        }
+
+        const SkRect srcSpaceAmbClipRect = clipRR.rect().makeOutset(ambientOffset, ambientOffset);
+        SkRect devSpaceAmbClipRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceAmbClipRect, srcSpaceAmbClipRect);
+        SkRRect devSpaceAmbientClipRR;
+        if (clipRR.isOval()) {
+            devSpaceAmbientClipRR = SkRRect::MakeOval(devSpaceAmbClipRect);
+        } else {
+            SkASSERT(clipRR.isRect());
+            devSpaceAmbientClipRR = SkRRect::MakeRect(devSpaceAmbClipRect);
+        }
+
+        SkRect cover = srcSpaceAmbClipRect;
+        if (!cover.intersect(srcSpaceAmbientRect)) {
+            return;
+        }
+
+        SkPaint paint;
+        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, 0, 0, 0));
+        paint.setShader(SkRRectsGaussianEdgeShader::Make(devSpaceAmbientRRect,
+                devSpaceAmbientClipRR, devSpaceAmbientRadius));
+        canvas->drawRect(cover, paint);
+    }
+
+    if (spotAlpha > 0.0f) {
+        const Vector3 lightPos = SkiaFrameRenderer::getLightCenter();
+        float zRatio = casterZValue / (lightPos.z - casterZValue);
+        // clamp
+        if (zRatio < 0.0f) {
+            zRatio = 0.0f;
+        } else if (zRatio > 0.95f) {
+            zRatio = 0.95f;
+        }
+
+        const SkScalar lightWidth = SkiaFrameRenderer::getLightRadius();
+        const SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
+        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
+
+        // Compute the scale and translation for the spot shadow.
+        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
+        const SkMatrix spotMatrix = SkMatrix::MakeScale(scale, scale);
+
+        SkRect srcSpaceScaledRect = casterRect;
+        spotMatrix.mapRect(&srcSpaceScaledRect);
+        srcSpaceScaledRect.outset(SkScalarHalf(srcSpaceSpotRadius),
+                SkScalarHalf(srcSpaceSpotRadius));
+
+        SkRRect srcSpaceSpotRRect;
+        if (isOval) {
+            srcSpaceSpotRRect = SkRRect::MakeOval(srcSpaceScaledRect);
+        } else {
+            srcSpaceSpotRRect = SkRRect::MakeRectXY(srcSpaceScaledRect, casterCornerRadius * scale,
+                    casterCornerRadius * scale);
+        }
+
+        SkPoint center = SkPoint::Make(srcSpaceSpotRRect.rect().centerX(),
+                srcSpaceSpotRRect.rect().centerY());
+        SkMatrix ctmInverse;
+        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
+            ALOGW("Matrix is degenerate. Will not render spot shadow!");
+            return;
+        }
+        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
+        ctmInverse.mapPoints(&lightPos2D, 1);
+        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
+                zRatio*(center.fY - lightPos2D.fY));
+
+        SkAutoCanvasRestore acr(canvas, true);
+        canvas->translate(spotOffset.fX, spotOffset.fY);
+
+        SkRect devSpaceScaledRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceScaledRect, srcSpaceScaledRect);
+
+        SkRRect devSpaceSpotRRect;
+        if (isOval) {
+            devSpaceSpotRRect = SkRRect::MakeOval(devSpaceScaledRect);
+        } else {
+            const SkScalar devSpaceScaledCornerRadius = casterCornerRadius * scale * scaleFactor;
+            devSpaceSpotRRect = SkRRect::MakeRectXY(devSpaceScaledRect, devSpaceScaledCornerRadius,
+                    devSpaceScaledCornerRadius);
+        }
+
+        SkPaint paint;
+        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, 0, 0, 0));
+
+        SkRect srcSpaceScaledClipRect = clipRR.rect();
+        spotMatrix.mapRect(&srcSpaceScaledClipRect);
+        srcSpaceScaledClipRect.outset(SkScalarHalf(srcSpaceSpotRadius),
+                SkScalarHalf(srcSpaceSpotRadius));
+
+        SkRect devSpaceScaledClipRect;
+        canvas->getTotalMatrix().mapRect(&devSpaceScaledClipRect, srcSpaceScaledClipRect);
+        SkRRect devSpaceSpotClipRR;
+        if (clipRR.isOval()) {
+            devSpaceSpotClipRR = SkRRect::MakeOval(devSpaceScaledClipRect);
+        } else {
+            SkASSERT(clipRR.isRect());
+            devSpaceSpotClipRR = SkRRect::MakeRect(devSpaceScaledClipRect);
+        }
+
+        paint.setShader(SkRRectsGaussianEdgeShader::Make(devSpaceSpotRRect, devSpaceSpotClipRR,
+                devSpaceSpotRadius));
+
+        SkRect cover = srcSpaceScaledClipRect;
+        if (!cover.intersect(srcSpaceSpotRRect.rect())) {
+            return;
+        }
+
+        canvas->drawRect(cover, paint);
+    }
+}
+
+/**
+ * @param casterRect         the rectangle bounds of the RRect casting the shadow
+ * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
+ * @param casterClipRect     a rectangular clip that must be intersected with the
+ *                           shadow-casting RRect prior to casting the shadow
+ * @param revealClip         a circular clip that must be interested with the castClipRect
+ *                           and the shadow-casting rect prior to casting the shadow
+ * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
+ * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
+ * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
+ * @param casterZValue       the Z value of the caster RRect
+ * @param canvas             the destination for the shadow draws
+ *
+ * We have special cases for 4 round rect shadow draws:
+ *    1) a RRect clipped by a reveal animation
+ *    2) a RRect clipped by a rectangle
+ *    3) an unclipped RRect with non-uniform scale
+ *    4) an unclipped RRect with uniform scale
+ * 1,2 and 4 require that the scale is uniform.
+ * 1 and 2 require that rects stay rects.
+ */
+static bool DrawShadowsAsRRects(const SkRect& casterRect, SkScalar casterCornerRadius,
+        const SkRect& casterClipRect, const RevealClip& revealClip, SkScalar ambientAlpha,
+        SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkCanvas* canvas) {
+    SkScalar scaleFactors[2];
+    if (!canvas->getTotalMatrix().getMinMaxScales(scaleFactors)) {
+        ALOGW("Matrix is degenerate. Will not render shadow!");
+        return false;
+    }
+
+    // The casterClipRect will contain the casterRect when bounds clipping is disabled
+    bool casterIsClippedByRect = !casterClipRect.contains(casterRect);
+    bool uniformScale = scaleFactors[0] == scaleFactors[1];
+
+    if (revealClip.willClip()) {
+        if (casterIsClippedByRect || !uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
+            return false;  // Fall back to the slow path since PathOps are required
+        }
+
+        const float revealRadius = revealClip.getRadius();
+        SkRect revealClipRect = SkRect::MakeLTRB(revealClip.getX()-revealRadius,
+                revealClip.getY()-revealRadius, revealClip.getX()+revealRadius,
+                revealClip.getY()+revealRadius);
+        SkRRect revealClipRR = SkRRect::MakeOval(revealClipRect);
+
+        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
+                casterZValue, scaleFactors[0], revealClipRR, canvas);
+        return true;
+    }
+
+    if (casterIsClippedByRect) {
+        if (!uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
+            return false;  // Fall back to the slow path since PathOps are required
+        }
+
+        SkRRect casterClipRR = SkRRect::MakeRect(casterClipRect);
+
+        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
+                casterZValue, scaleFactors[0], casterClipRR, canvas);
+        return true;
+    }
+
+    // The fast path needs uniform scale
+    if (!uniformScale) {
+        SkRRect casterRR = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
+        DrawAmbientShadowGeneral(canvas, casterRR, casterZValue, ambientAlpha,
+                [&](const SkRRect& rrect, const SkPaint& paint) {
+                    canvas->drawRRect(rrect, paint);
+                });
+        DrawSpotShadowGeneral(canvas, casterRR, casterZValue, spotAlpha,
+                [&](const SkRRect& rrect, const SkPaint& paint) {
+                canvas->drawRRect(rrect, paint);
+                });
+        return true;
+    }
+
+    DrawRRectShadows(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, casterAlpha,
+            casterZValue, scaleFactors[0], canvas);
+    return true;
+}
+
+// copied from FrameBuilder::deferShadow
+void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster) {
+    const RenderProperties& casterProperties = caster->getNodeProperties();
+
+    if (casterProperties.getAlpha() <= 0.0f
+            || casterProperties.getOutline().getAlpha() <= 0.0f
+            || !casterProperties.getOutline().getPath()
+            || casterProperties.getScaleX() == 0
+            || casterProperties.getScaleY() == 0) {
+        // no shadow to draw
+        return;
+    }
+
+    const SkScalar casterAlpha = casterProperties.getAlpha()
+            * casterProperties.getOutline().getAlpha();
+    if (casterAlpha <= 0.0f) {
+        return;
+    }
+
+    float ambientAlpha = SkiaFrameRenderer::getAmbientShadowAlpha()*casterAlpha;
+    float spotAlpha = SkiaFrameRenderer::getSpotShadowAlpha()*casterAlpha;
+    const float casterZValue = casterProperties.getZ();
+
+    const RevealClip& revealClip = casterProperties.getRevealClip();
+    const SkPath* revealClipPath = revealClip.getPath();
+    if (revealClipPath && revealClipPath->isEmpty()) {
+        // An empty reveal clip means nothing is drawn
+        return;
+    }
+
+    bool clippedToBounds = casterProperties.getClippingFlags() & CLIP_TO_CLIP_BOUNDS;
+
+    SkRect casterClipRect = SkRect::MakeLargest();
+    if (clippedToBounds) {
+        Rect clipBounds;
+        casterProperties.getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
+        casterClipRect = clipBounds.toSkRect();
+    }
+
+    SkAutoCanvasRestore acr(canvas, true);
+
+    SkMatrix shadowMatrix;
+    mat4 hwuiMatrix(caster->getRecordedMatrix());
+    // TODO we don't pass the optional boolean to treat it as a 4x4 matrix
+    caster->getRenderNode()->applyViewPropertyTransforms(hwuiMatrix);
+    hwuiMatrix.copyTo(shadowMatrix);
+    canvas->concat(shadowMatrix);
+
+    const Outline& casterOutline = casterProperties.getOutline();
+    Rect possibleRect;
+    float radius;
+    if (casterOutline.getAsRoundRect(&possibleRect, &radius)) {
+        if (DrawShadowsAsRRects(possibleRect.toSkRect(), radius, casterClipRect, revealClip,
+                ambientAlpha, spotAlpha, casterAlpha, casterZValue, canvas)) {
+            return;
+        }
+    }
+
+    // Hard cases and calls to general shadow code
+    const SkPath* casterOutlinePath = casterProperties.getOutline().getPath();
+
+    // holds temporary SkPath to store the result of intersections
+    SkPath tmpPath;
+    const SkPath* casterPath = casterOutlinePath;
+
+    // TODO: In to following course of code that calculates the final shape, is there an optimal
+    //       of doing the Op calculations?
+    // intersect the shadow-casting path with the reveal, if present
+    if (revealClipPath) {
+        Op(*casterPath, *revealClipPath, kIntersect_SkPathOp, &tmpPath);
+        casterPath = &tmpPath;
+    }
+
+    // intersect the shadow-casting path with the clipBounds, if present
+    if (clippedToBounds) {
+        SkPath clipBoundsPath;
+        clipBoundsPath.addRect(casterClipRect);
+        Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
+        casterPath = &tmpPath;
+    }
+
+    DrawAmbientShadowGeneral(canvas, *casterPath, casterZValue, ambientAlpha,
+            [&](const SkPath& path, const SkPaint& paint) {
+                canvas->drawPath(path, paint);
+            });
+
+    DrawSpotShadowGeneral(canvas, *casterPath, casterZValue, spotAlpha,
+            [&](const SkPath& path, const SkPaint& paint) {
+                canvas->drawPath(path, paint);
+            });
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
new file mode 100644
index 0000000..298a732
--- /dev/null
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -0,0 +1,80 @@
+/*
+ * 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 "RenderNodeDrawable.h"
+
+#include <SkCanvas.h>
+#include <SkDrawable.h>
+#include <utils/FatVector.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaDisplayList;
+class EndReorderBarrierDrawable;
+
+/**
+ * StartReorderBarrierDrawable and EndReorderBarrierDrawable work together to define
+ * a sub-list in a display list that need to be drawn out-of-order sorted instead by render
+ * node Z index.
+ * StartReorderBarrierDrawable will sort the entire range and it will draw
+ * render nodes in the range with negative Z index.
+ */
+class StartReorderBarrierDrawable : public SkDrawable {
+public:
+    explicit StartReorderBarrierDrawable(SkiaDisplayList* data);
+
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLargest();
+    }
+    virtual void onDraw(SkCanvas* canvas) override;
+
+private:
+    size_t mEndChildIndex;
+    size_t mBeginChildIndex;
+    FatVector<RenderNodeDrawable*, 16> mChildren;
+    SkiaDisplayList* mDisplayList;
+
+    friend class EndReorderBarrierDrawable;
+};
+
+/**
+ * See StartReorderBarrierDrawable.
+ * EndReorderBarrierDrawable relies on StartReorderBarrierDrawable to host and sort the render
+ * nodes by Z index. When EndReorderBarrierDrawable is drawn it will draw all render nodes in the
+ * range with positive Z index. It is also responsible for drawing shadows for the nodes
+ * corresponding to their z-index.
+ */
+class EndReorderBarrierDrawable : public SkDrawable {
+public:
+    explicit EndReorderBarrierDrawable(StartReorderBarrierDrawable* startBarrier);
+protected:
+    virtual SkRect onGetBounds() override {
+        return SkRect::MakeLargest();
+    }
+    virtual void onDraw(SkCanvas* canvas) override;
+private:
+    void drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster);
+    StartReorderBarrierDrawable* mStartBarrier;
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
similarity index 98%
rename from libs/hwui/SkiaDisplayList.cpp
rename to libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index d10f306..c734097e 100644
--- a/libs/hwui/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -24,6 +24,7 @@
 
 namespace android {
 namespace uirenderer {
+namespace skiapipeline {
 
 SkiaDisplayList::SkiaDisplayList(SkRect bounds) : mDrawable(SkLiteDL::New(bounds)) {
     SkASSERT(projectionReceiveIndex == -1);
@@ -130,5 +131,6 @@
     new (&allocator) LinearAllocator();
 }
 
+}; // namespace skiapipeline
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
similarity index 97%
rename from libs/hwui/SkiaDisplayList.h
rename to libs/hwui/pipeline/skia/SkiaDisplayList.h
index c8a82bd..734aae4a 100644
--- a/libs/hwui/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -17,7 +17,8 @@
 #pragma once
 
 #include "DisplayList.h"
-#include "SkiaDrawables.h"
+#include "GLFunctorDrawable.h"
+#include "RenderNodeDrawable.h"
 
 #include <deque>
 #include <SkLiteDL.h>
@@ -25,6 +26,7 @@
 
 namespace android {
 namespace uirenderer {
+namespace skiapipeline {
 
 /**
  * This class is intended to be self contained, but still subclasses from
@@ -148,5 +150,6 @@
     bool mPinnedImages = false;
 };
 
+}; // namespace skiapipeline
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaFrameRenderer.h b/libs/hwui/pipeline/skia/SkiaFrameRenderer.h
new file mode 100644
index 0000000..70207c1
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaFrameRenderer.h
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * TODO: this is a stub that will be added in a subsquent CL
+ */
+class SkiaFrameRenderer {
+public:
+
+    static bool skpCaptureEnabled() { return false; }
+
+    // TODO avoids unused compile error but we need to pass this to the reorder drawables!
+    static float getLightRadius() {
+        return 1.0f;
+    }
+
+    static uint8_t getAmbientShadowAlpha() {
+        return 1;
+    }
+
+    static uint8_t getSpotShadowAlpha() {
+        return 1;
+    }
+
+    static Vector3 getLightCenter() {
+        Vector3 result;
+        result.x = result.y = result.z = 1.0f;
+        return result;
+    }
+
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
new file mode 100644
index 0000000..8a42983
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -0,0 +1,252 @@
+/*
+ * 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 "SkiaRecordingCanvas.h"
+
+#include "Layer.h"
+#include "RenderNode.h"
+#include "LayerDrawable.h"
+#include "NinePatchUtils.h"
+#include "pipeline/skia/AnimatedDrawables.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+// ----------------------------------------------------------------------------
+// Recording Canvas Setup
+// ----------------------------------------------------------------------------
+
+void SkiaRecordingCanvas::initDisplayList(uirenderer::RenderNode* renderNode, int width,
+        int height) {
+    mBarrierPending = false;
+    mCurrentBarrier = nullptr;
+    SkASSERT(mDisplayList.get() == nullptr);
+
+    if (renderNode) {
+        mDisplayList = renderNode->detachAvailableList();
+    }
+    SkRect bounds = SkRect::MakeWH(width, height);
+    if (mDisplayList) {
+        mDisplayList->reset(nullptr, bounds);
+    } else {
+        mDisplayList.reset(new SkiaDisplayList(bounds));
+    }
+
+    mRecorder.reset(mDisplayList->mDrawable.get());
+    SkiaCanvas::reset(&mRecorder);
+}
+
+uirenderer::DisplayList* SkiaRecordingCanvas::finishRecording() {
+    // close any existing chunks if necessary
+    insertReorderBarrier(false);
+    mRecorder.restoreToCount(1);
+    return mDisplayList.release();
+}
+
+// ----------------------------------------------------------------------------
+// Recording Canvas draw operations: View System
+// ----------------------------------------------------------------------------
+
+void SkiaRecordingCanvas::drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+        uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+        uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+        uirenderer::CanvasPropertyPrimitive* ry, uirenderer::CanvasPropertyPaint* paint) {
+    drawDrawable(mDisplayList->allocateDrawable<AnimatedRoundRect>(left, top, right, bottom,
+            rx, ry, paint));
+}
+
+void SkiaRecordingCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+        uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+        uirenderer::CanvasPropertyPaint* paint) {
+    drawDrawable(mDisplayList->allocateDrawable<AnimatedCircle>(x, y, radius, paint));
+}
+
+void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) {
+    mBarrierPending = enableReorder;
+
+    if (nullptr != mCurrentBarrier) {
+        // finish off the existing chunk
+        SkDrawable* drawable =
+                mDisplayList->allocateDrawable<EndReorderBarrierDrawable>(
+                mCurrentBarrier);
+        mCurrentBarrier = nullptr;
+        drawDrawable(drawable);
+    }
+}
+
+void SkiaRecordingCanvas::drawLayer(uirenderer::DeferredLayerUpdater* layerUpdater) {
+    if (layerUpdater != nullptr && layerUpdater->backingLayer() != nullptr) {
+        uirenderer::Layer* layer = layerUpdater->backingLayer();
+        sk_sp<SkDrawable> drawable(new LayerDrawable(layer));
+        drawDrawable(drawable.get());
+    }
+}
+
+void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) {
+    // lazily create the chunk if needed
+    if (mBarrierPending) {
+        mCurrentBarrier = (StartReorderBarrierDrawable*)
+                mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(
+                mDisplayList.get());
+        drawDrawable(mCurrentBarrier);
+        mBarrierPending = false;
+    }
+
+    // record the child node
+    mDisplayList->mChildNodes.emplace_back(renderNode, asSkCanvas());
+    drawDrawable(&mDisplayList->mChildNodes.back());
+
+    // use staging property, since recording on UI thread
+    if (renderNode->stagingProperties().isProjectionReceiver()) {
+        mDisplayList->mIsProjectionReceiver = true;
+        // set projectionReceiveIndex so that RenderNode.hasProjectionReceiver returns true
+        mDisplayList->projectionReceiveIndex = mDisplayList->mChildNodes.size() - 1;
+    }
+}
+
+void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
+        uirenderer::GlFunctorLifecycleListener* listener) {
+    mDisplayList->mChildFunctors.emplace_back(functor, listener, asSkCanvas());
+    drawDrawable(&mDisplayList->mChildFunctors.back());
+}
+
+class VectorDrawable : public SkDrawable {
+ public:
+    VectorDrawable(VectorDrawableRoot* tree) : mRoot(tree) {}
+
+ protected:
+     virtual SkRect onGetBounds() override {
+         return SkRect::MakeLargest();
+     }
+     virtual void onDraw(SkCanvas* canvas) override {
+         Bitmap& hwuiBitmap = mRoot->getBitmapUpdateIfDirty();
+         SkBitmap bitmap;
+         hwuiBitmap.getSkBitmap(&bitmap);
+         SkPaint* paint = mRoot->getPaint();
+         canvas->drawBitmapRect(bitmap, mRoot->mutateProperties()->getBounds(), paint);
+         /*
+          * TODO we can draw this directly but need to address the following...
+          *
+          * 1) Add drawDirect(SkCanvas*) to VectorDrawableRoot
+          * 2) fix VectorDrawable.cpp's Path::draw to not make a temporary path
+          *    so that we don't break caching
+          * 3) figure out how to set path's as volatile during animation
+          * 4) if mRoot->getPaint() != null either promote to layer (during
+          *    animation) or cache in SkSurface (for static content)
+          *
+          */
+     }
+
+ private:
+    sp<VectorDrawableRoot> mRoot;
+};
+
+void SkiaRecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
+    drawDrawable(mDisplayList->allocateDrawable<VectorDrawable>(tree));
+    mDisplayList->mVectorDrawables.push_back(tree);
+}
+
+// ----------------------------------------------------------------------------
+// Recording Canvas draw operations: Bitmaps
+// ----------------------------------------------------------------------------
+
+inline static const SkPaint* nonAAPaint(const SkPaint* origPaint, SkPaint* tmpPaint) {
+    if (origPaint && origPaint->isAntiAlias()) {
+        *tmpPaint = *origPaint;
+        tmpPaint->setAntiAlias(false);
+        return tmpPaint;
+    } else {
+        return origPaint;
+    }
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
+    SkBitmap skBitmap;
+    bitmap.getSkBitmap(&skBitmap);
+
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+    if (!skBitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
+        const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+    SkAutoCanvasRestore acr(&mRecorder, true);
+    concat(matrix);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
+        float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
+        float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+    SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
+    SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+    SkPaint tmpPaint;
+    mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
+}
+
+void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
+        float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
+    SkBitmap bitmap;
+    hwuiBitmap.getSkBitmap(&bitmap);
+
+    SkCanvas::Lattice lattice;
+    NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+
+    lattice.fFlags = nullptr;
+    int numFlags = 0;
+    if (chunk.numColors > 0 && chunk.numColors == NinePatchUtils::NumDistinctRects(lattice)) {
+        // We can expect the framework to give us a color for every distinct rect.
+        // Skia requires placeholder flags for degenerate rects.
+        numFlags = (lattice.fXCount + 1) * (lattice.fYCount + 1);
+    }
+
+    SkAutoSTMalloc<25, SkCanvas::Lattice::Flags> flags(numFlags);
+    if (numFlags > 0) {
+        NinePatchUtils::SetLatticeFlags(&lattice, flags.get(), numFlags, chunk);
+    }
+
+    lattice.fBounds = nullptr;
+    SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
+    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+    if (!bitmap.isImmutable()) {
+        mDisplayList->mMutableImages.push_back(image.get());
+    }
+
+    SkPaint tmpPaint;
+    mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
+}
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
new file mode 100644
index 0000000..8aef97f
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -0,0 +1,94 @@
+/*
+ * 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 "SkiaCanvas.h"
+#include "SkiaDisplayList.h"
+#include "ReorderBarrierDrawables.h"
+#include <SkLiteRecorder.h>
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+/**
+ * A SkiaCanvas implementation that records drawing operations for deferred rendering backed by a
+ * SkLiteRecorder and a SkiaDisplayList.
+ */
+class SkiaRecordingCanvas : public SkiaCanvas {
+ public:
+    explicit SkiaRecordingCanvas(uirenderer::RenderNode* renderNode, int width, int height) {
+        initDisplayList(renderNode, width, height);
+    }
+
+    virtual void setBitmap(const SkBitmap& bitmap) override {
+        LOG_ALWAYS_FATAL("DisplayListCanvas is not backed by a bitmap.");
+    }
+
+    virtual void resetRecording(int width, int height,
+            uirenderer::RenderNode* renderNode) override {
+        initDisplayList(renderNode, width, height);
+    }
+
+    virtual uirenderer::DisplayList* finishRecording() override;
+
+    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 drawNinePatch(Bitmap& hwuiBitmap, const android::Res_png_9patch& chunk,
+            float dstLeft, float dstTop, float dstRight, float dstBottom,
+            const SkPaint* paint) override;
+
+    virtual void drawRoundRect(uirenderer::CanvasPropertyPrimitive* left,
+            uirenderer::CanvasPropertyPrimitive* top, uirenderer::CanvasPropertyPrimitive* right,
+            uirenderer::CanvasPropertyPrimitive* bottom, uirenderer::CanvasPropertyPrimitive* rx,
+            uirenderer::CanvasPropertyPrimitive* ry,
+            uirenderer::CanvasPropertyPaint* paint) override;
+    virtual void drawCircle(uirenderer::CanvasPropertyPrimitive* x,
+            uirenderer::CanvasPropertyPrimitive* y, uirenderer::CanvasPropertyPrimitive* radius,
+            uirenderer::CanvasPropertyPaint* paint) override;
+
+    virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
+
+    virtual void insertReorderBarrier(bool enableReorder) override;
+    virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
+    virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
+    virtual void callDrawGLFunction(Functor* functor,
+                                    uirenderer::GlFunctorLifecycleListener* listener) override;
+
+private:
+    SkLiteRecorder mRecorder;
+    std::unique_ptr<SkiaDisplayList> mDisplayList;
+    bool mBarrierPending;
+    StartReorderBarrierDrawable* mCurrentBarrier;
+
+    /**
+     *  A new SkiaDisplayList is created or recycled if available.
+     *
+     *  @param renderNode is optional and used to recycle an old display list.
+     *  @param width used to calculate recording bounds.
+     *  @param height used to calculate recording bounds.
+     */
+    void initDisplayList(uirenderer::RenderNode* renderNode, int width, int height);
+};
+
+}; // namespace skiapipeline
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 5b9b003..9530c79 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -125,5 +125,44 @@
     return utf16;
 }
 
+SkColor TestUtils::getColor(const sk_sp<SkSurface>& surface, int x, int y) {
+    SkPixmap pixmap;
+    if (!surface->peekPixels(&pixmap)) {
+        return 0;
+    }
+    switch (pixmap.colorType()) {
+        case kGray_8_SkColorType: {
+            const uint8_t* addr = pixmap.addr8(x, y);
+            return SkColorSetRGB(*addr, *addr, *addr);
+        }
+        case kAlpha_8_SkColorType: {
+            const uint8_t* addr = pixmap.addr8(x, y);
+            return SkColorSetA(0, addr[0]);
+        }
+        case kRGB_565_SkColorType: {
+            const uint16_t* addr = pixmap.addr16(x, y);
+            return SkPixel16ToColor(addr[0]);
+        }
+        case kARGB_4444_SkColorType: {
+            const uint16_t* addr = pixmap.addr16(x, y);
+            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case kBGRA_8888_SkColorType: {
+            const uint32_t* addr = pixmap.addr32(x, y);
+            SkPMColor c = SkSwizzle_BGRA_to_PMColor(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        case kRGBA_8888_SkColorType: {
+            const uint32_t* addr = pixmap.addr32(x, y);
+            SkPMColor c = SkSwizzle_RGBA_to_PMColor(addr[0]);
+            return SkUnPreMultiply::PMColorToColor(c);
+        }
+        default:
+            return 0;
+    }
+    return 0;
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index f6fe7d2..0be5a3b 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -260,6 +260,8 @@
          int mLastMode = -1;
      };
 
+    static SkColor getColor(const sk_sp<SkSurface>& surface, int x, int y);
+
 private:
     static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
         node->syncProperties();
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
new file mode 100644
index 0000000..19c311c
--- /dev/null
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -0,0 +1,234 @@
+/*
+ * 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 <gtest/gtest.h>
+#include <VectorDrawable.h>
+
+#include "AnimationContext.h"
+#include "DamageAccumulator.h"
+#include "IContextFactory.h"
+#include "pipeline/skia/SkiaDisplayList.h"
+#include "pipeline/skia/SkiaRecordingCanvas.h"
+#include "renderthread/CanvasContext.h"
+#include "tests/common/TestUtils.h"
+#include "SkiaCanvas.h"
+#include <SkLiteRecorder.h>
+#include <string.h>
+
+
+using namespace android;
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::skiapipeline;
+
+static sp<RenderNode> createSkiaNode(int left, int top, int right, int bottom,
+        std::function<void(RenderProperties& props, SkiaRecordingCanvas& canvas)> setup,
+        const char* name = nullptr, SkiaDisplayList* displayList = nullptr) {
+#if HWUI_NULL_GPU
+    // if RenderNodes are being sync'd/used, device info will be needed, since
+    // DeviceInfo::maxTextureSize() affects layer property
+    DeviceInfo::initialize();
+#endif
+    sp<RenderNode> node = new RenderNode();
+    if (name) {
+        node->setName(name);
+    }
+    RenderProperties& props = node->mutateStagingProperties();
+    props.setLeftTopRightBottom(left, top, right, bottom);
+    if (displayList) {
+        node->setStagingDisplayList(displayList, nullptr);
+    }
+    if (setup) {
+        std::unique_ptr<SkiaRecordingCanvas> canvas(new SkiaRecordingCanvas(nullptr,
+            props.getWidth(), props.getHeight()));
+        setup(props, *canvas.get());
+        node->setStagingDisplayList(canvas->finishRecording(), nullptr);
+    }
+    node->setPropertyFieldsDirty(0xFFFFFFFF);
+    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
+    return node;
+}
+
+TEST(RenderNodeDrawable, create) {
+    auto rootNode = TestUtils::createNode(0, 0, 200, 400,
+            [](RenderProperties& props, Canvas& canvas) {
+                canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
+            });
+
+    auto skLiteDL = SkLiteDL::New(SkRect::MakeWH(1, 1));
+    SkLiteRecorder canvas;
+    canvas.reset(skLiteDL.get());
+    canvas.translate(100, 100);
+    RenderNodeDrawable drawable(rootNode.get(), &canvas);
+
+    ASSERT_EQ(drawable.getRenderNode(), rootNode.get());
+    ASSERT_EQ(&drawable.getNodeProperties(), &rootNode->properties());
+    ASSERT_EQ(drawable.getRecordedMatrix(), canvas.getTotalMatrix());
+}
+
+TEST(RenderNodeDrawable, drawContent) {
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    //create a RenderNodeDrawable backed by a RenderNode backed by a SkLiteRecorder
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
+            recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+    RenderNodeDrawable drawable(rootNode.get(), &canvas, false);
+
+    //negative and positive Z order are drawn out of order
+    rootNode->animatorProperties().setElevation(10.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+    rootNode->animatorProperties().setElevation(-10.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    //zero Z are drawn immediately
+    rootNode->animatorProperties().setElevation(0.0f);
+    canvas.drawDrawable(&drawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
+
+//TODO: another test that verifies equal z values are drawn in order, and barriers prevent Z
+//intermixing (model after FrameBuilder zReorder)
+TEST(RenderNodeDrawable, drawAndReorder) {
+    //this test exercises StartReorderBarrierDrawable, EndReorderBarrierDrawable and
+    //SkiaRecordingCanvas
+    auto surface = SkSurface::MakeRasterN32Premul(4, 4);
+    SkCanvas& canvas = *surface->getCanvas();
+
+    canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
+
+    //-z draws to all 4 pixels (RED)
+    auto redNode = createSkiaNode(0, 0, 4, 4,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+            props.setElevation(-10.0f);
+        }, "redNode");
+
+    //0z draws to bottom 2 pixels (GREEN)
+    auto bottomHalfGreenNode = createSkiaNode(0, 0, 4, 4,
+            [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) {
+                SkPaint greenPaint;
+                greenPaint.setColor(SK_ColorGREEN);
+                greenPaint.setStyle(SkPaint::kFill_Style);
+                bottomHalfGreenCanvas.drawRect(0, 2, 4, 4, greenPaint);
+                props.setElevation(0.0f);
+            }, "bottomHalfGreenNode");
+
+    //+z draws to right 2 pixels (BLUE)
+    auto rightHalfBlueNode = createSkiaNode(0, 0, 4, 4,
+        [](RenderProperties& props, SkiaRecordingCanvas& rightHalfBlueCanvas) {
+            SkPaint bluePaint;
+            bluePaint.setColor(SK_ColorBLUE);
+            bluePaint.setStyle(SkPaint::kFill_Style);
+            rightHalfBlueCanvas.drawRect(2, 0, 4, 4, bluePaint);
+            props.setElevation(10.0f);
+        }, "rightHalfBlueNode");
+
+    auto rootNode = createSkiaNode(0, 0, 4, 4,
+            [&](RenderProperties& props, SkiaRecordingCanvas& rootRecorder) {
+                rootRecorder.insertReorderBarrier(true);
+                //draw in reverse Z order, so Z alters draw order
+                rootRecorder.drawRenderNode(rightHalfBlueNode.get());
+                rootRecorder.drawRenderNode(bottomHalfGreenNode.get());
+                rootRecorder.drawRenderNode(redNode.get());
+            }, "rootNode");
+
+    RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable3);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 3), SK_ColorGREEN);
+    ASSERT_EQ(TestUtils::getColor(surface, 3, 3), SK_ColorBLUE);
+}
+
+TEST(RenderNodeDrawable, composeOnLayer)
+{
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& recorder) {
+            recorder.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        });
+
+    //attach a layer to the render node
+    auto surfaceLayer = SkSurface::MakeRasterN32Premul(1, 1);
+    auto canvas2 = surfaceLayer->getCanvas();
+    canvas2->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver);
+    rootNode->setLayerSurface( surfaceLayer  );
+
+    RenderNodeDrawable drawable1(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable1);
+    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));
+
+    RenderNodeDrawable drawable2(rootNode.get(), &canvas, true);
+    canvas.drawDrawable(&drawable2);
+    ASSERT_EQ(SK_ColorWHITE, TestUtils::getColor(surface, 0, 0));
+
+    RenderNodeDrawable drawable3(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&drawable3);
+    ASSERT_EQ(SK_ColorRED, TestUtils::getColor(surface, 0, 0));
+
+    rootNode->setLayerSurface( sk_sp<SkSurface>()  );
+}
+
+//TODO: refactor to cover test cases from FrameBuilderTests_projectionReorder
+//validate with bounds and projection path mask.
+//TODO: research if we could hook in and mock/validate different aspects of the drawing,
+//instead of validating pixels
+TEST(RenderNodeDrawable, projectDraw) {
+    auto surface = SkSurface::MakeRasterN32Premul(1, 1);
+    SkCanvas& canvas = *surface->getCanvas();
+    canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE);
+
+    auto redNode = createSkiaNode(0, 0, 1, 1,
+        [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) {
+            redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
+        }, "redNode");
+
+    auto greenNodeWithRedChild = createSkiaNode(0, 0, 1, 1,
+        [&](RenderProperties& props, SkiaRecordingCanvas& greenCanvasWithRedChild) {
+            greenCanvasWithRedChild.drawRenderNode(redNode.get());
+            greenCanvasWithRedChild.drawColor(SK_ColorGREEN, SkBlendMode::kSrcOver);
+        }, "greenNodeWithRedChild");
+
+    auto rootNode = createSkiaNode(0, 0, 1, 1,
+        [&](RenderProperties& props, SkiaRecordingCanvas& rootCanvas) {
+            rootCanvas.drawRenderNode(greenNodeWithRedChild.get());
+        }, "rootNode");
+    SkiaDisplayList* rootDisplayList = static_cast<SkiaDisplayList*>(
+        (const_cast<DisplayList*>(rootNode->getDisplayList())));
+
+    RenderNodeDrawable rootDrawable(rootNode.get(), &canvas, false);
+    canvas.drawDrawable(&rootDrawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorGREEN);
+
+    //project redNode on rootNode, which will change the test outcome,
+    //because redNode will draw after greenNodeWithRedChild
+    rootDisplayList->mIsProjectionReceiver = true;
+    redNode->animatorProperties().setProjectBackwards(true);
+    canvas.drawDrawable(&rootDrawable);
+    ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED);
+}
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index 72029b9..fe6cea6 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -20,14 +20,14 @@
 #include "AnimationContext.h"
 #include "DamageAccumulator.h"
 #include "IContextFactory.h"
-#include "SkiaDisplayList.h"
+#include "pipeline/skia/SkiaDisplayList.h"
 #include "renderthread/CanvasContext.h"
 #include "tests/common/TestUtils.h"
 
-
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::skiapipeline;
 
 TEST(SkiaDisplayList, create) {
     SkRect bounds = SkRect::MakeWH(200, 200);
