Delete old rendering pipeline

fixes: 30002246

Change-Id: I45df0e924708526cee045b14c291bd23aa1a92db
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index d90f88f..95b28d3 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -2,8 +2,6 @@
 include $(CLEAR_VARS)
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
-HWUI_NEW_OPS := true
-
 # Enables fine-grained GLES error checking
 # If set to true, every GLES call is wrapped & error checked
 # Has moderate overhead
@@ -45,19 +43,21 @@
     Animator.cpp \
     AnimatorManager.cpp \
     AssetAtlas.cpp \
+    BakedOpDispatcher.cpp \
+    BakedOpRenderer.cpp \
+    BakedOpState.cpp \
     Caches.cpp \
     CanvasState.cpp \
     ClipArea.cpp \
     DamageAccumulator.cpp \
-    DeferredDisplayList.cpp \
     DeferredLayerUpdater.cpp \
     DeviceInfo.cpp \
     DisplayList.cpp \
-    DisplayListCanvas.cpp \
     Dither.cpp \
     Extensions.cpp \
     FboCache.cpp \
     FontRenderer.cpp \
+    FrameBuilder.cpp \
     FrameInfo.cpp \
     FrameInfoVisualizer.cpp \
     GammaFontRenderer.cpp \
@@ -68,23 +68,24 @@
     Interpolator.cpp \
     JankTracker.cpp \
     Layer.cpp \
-    LayerCache.cpp \
+    LayerBuilder.cpp \
     LayerRenderer.cpp \
     LayerUpdateQueue.cpp \
     Matrix.cpp \
-    OpenGLRenderer.cpp \
+    OpDumper.cpp \
     Patch.cpp \
     PatchCache.cpp \
     PathCache.cpp \
-    PathTessellator.cpp \
     PathParser.cpp \
+    PathTessellator.cpp \
     PixelBuffer.cpp \
     Program.cpp \
     ProgramCache.cpp \
     Properties.cpp \
-    PropertyValuesHolder.cpp \
     PropertyValuesAnimatorSet.cpp \
+    PropertyValuesHolder.cpp \
     Readback.cpp \
+    RecordingCanvas.cpp \
     RenderBufferCache.cpp \
     RenderNode.cpp \
     RenderProperties.cpp \
@@ -130,20 +131,6 @@
 # clang's warning is broken, see: https://llvm.org/bugs/show_bug.cgi?id=21629
 hwui_cflags += -Wno-missing-braces
 
-ifeq (true, $(HWUI_NEW_OPS))
-    hwui_src_files += \
-        BakedOpDispatcher.cpp \
-        BakedOpRenderer.cpp \
-        BakedOpState.cpp \
-        FrameBuilder.cpp \
-        LayerBuilder.cpp \
-        OpDumper.cpp \
-        RecordingCanvas.cpp
-
-    hwui_cflags += -DHWUI_NEW_OPS
-
-endif
-
 ifndef HWUI_COMPILE_SYMBOLS
     hwui_cflags += -fvisibility=hidden
 endif
@@ -255,40 +242,36 @@
 LOCAL_SRC_FILES += \
     $(hwui_test_common_src_files) \
     tests/unit/main.cpp \
+    tests/unit/BakedOpDispatcherTests.cpp \
+    tests/unit/BakedOpRendererTests.cpp \
+    tests/unit/BakedOpStateTests.cpp \
     tests/unit/CanvasStateTests.cpp \
     tests/unit/ClipAreaTests.cpp \
     tests/unit/DamageAccumulatorTests.cpp \
     tests/unit/DeviceInfoTests.cpp \
     tests/unit/FatVectorTests.cpp \
     tests/unit/FontRendererTests.cpp \
+    tests/unit/FrameBuilderTests.cpp \
     tests/unit/GlopBuilderTests.cpp \
     tests/unit/GpuMemoryTrackerTests.cpp \
     tests/unit/GradientCacheTests.cpp \
     tests/unit/LayerUpdateQueueTests.cpp \
+    tests/unit/LeakCheckTests.cpp \
     tests/unit/LinearAllocatorTests.cpp \
     tests/unit/MatrixTests.cpp \
     tests/unit/MeshStateTests.cpp \
     tests/unit/OffscreenBufferPoolTests.cpp \
+    tests/unit/OpDumperTests.cpp \
+    tests/unit/RecordingCanvasTests.cpp \
     tests/unit/RenderNodeTests.cpp \
     tests/unit/RenderPropertiesTests.cpp \
     tests/unit/SkiaBehaviorTests.cpp \
+    tests/unit/SkiaCanvasTests.cpp \
     tests/unit/SnapshotTests.cpp \
     tests/unit/StringUtilsTests.cpp \
     tests/unit/TestUtilsTests.cpp \
     tests/unit/TextDropShadowCacheTests.cpp \
-    tests/unit/VectorDrawableTests.cpp
-
-ifeq (true, $(HWUI_NEW_OPS))
-    LOCAL_SRC_FILES += \
-        tests/unit/BakedOpDispatcherTests.cpp \
-        tests/unit/BakedOpRendererTests.cpp \
-        tests/unit/BakedOpStateTests.cpp \
-        tests/unit/FrameBuilderTests.cpp \
-        tests/unit/LeakCheckTests.cpp \
-        tests/unit/OpDumperTests.cpp \
-        tests/unit/RecordingCanvasTests.cpp \
-        tests/unit/SkiaCanvasTests.cpp
-endif
+    tests/unit/VectorDrawableTests.cpp \
 
 include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_NATIVE_TEST)
@@ -344,15 +327,12 @@
     tests/microbench/main.cpp \
     tests/microbench/DisplayListCanvasBench.cpp \
     tests/microbench/FontBench.cpp \
+    tests/microbench/FrameBuilderBench.cpp \
     tests/microbench/LinearAllocatorBench.cpp \
     tests/microbench/PathParserBench.cpp \
     tests/microbench/ShadowBench.cpp \
     tests/microbench/TaskManagerBench.cpp
 
-ifeq (true, $(HWUI_NEW_OPS))
-    LOCAL_SRC_FILES += \
-        tests/microbench/FrameBuilderBench.cpp
-endif
 
 include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_NATIVE_BENCHMARK)
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f2d344f..ef81a52 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -163,17 +163,15 @@
     log.appendFormat("Current memory usage / total memory usage (bytes):\n");
     log.appendFormat("  TextureCache         %8d / %8d\n",
             textureCache.getSize(), textureCache.getMaxSize());
-    log.appendFormat("  LayerCache           %8d / %8d (numLayers = %zu)\n",
-            layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount());
     if (mRenderState) {
         int memused = 0;
         for (std::set<Layer*>::iterator it = mRenderState->mActiveLayers.begin();
                 it != mRenderState->mActiveLayers.end(); it++) {
             const Layer* layer = *it;
-            log.appendFormat("    Layer size %dx%d; isTextureLayer()=%d; texid=%u fbo=%u; refs=%d\n",
+            log.appendFormat("    Layer size %dx%d; texid=%u refs=%d\n",
                     layer->getWidth(), layer->getHeight(),
-                    layer->isTextureLayer(), layer->getTextureId(),
-                    layer->getFbo(), layer->getStrongCount());
+                    layer->getTextureId(),
+                    layer->getStrongCount());
             memused += layer->getWidth() * layer->getHeight() * 4;
         }
         log.appendFormat("  Layers total   %8d (numLayers = %zu)\n",
@@ -248,7 +246,6 @@
             tessellationCache.clear();
             // fall through
         case FlushMode::Layers:
-            layerCache.clear();
             renderBufferCache.clear();
             break;
     }
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index eac9359..fe9411d 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_CACHES_H
-#define ANDROID_HWUI_CACHES_H
+#pragma once
 
 #include "AssetAtlas.h"
 #include "Dither.h"
@@ -23,7 +22,6 @@
 #include "FboCache.h"
 #include "GammaFontRenderer.h"
 #include "GradientCache.h"
-#include "LayerCache.h"
 #include "PatchCache.h"
 #include "ProgramCache.h"
 #include "PathCache.h"
@@ -146,7 +144,6 @@
     Extensions mExtensions;
 public:
     TextureCache textureCache;
-    LayerCache layerCache;
     RenderBufferCache renderBufferCache;
     GradientCache gradientCache;
     PatchCache patchCache;
@@ -205,5 +202,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_CACHES_H
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index e2149d1..7e2c28c 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -23,8 +23,7 @@
 
 
 CanvasState::CanvasState(CanvasStateClient& renderer)
-        : mDirtyClip(false)
-        , mWidth(-1)
+        : mWidth(-1)
         , mHeight(-1)
         , mSaveCount(1)
         , mCanvas(renderer)
@@ -205,19 +204,16 @@
 
 bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
     mSnapshot->clip(Rect(left, top, right, bottom), op);
-    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
 bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
     mSnapshot->clipPath(*path, op);
-    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
 bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
     mSnapshot->clipRegionTransformed(*region, op);
-    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
@@ -236,15 +232,6 @@
     }
 }
 
-void CanvasState::setClippingRoundRect(LinearAllocator& allocator,
-        const Rect& rect, float radius, bool highPriority) {
-    mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
-}
-
-void CanvasState::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
-    mSnapshot->setProjectionPathMask(allocator, path);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Quick Rejection
 ///////////////////////////////////////////////////////////////////////////////
@@ -263,7 +250,7 @@
         float right, float bottom,
         bool* clipRequired, bool* roundRectClipRequired,
         bool snapOut) const {
-    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
+    if (bottom <= top || right <= left) {
         return true;
     }
 
@@ -291,7 +278,7 @@
 
 bool CanvasState::quickRejectConservative(float left, float top,
         float right, float bottom) const {
-    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
+    if (bottom <= top || right <= left) {
         return true;
     }
 
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h
index b9e87ae..ba260d1 100644
--- a/libs/hwui/CanvasState.h
+++ b/libs/hwui/CanvasState.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_CANVAS_STATE_H
-#define ANDROID_HWUI_CANVAS_STATE_H
+#pragma once
 
 #include "Snapshot.h"
 
@@ -62,11 +61,11 @@
  * Renderer interface. Drawing and recording classes that include a CanvasState will have
  * different use cases:
  *
- * Drawing code maintaining canvas state (i.e. OpenGLRenderer) can query attributes (such as
+ * Drawing code maintaining canvas state (e.g. FrameBuilder) can query attributes (such as
  * transform) or hook into changes (e.g. save/restore) with minimal surface area for manipulating
  * the stack itself.
  *
- * Recording code maintaining canvas state (i.e. DisplayListCanvas) can both record and pass
+ * Recording code maintaining canvas state (e.g. RecordingCanvas) can both record and pass
  * through state operations to CanvasState, so that not only will querying operations work
  * (getClip/Matrix), but so that quickRejection can also be used.
  */
@@ -134,8 +133,12 @@
      */
     void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
     void setClippingRoundRect(LinearAllocator& allocator,
-            const Rect& rect, float radius, bool highPriority = true);
-    void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);
+            const Rect& rect, float radius, bool highPriority = true) {
+        mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
+    }
+    void setProjectionPathMask(const SkPath* path) {
+        mSnapshot->setProjectionPathMask(path);
+    }
 
     /**
      * Returns true if drawing in the rectangle (left, top, right, bottom)
@@ -145,19 +148,12 @@
     bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
             bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const;
 
-    void setDirtyClip(bool opaque) { mDirtyClip = opaque; }
-    bool getDirtyClip() const { return mDirtyClip; }
-
     void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
-    void setEmpty(bool value) { mSnapshot->empty = value; }
-    void setInvisible(bool value) { mSnapshot->invisible = value; }
 
     inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
     inline const Rect& currentRenderTargetClip() const { return currentSnapshot()->getRenderTargetClip(); }
-    inline Region* currentRegion() const { return currentSnapshot()->region; }
     inline int currentFlags() const { return currentSnapshot()->flags; }
     const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
-    inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
     int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
     int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
     int getWidth() const { return mWidth; }
@@ -173,10 +169,6 @@
     void freeSnapshot(Snapshot* snapshot);
     void freeAllSnapshots();
 
-    /// indicates that the clip has been changed since the last time it was consumed
-    // TODO: delete when switching to HWUI_NEW_OPS
-    bool mDirtyClip;
-
     /// Dimensions of the drawing surface
     int mWidth, mHeight;
 
@@ -201,5 +193,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_CANVAS_STATE_H
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
deleted file mode 100644
index 689179d..0000000
--- a/libs/hwui/DeferredDisplayList.cpp
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/Trace.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#include "Caches.h"
-#include "Debug.h"
-#include "DeferredDisplayList.h"
-#include "DisplayListOp.h"
-#include "OpenGLRenderer.h"
-#include "Properties.h"
-#include "utils/MathUtils.h"
-
-#if DEBUG_DEFER
-    #define DEFER_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define DEFER_LOGD(...)
-#endif
-
-namespace android {
-namespace uirenderer {
-
-// Depth of the save stack at the beginning of batch playback at flush time
-#define FLUSH_SAVE_STACK_DEPTH 2
-
-#define DEBUG_COLOR_BARRIER          0x1f000000
-#define DEBUG_COLOR_MERGEDBATCH      0x5f7f7fff
-#define DEBUG_COLOR_MERGEDBATCH_SOLO 0x5f7fff7f
-
-static bool avoidOverdraw() {
-    // Don't avoid overdraw when visualizing it, since that makes it harder to
-    // debug where it's coming from, and when the problem occurs.
-    return !Properties::debugOverdraw;
-};
-
-/////////////////////////////////////////////////////////////////////////////////
-// Operation Batches
-/////////////////////////////////////////////////////////////////////////////////
-
-class Batch {
-public:
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) = 0;
-    virtual ~Batch() {}
-    virtual bool purelyDrawBatch() { return false; }
-    virtual bool coversBounds(const Rect& bounds) { return false; }
-};
-
-class DrawBatch : public Batch {
-public:
-    explicit DrawBatch(const DeferInfo& deferInfo) : mAllOpsOpaque(true),
-            mBatchId(deferInfo.batchId), mMergeId(deferInfo.mergeId) {
-        mOps.clear();
-    }
-
-    virtual ~DrawBatch() { mOps.clear(); }
-
-    virtual void add(DrawOp* op, const DeferredDisplayState* state, bool opaqueOverBounds) {
-        // NOTE: ignore empty bounds special case, since we don't merge across those ops
-        mBounds.unionWith(state->mBounds);
-        mAllOpsOpaque &= opaqueOverBounds;
-        mOps.push_back(OpStatePair(op, state));
-    }
-
-    bool intersects(const Rect& rect) {
-        if (!rect.intersects(mBounds)) return false;
-
-        for (unsigned int i = 0; i < mOps.size(); i++) {
-            if (rect.intersects(mOps[i].state->mBounds)) {
-#if DEBUG_DEFER
-                DEFER_LOGD("op intersects with op %p with bounds %f %f %f %f:", mOps[i].op,
-                        mOps[i].state->mBounds.left, mOps[i].state->mBounds.top,
-                        mOps[i].state->mBounds.right, mOps[i].state->mBounds.bottom);
-                mOps[i].op->output(2);
-#endif
-                return true;
-            }
-        }
-        return false;
-    }
-
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) override {
-        DEFER_LOGD("%d  replaying DrawBatch %p, with %d ops (batch id %x, merge id %p)",
-                index, this, mOps.size(), getBatchId(), getMergeId());
-
-        for (unsigned int i = 0; i < mOps.size(); i++) {
-            DrawOp* op = mOps[i].op;
-            const DeferredDisplayState* state = mOps[i].state;
-            renderer.restoreDisplayState(*state);
-
-#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-            renderer.eventMark(op->name());
-#endif
-            op->applyDraw(renderer, dirty);
-
-#if DEBUG_MERGE_BEHAVIOR
-            const Rect& bounds = state->mBounds;
-            int batchColor = 0x1f000000;
-            if (getBatchId() & 0x1) batchColor |= 0x0000ff;
-            if (getBatchId() & 0x2) batchColor |= 0x00ff00;
-            if (getBatchId() & 0x4) batchColor |= 0xff0000;
-            renderer.drawScreenSpaceColorRect(bounds.left, bounds.top, bounds.right, bounds.bottom,
-                    batchColor);
-#endif
-        }
-    }
-
-    virtual bool purelyDrawBatch() override { return true; }
-
-    virtual bool coversBounds(const Rect& bounds) override {
-        if (CC_LIKELY(!mAllOpsOpaque || !mBounds.contains(bounds) || count() == 1)) return false;
-
-        Region uncovered(android::Rect(bounds.left, bounds.top, bounds.right, bounds.bottom));
-        for (unsigned int i = 0; i < mOps.size(); i++) {
-            const Rect &r = mOps[i].state->mBounds;
-            uncovered.subtractSelf(android::Rect(r.left, r.top, r.right, r.bottom));
-        }
-        return uncovered.isEmpty();
-    }
-
-    inline int getBatchId() const { return mBatchId; }
-    inline mergeid_t getMergeId() const { return mMergeId; }
-    inline int count() const { return mOps.size(); }
-
-protected:
-    std::vector<OpStatePair> mOps;
-    Rect mBounds; // union of bounds of contained ops
-private:
-    bool mAllOpsOpaque;
-    int mBatchId;
-    mergeid_t mMergeId;
-};
-
-class MergingDrawBatch : public DrawBatch {
-public:
-    MergingDrawBatch(DeferInfo& deferInfo, int width, int height) :
-            DrawBatch(deferInfo), mClipRect(width, height),
-            mClipSideFlags(kClipSide_None) {}
-
-    /*
-     * Helper for determining if a new op can merge with a MergingDrawBatch based on their bounds
-     * and clip side flags. Positive bounds delta means new bounds fit in old.
-     */
-    static inline bool checkSide(const int currentFlags, const int newFlags, const int side,
-            float boundsDelta) {
-        bool currentClipExists = currentFlags & side;
-        bool newClipExists = newFlags & side;
-
-        // if current is clipped, we must be able to fit new bounds in current
-        if (boundsDelta > 0 && currentClipExists) return false;
-
-        // if new is clipped, we must be able to fit current bounds in new
-        if (boundsDelta < 0 && newClipExists) return false;
-
-        return true;
-    }
-
-    /*
-     * Checks if a (mergeable) op can be merged into this batch
-     *
-     * If true, the op's multiDraw must be guaranteed to handle both ops simultaneously, so it is
-     * important to consider all paint attributes used in the draw calls in deciding both a) if an
-     * op tries to merge at all, and b) if the op can merge with another set of ops
-     *
-     * False positives can lead to information from the paints of subsequent merged operations being
-     * dropped, so we make simplifying qualifications on the ops that can merge, per op type.
-     */
-    bool canMergeWith(const DrawOp* op, const DeferredDisplayState* state) {
-        bool isTextBatch = getBatchId() == DeferredDisplayList::kOpBatch_Text ||
-                getBatchId() == DeferredDisplayList::kOpBatch_ColorText;
-
-        // Overlapping other operations is only allowed for text without shadow. For other ops,
-        // multiDraw isn't guaranteed to overdraw correctly
-        if (!isTextBatch || op->hasTextShadow()) {
-            if (intersects(state->mBounds)) return false;
-        }
-        const DeferredDisplayState* lhs = state;
-        const DeferredDisplayState* rhs = mOps[0].state;
-
-        if (!MathUtils::areEqual(lhs->mAlpha, rhs->mAlpha)) return false;
-
-        // Identical round rect clip state means both ops will clip in the same way, or not at all.
-        // As the state objects are const, we can compare their pointers to determine mergeability
-        if (lhs->mRoundRectClipState != rhs->mRoundRectClipState) return false;
-        if (lhs->mProjectionPathMask != rhs->mProjectionPathMask) return false;
-
-        /* Clipping compatibility check
-         *
-         * Exploits the fact that if a op or batch is clipped on a side, its bounds will equal its
-         * clip for that side.
-         */
-        const int currentFlags = mClipSideFlags;
-        const int newFlags = state->mClipSideFlags;
-        if (currentFlags != kClipSide_None || newFlags != kClipSide_None) {
-            const Rect& opBounds = state->mBounds;
-            float boundsDelta = mBounds.left - opBounds.left;
-            if (!checkSide(currentFlags, newFlags, kClipSide_Left, boundsDelta)) return false;
-            boundsDelta = mBounds.top - opBounds.top;
-            if (!checkSide(currentFlags, newFlags, kClipSide_Top, boundsDelta)) return false;
-
-            // right and bottom delta calculation reversed to account for direction
-            boundsDelta = opBounds.right - mBounds.right;
-            if (!checkSide(currentFlags, newFlags, kClipSide_Right, boundsDelta)) return false;
-            boundsDelta = opBounds.bottom - mBounds.bottom;
-            if (!checkSide(currentFlags, newFlags, kClipSide_Bottom, boundsDelta)) return false;
-        }
-
-        // if paints are equal, then modifiers + paint attribs don't need to be compared
-        if (op->mPaint == mOps[0].op->mPaint) return true;
-
-        if (PaintUtils::getAlphaDirect(op->mPaint)
-                != PaintUtils::getAlphaDirect(mOps[0].op->mPaint)) {
-            return false;
-        }
-
-        if (op->mPaint && mOps[0].op->mPaint &&
-            op->mPaint->getColorFilter() != mOps[0].op->mPaint->getColorFilter()) {
-            return false;
-        }
-
-        if (op->mPaint && mOps[0].op->mPaint &&
-            op->mPaint->getShader() != mOps[0].op->mPaint->getShader()) {
-            return false;
-        }
-
-        return true;
-    }
-
-    virtual void add(DrawOp* op, const DeferredDisplayState* state,
-            bool opaqueOverBounds) override {
-        DrawBatch::add(op, state, opaqueOverBounds);
-
-        const int newClipSideFlags = state->mClipSideFlags;
-        mClipSideFlags |= newClipSideFlags;
-        if (newClipSideFlags & kClipSide_Left) mClipRect.left = state->mClip.left;
-        if (newClipSideFlags & kClipSide_Top) mClipRect.top = state->mClip.top;
-        if (newClipSideFlags & kClipSide_Right) mClipRect.right = state->mClip.right;
-        if (newClipSideFlags & kClipSide_Bottom) mClipRect.bottom = state->mClip.bottom;
-    }
-
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) override {
-        DEFER_LOGD("%d  replaying MergingDrawBatch %p, with %d ops,"
-                " clip flags %x (batch id %x, merge id %p)",
-                index, this, mOps.size(), mClipSideFlags, getBatchId(), getMergeId());
-        if (mOps.size() == 1) {
-            DrawBatch::replay(renderer, dirty, -1);
-            return;
-        }
-
-        // clipping in the merged case is done ahead of time since all ops share the clip (if any)
-        renderer.setupMergedMultiDraw(mClipSideFlags ? &mClipRect : nullptr);
-
-        DrawOp* op = mOps[0].op;
-#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        renderer.eventMark("multiDraw");
-        renderer.eventMark(op->name());
-#endif
-        op->multiDraw(renderer, dirty, mOps, mBounds);
-
-#if DEBUG_MERGE_BEHAVIOR
-        renderer.drawScreenSpaceColorRect(mBounds.left, mBounds.top, mBounds.right, mBounds.bottom,
-                DEBUG_COLOR_MERGEDBATCH);
-#endif
-    }
-
-private:
-    /*
-     * Contains the effective clip rect shared by all merged ops. Initialized to the layer viewport,
-     * it will shrink if an op must be clipped on a certain side. The clipped sides are reflected in
-     * mClipSideFlags.
-     */
-    Rect mClipRect;
-    int mClipSideFlags;
-};
-
-class StateOpBatch : public Batch {
-public:
-    // creates a single operation batch
-    StateOpBatch(const StateOp* op, const DeferredDisplayState* state) : mOp(op), mState(state) {}
-
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) override {
-        DEFER_LOGD("replaying state op batch %p", this);
-        renderer.restoreDisplayState(*mState);
-
-        // use invalid save count because it won't be used at flush time - RestoreToCountOp is the
-        // only one to use it, and we don't use that class at flush time, instead calling
-        // renderer.restoreToCount directly
-        int saveCount = -1;
-        mOp->applyState(renderer, saveCount);
-    }
-
-private:
-    const StateOp* mOp;
-    const DeferredDisplayState* mState;
-};
-
-class RestoreToCountBatch : public Batch {
-public:
-    RestoreToCountBatch(const StateOp* op, const DeferredDisplayState* state, int restoreCount) :
-            mState(state), mRestoreCount(restoreCount) {}
-
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) override {
-        DEFER_LOGD("batch %p restoring to count %d", this, mRestoreCount);
-
-        renderer.restoreDisplayState(*mState);
-        renderer.restoreToCount(mRestoreCount);
-    }
-
-private:
-    // we use the state storage for the RestoreToCountOp, but don't replay the op itself
-    const DeferredDisplayState* mState;
-
-    /*
-     * The count used here represents the flush() time saveCount. This is as opposed to the
-     * DisplayList record time, or defer() time values (which are RestoreToCountOp's mCount, and
-     * (saveCount + mCount) respectively). Since the count is different from the original
-     * RestoreToCountOp, we don't store a pointer to the op, as elsewhere.
-     */
-    const int mRestoreCount;
-};
-
-#if DEBUG_MERGE_BEHAVIOR
-class BarrierDebugBatch : public Batch {
-    virtual void replay(OpenGLRenderer& renderer, Rect& dirty, int index) {
-        renderer.drawScreenSpaceColorRect(0, 0, 10000, 10000, DEBUG_COLOR_BARRIER);
-    }
-};
-#endif
-
-/////////////////////////////////////////////////////////////////////////////////
-// DeferredDisplayList
-/////////////////////////////////////////////////////////////////////////////////
-
-void DeferredDisplayList::resetBatchingState() {
-    for (int i = 0; i < kOpBatch_Count; i++) {
-        mBatchLookup[i] = nullptr;
-        mMergingBatches[i].clear();
-    }
-#if DEBUG_MERGE_BEHAVIOR
-    if (mBatches.size() != 0) {
-        mBatches.add(new BarrierDebugBatch());
-    }
-#endif
-    mEarliestBatchIndex = mBatches.size();
-}
-
-void DeferredDisplayList::clear() {
-    resetBatchingState();
-    mComplexClipStackStart = -1;
-
-    for (unsigned int i = 0; i < mBatches.size(); i++) {
-        delete mBatches[i];
-    }
-    mBatches.clear();
-    mSaveStack.clear();
-    mEarliestBatchIndex = 0;
-    mEarliestUnclearedIndex = 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Operation adding
-/////////////////////////////////////////////////////////////////////////////////
-
-int DeferredDisplayList::getStateOpDeferFlags() const {
-    // For both clipOp and save(Layer)Op, we don't want to save drawing info, and only want to save
-    // the clip if we aren't recording a complex clip (and can thus trust it to be a rect)
-    return recordingComplexClip() ? 0 : kStateDeferFlag_Clip;
-}
-
-int DeferredDisplayList::getDrawOpDeferFlags() const {
-    return kStateDeferFlag_Draw | getStateOpDeferFlags();
-}
-
-/**
- * When an clipping operation occurs that could cause a complex clip, record the operation and all
- * subsequent clipOps, save/restores (if the clip flag is set). During a flush, instead of loading
- * the clip from deferred state, we play back all of the relevant state operations that generated
- * the complex clip.
- *
- * Note that we don't need to record the associated restore operation, since operations at defer
- * time record whether they should store the renderer's current clip
- */
-void DeferredDisplayList::addClip(OpenGLRenderer& renderer, ClipOp* op) {
-    if (recordingComplexClip() || op->canCauseComplexClip() || !renderer.hasRectToRectTransform()) {
-        DEFER_LOGD("%p Received complex clip operation %p", this, op);
-
-        // NOTE: defer clip op before setting mComplexClipStackStart so previous clip is recorded
-        storeStateOpBarrier(renderer, op);
-
-        if (!recordingComplexClip()) {
-            mComplexClipStackStart = renderer.getSaveCount() - 1;
-            DEFER_LOGD("    Starting complex clip region, start is %d", mComplexClipStackStart);
-        }
-    }
-}
-
-/**
- * For now, we record save layer operations as barriers in the batch list, preventing drawing
- * operations from reordering around the saveLayer and it's associated restore()
- *
- * In the future, we should send saveLayer commands (if they can be played out of order) and their
- * contained drawing operations to a seperate list of batches, so that they may draw at the
- * beginning of the frame. This would avoid targetting and removing an FBO in the middle of a frame.
- *
- * saveLayer operations should be pulled to the beginning of the frame if the canvas doesn't have a
- * complex clip, and if the flags (SaveFlags::Clip & SaveFlags::ClipToLayer) are set.
- */
-void DeferredDisplayList::addSaveLayer(OpenGLRenderer& renderer,
-        SaveLayerOp* op, int newSaveCount) {
-    DEFER_LOGD("%p adding saveLayerOp %p, flags %x, new count %d",
-            this, op, op->getFlags(), newSaveCount);
-
-    storeStateOpBarrier(renderer, op);
-    mSaveStack.push_back(newSaveCount);
-}
-
-/**
- * Takes save op and it's return value - the new save count - and stores it into the stream as a
- * barrier if it's needed to properly modify a complex clip
- */
-void DeferredDisplayList::addSave(OpenGLRenderer& renderer, SaveOp* op, int newSaveCount) {
-    int saveFlags = op->getFlags();
-    DEFER_LOGD("%p adding saveOp %p, flags %x, new count %d", this, op, saveFlags, newSaveCount);
-
-    if (recordingComplexClip() && (saveFlags & SaveFlags::Clip)) {
-        // store and replay the save operation, as it may be needed to correctly playback the clip
-        DEFER_LOGD("    adding save barrier with new save count %d", newSaveCount);
-        storeStateOpBarrier(renderer, op);
-        mSaveStack.push_back(newSaveCount);
-    }
-}
-
-/**
- * saveLayer() commands must be associated with a restoreToCount batch that will clean up and draw
- * the layer in the deferred list
- *
- * other save() commands which occur as children of a snapshot with complex clip will be deferred,
- * and must be restored
- *
- * Either will act as a barrier to draw operation reordering, as we want to play back layer
- * save/restore and complex canvas modifications (including save/restore) in order.
- */
-void DeferredDisplayList::addRestoreToCount(OpenGLRenderer& renderer, StateOp* op,
-        int newSaveCount) {
-    DEFER_LOGD("%p addRestoreToCount %d", this, newSaveCount);
-
-    if (recordingComplexClip() && newSaveCount <= mComplexClipStackStart) {
-        mComplexClipStackStart = -1;
-        resetBatchingState();
-    }
-
-    if (mSaveStack.empty() || newSaveCount > mSaveStack.back()) {
-        return;
-    }
-
-    while (!mSaveStack.empty() && mSaveStack.back() >= newSaveCount) mSaveStack.pop_back();
-
-    storeRestoreToCountBarrier(renderer, op, mSaveStack.size() + FLUSH_SAVE_STACK_DEPTH);
-}
-
-void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
-    /* 1: op calculates local bounds */
-    DeferredDisplayState* const state = createState();
-    if (op->getLocalBounds(state->mBounds)) {
-        if (state->mBounds.isEmpty()) {
-            // valid empty bounds, don't bother deferring
-            tryRecycleState(state);
-            return;
-        }
-    } else {
-        state->mBounds.setEmpty();
-    }
-
-    /* 2: renderer calculates global bounds + stores state */
-    if (renderer.storeDisplayState(*state, getDrawOpDeferFlags())) {
-        tryRecycleState(state);
-        return; // quick rejected
-    }
-
-    /* 3: ask op for defer info, given renderer state */
-    DeferInfo deferInfo;
-    op->onDefer(renderer, deferInfo, *state);
-
-    // complex clip has a complex set of expectations on the renderer state - for now, avoid taking
-    // the merge path in those cases
-    deferInfo.mergeable &= !recordingComplexClip();
-    deferInfo.opaqueOverBounds &= !recordingComplexClip()
-            && mSaveStack.empty()
-            && !state->mRoundRectClipState;
-
-    if (CC_LIKELY(avoidOverdraw()) && mBatches.size() &&
-            state->mClipSideFlags != kClipSide_ConservativeFull &&
-            deferInfo.opaqueOverBounds && state->mBounds.contains(mBounds)) {
-        // avoid overdraw by resetting drawing state + discarding drawing ops
-        discardDrawingBatches(mBatches.size() - 1);
-        resetBatchingState();
-    }
-
-    if (CC_UNLIKELY(Properties::drawReorderDisabled)) {
-        // TODO: elegant way to reuse batches?
-        DrawBatch* b = new DrawBatch(deferInfo);
-        b->add(op, state, deferInfo.opaqueOverBounds);
-        mBatches.push_back(b);
-        return;
-    }
-
-    // find the latest batch of the new op's type, and try to merge the new op into it
-    DrawBatch* targetBatch = nullptr;
-
-    // insertion point of a new batch, will hopefully be immediately after similar batch
-    // (eventually, should be similar shader)
-    int insertBatchIndex = mBatches.size();
-    if (!mBatches.empty()) {
-        if (state->mBounds.isEmpty()) {
-            // don't know the bounds for op, so create new batch and start from scratch on next op
-            DrawBatch* b = new DrawBatch(deferInfo);
-            b->add(op, state, deferInfo.opaqueOverBounds);
-            mBatches.push_back(b);
-            resetBatchingState();
-#if DEBUG_DEFER
-            DEFER_LOGD("Warning: Encountered op with empty bounds, resetting batches");
-            op->output(2);
-#endif
-            return;
-        }
-
-        if (deferInfo.mergeable) {
-            // Try to merge with any existing batch with same mergeId.
-            std::unordered_map<mergeid_t, DrawBatch*>& mergingBatch
-                    = mMergingBatches[deferInfo.batchId];
-            auto getResult = mergingBatch.find(deferInfo.mergeId);
-            if (getResult != mergingBatch.end()) {
-                targetBatch = getResult->second;
-                if (!((MergingDrawBatch*) targetBatch)->canMergeWith(op, state)) {
-                    targetBatch = nullptr;
-                }
-            }
-        } else {
-            // join with similar, non-merging batch
-            targetBatch = (DrawBatch*)mBatchLookup[deferInfo.batchId];
-        }
-
-        if (targetBatch || deferInfo.mergeable) {
-            // iterate back toward target to see if anything drawn since should overlap the new op
-            // if no target, merging ops still interate to find similar batch to insert after
-            for (int i = mBatches.size() - 1; i >= mEarliestBatchIndex; i--) {
-                DrawBatch* overBatch = (DrawBatch*)mBatches[i];
-
-                if (overBatch == targetBatch) break;
-
-                // TODO: also consider shader shared between batch types
-                if (deferInfo.batchId == overBatch->getBatchId()) {
-                    insertBatchIndex = i + 1;
-                    if (!targetBatch) break; // found insert position, quit
-                }
-
-                if (overBatch->intersects(state->mBounds)) {
-                    // NOTE: it may be possible to optimize for special cases where two operations
-                    // of the same batch/paint could swap order, such as with a non-mergeable
-                    // (clipped) and a mergeable text operation
-                    targetBatch = nullptr;
-#if DEBUG_DEFER
-                    DEFER_LOGD("op couldn't join batch %p, was intersected by batch %d",
-                            targetBatch, i);
-                    op->output(2);
-#endif
-                    break;
-                }
-            }
-        }
-    }
-
-    if (!targetBatch) {
-        if (deferInfo.mergeable) {
-            targetBatch = new MergingDrawBatch(deferInfo,
-                    renderer.getViewportWidth(), renderer.getViewportHeight());
-            mMergingBatches[deferInfo.batchId].insert(
-                    std::make_pair(deferInfo.mergeId, targetBatch));
-        } else {
-            targetBatch = new DrawBatch(deferInfo);
-            mBatchLookup[deferInfo.batchId] = targetBatch;
-        }
-
-        DEFER_LOGD("creating %singBatch %p, bid %x, at %d",
-                deferInfo.mergeable ? "Merg" : "Draw",
-                targetBatch, deferInfo.batchId, insertBatchIndex);
-        mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch);
-    }
-
-    targetBatch->add(op, state, deferInfo.opaqueOverBounds);
-}
-
-void DeferredDisplayList::storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op) {
-    DEFER_LOGD("%p adding state op barrier at pos %d", this, mBatches.size());
-
-    DeferredDisplayState* state = createState();
-    renderer.storeDisplayState(*state, getStateOpDeferFlags());
-    mBatches.push_back(new StateOpBatch(op, state));
-    resetBatchingState();
-}
-
-void DeferredDisplayList::storeRestoreToCountBarrier(OpenGLRenderer& renderer, StateOp* op,
-        int newSaveCount) {
-    DEFER_LOGD("%p adding restore to count %d barrier, pos %d",
-            this, newSaveCount, mBatches.size());
-
-    // store displayState for the restore operation, as it may be associated with a saveLayer that
-    // doesn't have SaveFlags::Clip set
-    DeferredDisplayState* state = createState();
-    renderer.storeDisplayState(*state, getStateOpDeferFlags());
-    mBatches.push_back(new RestoreToCountBatch(op, state, newSaveCount));
-    resetBatchingState();
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-// Replay / flush
-/////////////////////////////////////////////////////////////////////////////////
-
-static void replayBatchList(const std::vector<Batch*>& batchList,
-        OpenGLRenderer& renderer, Rect& dirty) {
-
-    for (unsigned int i = 0; i < batchList.size(); i++) {
-        if (batchList[i]) {
-            batchList[i]->replay(renderer, dirty, i);
-        }
-    }
-    DEFER_LOGD("--flushed, drew %d batches", batchList.size());
-}
-
-void DeferredDisplayList::flush(OpenGLRenderer& renderer, Rect& dirty) {
-    ATRACE_NAME("flush drawing commands");
-    Caches::getInstance().fontRenderer.endPrecaching();
-
-    if (isEmpty()) return; // nothing to flush
-    renderer.restoreToCount(1);
-
-    DEFER_LOGD("--flushing");
-    renderer.eventMark("Flush");
-
-    // save and restore so that reordering doesn't affect final state
-    renderer.save(SaveFlags::MatrixClip);
-
-    if (CC_LIKELY(avoidOverdraw())) {
-        for (unsigned int i = 1; i < mBatches.size(); i++) {
-            if (mBatches[i] && mBatches[i]->coversBounds(mBounds)) {
-                discardDrawingBatches(i - 1);
-            }
-        }
-    }
-    // NOTE: depth of the save stack at this point, before playback, should be reflected in
-    // FLUSH_SAVE_STACK_DEPTH, so that save/restores match up correctly
-    replayBatchList(mBatches, renderer, dirty);
-
-    renderer.restoreToCount(1);
-
-    DEFER_LOGD("--flush complete, returning %x", status);
-    clear();
-}
-
-void DeferredDisplayList::discardDrawingBatches(const unsigned int maxIndex) {
-    for (unsigned int i = mEarliestUnclearedIndex; i <= maxIndex; i++) {
-        // leave deferred state ops alone for simplicity (empty save restore pairs may now exist)
-        if (mBatches[i] && mBatches[i]->purelyDrawBatch()) {
-            delete mBatches[i];
-            mBatches[i] = nullptr;
-        }
-    }
-    mEarliestUnclearedIndex = maxIndex + 1;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
deleted file mode 100644
index 98ccf11..0000000
--- a/libs/hwui/DeferredDisplayList.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H
-#define ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H
-
-#include <unordered_map>
-
-#include <utils/Errors.h>
-#include <utils/LinearAllocator.h>
-
-#include "Matrix.h"
-#include "OpenGLRenderer.h"
-#include "Rect.h"
-
-#include <vector>
-
-class SkBitmap;
-
-namespace android {
-namespace uirenderer {
-
-class ClipOp;
-class DrawOp;
-class SaveOp;
-class SaveLayerOp;
-class StateOp;
-
-class DeferredDisplayState;
-
-class Batch;
-class DrawBatch;
-class MergingDrawBatch;
-
-typedef const void* mergeid_t;
-
-class DeferredDisplayState {
-public:
-    // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped
-    Rect mBounds;
-
-    // the below are set and used by the OpenGLRenderer at record and deferred playback
-    bool mClipValid;
-    Rect mClip;
-    int mClipSideFlags; // specifies which sides of the bounds are clipped, unclipped if cleared
-    mat4 mMatrix;
-    float mAlpha;
-    const RoundRectClipState* mRoundRectClipState;
-    const ProjectionPathMask* mProjectionPathMask;
-};
-
-class OpStatePair {
-public:
-    OpStatePair()
-            : op(nullptr), state(nullptr) {}
-    OpStatePair(DrawOp* newOp, const DeferredDisplayState* newState)
-            : op(newOp), state(newState) {}
-    OpStatePair(const OpStatePair& other)
-            : op(other.op), state(other.state) {}
-    DrawOp* op;
-    const DeferredDisplayState* state;
-};
-
-class DeferredDisplayList {
-    friend struct DeferStateStruct; // used to give access to allocator
-public:
-    DeferredDisplayList(const Rect& bounds)
-            : mBounds(bounds) {
-        clear();
-    }
-    ~DeferredDisplayList() { clear(); }
-
-    enum OpBatchId {
-        kOpBatch_None = 0, // Don't batch
-        kOpBatch_Bitmap,
-        kOpBatch_Patch,
-        kOpBatch_AlphaVertices,
-        kOpBatch_Vertices,
-        kOpBatch_AlphaMaskTexture,
-        kOpBatch_Text,
-        kOpBatch_ColorText,
-
-        kOpBatch_Count, // Add other batch ids before this
-    };
-
-    bool isEmpty() { return mBatches.empty(); }
-
-    /**
-     * Plays back all of the draw ops recorded into batches to the renderer.
-     * Adjusts the state of the renderer as necessary, and restores it when complete
-     */
-    void flush(OpenGLRenderer& renderer, Rect& dirty);
-
-    void addClip(OpenGLRenderer& renderer, ClipOp* op);
-    void addSaveLayer(OpenGLRenderer& renderer, SaveLayerOp* op, int newSaveCount);
-    void addSave(OpenGLRenderer& renderer, SaveOp* op, int newSaveCount);
-    void addRestoreToCount(OpenGLRenderer& renderer, StateOp* op, int newSaveCount);
-
-    /**
-     * Add a draw op into the DeferredDisplayList, reordering as needed (for performance) if
-     * disallowReorder is false, respecting draw order when overlaps occur.
-     */
-    void addDrawOp(OpenGLRenderer& renderer, DrawOp* op);
-
-private:
-    DeferredDisplayList(const DeferredDisplayList& other); // disallow copy
-
-    DeferredDisplayState* createState() {
-        return mAllocator.create_trivial<DeferredDisplayState>();
-    }
-
-    void tryRecycleState(DeferredDisplayState* state) {
-        mAllocator.rewindIfLastAlloc(state);
-    }
-
-    /**
-     * Resets the batching back-pointers, creating a barrier in the operation stream so that no ops
-     * added in the future will be inserted into a batch that already exist.
-     */
-    void resetBatchingState();
-
-    void clear();
-
-    void storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op);
-    void storeRestoreToCountBarrier(OpenGLRenderer& renderer, StateOp* op, int newSaveCount);
-
-    bool recordingComplexClip() const { return mComplexClipStackStart >= 0; }
-
-    int getStateOpDeferFlags() const;
-    int getDrawOpDeferFlags() const;
-
-    void discardDrawingBatches(const unsigned int maxIndex);
-
-    // layer space bounds of rendering
-    Rect mBounds;
-
-    /**
-     * At defer time, stores the *defer time* savecount of save/saveLayer ops that were deferred, so
-     * that when an associated restoreToCount is deferred, it can be recorded as a
-     * RestoreToCountBatch
-     */
-    std::vector<int> mSaveStack;
-    int mComplexClipStackStart;
-
-    std::vector<Batch*> mBatches;
-
-    // Maps batch ids to the most recent *non-merging* batch of that id
-    Batch* mBatchLookup[kOpBatch_Count];
-
-    // Points to the index after the most recent barrier
-    int mEarliestBatchIndex;
-
-    // Points to the first index that may contain a pure drawing batch
-    int mEarliestUnclearedIndex;
-
-    /**
-     * Maps the mergeid_t returned by an op's getMergeId() to the most recently seen
-     * MergingDrawBatch of that id. These ids are unique per draw type and guaranteed to not
-     * collide, which avoids the need to resolve mergeid collisions.
-     */
-    std::unordered_map<mergeid_t, DrawBatch*> mMergingBatches[kOpBatch_Count];
-
-    LinearAllocator mAllocator;
-};
-
-/**
- * Struct containing information that instructs the defer
- */
-struct DeferInfo {
-public:
-    DeferInfo() :
-            batchId(DeferredDisplayList::kOpBatch_None),
-            mergeId((mergeid_t) -1),
-            mergeable(false),
-            opaqueOverBounds(false) {
-    };
-
-    int batchId;
-    mergeid_t mergeId;
-    bool mergeable;
-    bool opaqueOverBounds; // opaque over bounds in DeferredDisplayState - can skip ops below
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_DEFERRED_DISPLAY_LIST_H
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index f833a54..f13cb8d 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -15,11 +15,10 @@
  */
 #include "DeferredLayerUpdater.h"
 
-#include "OpenGLRenderer.h"
-
 #include "LayerRenderer.h"
 #include "renderthread/EglManager.h"
 #include "renderthread/RenderTask.h"
+#include "utils/PaintUtils.h"
 
 namespace android {
 namespace uirenderer {
@@ -29,8 +28,7 @@
         , mTransform(nullptr)
         , mNeedsGLContextAttach(false)
         , mUpdateTexImage(false)
-        , mLayer(layer)
-        , mCaches(Caches::getInstance()) {
+        , mLayer(layer) {
     mWidth = mLayer->layer.getWidth();
     mHeight = mLayer->layer.getHeight();
     mBlend = mLayer->isBlend();
@@ -54,7 +52,6 @@
 }
 
 void DeferredLayerUpdater::apply() {
-    // These properties are applied the same to both layer types
     mLayer->setColorFilter(mColorFilter);
     mLayer->setAlpha(mAlpha, mMode);
 
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 44a24c8..389e17d 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef DEFERREDLAYERUPDATE_H_
-#define DEFERREDLAYERUPDATE_H_
+
+#pragma once
 
 #include <cutils/compiler.h>
 #include <gui/GLConsumer.h>
@@ -100,19 +100,15 @@
     SkColorFilter* mColorFilter;
     int mAlpha;
     SkXfermode::Mode mMode;
-
     sp<GLConsumer> mSurfaceTexture;
     SkMatrix* mTransform;
     bool mNeedsGLContextAttach;
     bool mUpdateTexImage;
 
     Layer* mLayer;
-    Caches& mCaches;
 
     void doUpdateTexImage();
 };
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* DEFERREDLAYERUPDATE_H_ */
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index 28be05c..ca9e2bd 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -21,13 +21,8 @@
 
 #include "Debug.h"
 #include "DisplayList.h"
-#include "RenderNode.h"
-
-#if HWUI_NEW_OPS
 #include "RecordedOp.h"
-#else
-#include "DisplayListOp.h"
-#endif
+#include "RenderNode.h"
 
 namespace android {
 namespace uirenderer {
@@ -45,8 +40,7 @@
         , regions(stdAllocator)
         , referenceHolders(stdAllocator)
         , functors(stdAllocator)
-        , vectorDrawables(stdAllocator)
-        , hasDrawOps(false) {
+        , vectorDrawables(stdAllocator) {
 }
 
 DisplayList::~DisplayList() {
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index ccf71c6..a8205c8 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_DISPLAY_LIST_H
-#define ANDROID_HWUI_DISPLAY_LIST_H
+#pragma once
 
 #include <SkCamera.h>
 #include <SkMatrix.h>
@@ -34,7 +33,6 @@
 
 #include "Debug.h"
 #include "CanvasProperty.h"
-#include "DeferredDisplayList.h"
 #include "GlFunctorLifecycleListener.h"
 #include "Matrix.h"
 #include "RenderProperties.h"
@@ -49,72 +47,20 @@
 namespace android {
 namespace uirenderer {
 
-class DeferredDisplayList;
-class DisplayListOp;
-class DisplayListCanvas;
-class OpenGLRenderer;
 class Rect;
 class Layer;
 
-#if HWUI_NEW_OPS
 struct RecordedOp;
 struct RenderNodeOp;
 
 typedef RecordedOp BaseOpType;
 typedef RenderNodeOp NodeOpType;
-#else
-class DrawRenderNodeOp;
-
-typedef DisplayListOp BaseOpType;
-typedef DrawRenderNodeOp NodeOpType;
-#endif
 
 namespace VectorDrawable {
 class Tree;
 };
 typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
 
-/**
- * Holds data used in the playback a tree of DisplayLists.
- */
-struct PlaybackStateStruct {
-protected:
-    PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator)
-            : mRenderer(renderer)
-            , mReplayFlags(replayFlags)
-            , mAllocator(allocator) {}
-
-public:
-    OpenGLRenderer& mRenderer;
-    const int mReplayFlags;
-
-    // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
-    // while defer shares the DeferredDisplayList's Allocator
-    // TODO: move this allocator to be owned by object with clear frame lifecycle
-    LinearAllocator * const mAllocator;
-
-    SkPath* allocPathForFrame() {
-        return mRenderer.allocPathForFrame();
-    }
-};
-
-struct DeferStateStruct : public PlaybackStateStruct {
-    DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
-            : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)),
-            mDeferredList(deferredList) {}
-
-    DeferredDisplayList& mDeferredList;
-};
-
-struct ReplayStateStruct : public PlaybackStateStruct {
-    ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
-            : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator),
-            mDirty(dirty) {}
-
-    Rect& mDirty;
-    LinearAllocator mReplayAllocator;
-};
-
 struct FunctorContainer {
     Functor* functor;
     GlFunctorLifecycleListener* listener;
@@ -124,7 +70,6 @@
  * Data structure that holds the list of commands used in display list stream
  */
 class DisplayList {
-    friend class DisplayListCanvas;
     friend class RecordingCanvas;
 public:
     struct Chunk {
@@ -138,9 +83,9 @@
 
         // whether children with non-zero Z in the chunk should be reordered
         bool reorderChildren;
-#if HWUI_NEW_OPS
+
+        // clip at the beginning of a reorder section, applied to reordered children
         const ClipBase* reorderClip;
-#endif
     };
 
     DisplayList();
@@ -169,11 +114,7 @@
         return allocator.usedSize();
     }
     bool isEmpty() {
-#if HWUI_NEW_OPS
         return ops.empty();
-#else
-        return !hasDrawOps;
-#endif
     }
 
 private:
@@ -203,12 +144,8 @@
     // gets special treatment exclusive for webview.
     LsaVector<VectorDrawableRoot*> vectorDrawables;
 
-    bool hasDrawOps; // only used if !HWUI_NEW_OPS
-
     void cleanupResources();
 };
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_OPENGL_RENDERER_H
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
deleted file mode 100644
index bec66295..0000000
--- a/libs/hwui/DisplayListCanvas.cpp
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "DisplayListCanvas.h"
-
-#include "DeferredDisplayList.h"
-#include "DeferredLayerUpdater.h"
-#include "DisplayListOp.h"
-#include "ResourceCache.h"
-#include "RenderNode.h"
-#include "VectorDrawable.h"
-#include "utils/PaintUtils.h"
-
-#include <SkCamera.h>
-#include <SkCanvas.h>
-
-#include <private/hwui/DrawGlInfo.h>
-
-namespace android {
-namespace uirenderer {
-
-DisplayListCanvas::DisplayListCanvas(int width, int height)
-    : mState(*this)
-    , mResourceCache(ResourceCache::getInstance())
-    , mDisplayList(nullptr)
-    , mTranslateX(0.0f)
-    , mTranslateY(0.0f)
-    , mHasDeferredTranslate(false)
-    , mDeferredBarrierType(kBarrier_None)
-    , mHighContrastText(false)
-    , mRestoreSaveCount(-1) {
-    resetRecording(width, height);
-}
-
-DisplayListCanvas::~DisplayListCanvas() {
-    LOG_ALWAYS_FATAL_IF(mDisplayList,
-            "Destroyed a DisplayListCanvas during a record!");
-}
-
-void DisplayListCanvas::resetRecording(int width, int height) {
-    LOG_ALWAYS_FATAL_IF(mDisplayList,
-            "prepareDirty called a second time during a recording!");
-    mDisplayList = new DisplayList();
-
-    mState.initializeSaveStack(width, height,
-            0, 0, width, height, Vector3());
-
-    mDeferredBarrierType = kBarrier_InOrder;
-    mState.setDirtyClip(false);
-    mRestoreSaveCount = -1;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Operations
-///////////////////////////////////////////////////////////////////////////////
-
-DisplayList* DisplayListCanvas::finishRecording() {
-    flushRestoreToCount();
-    flushTranslate();
-
-    mPaintMap.clear();
-    mRegionMap.clear();
-    mPathMap.clear();
-    DisplayList* displayList = mDisplayList;
-    mDisplayList = nullptr;
-    mSkiaCanvasProxy.reset(nullptr);
-    return displayList;
-}
-
-void DisplayListCanvas::callDrawGLFunction(Functor* functor,
-        GlFunctorLifecycleListener* listener) {
-    addDrawOp(new (alloc()) DrawFunctorOp(functor));
-    mDisplayList->functors.push_back({functor, listener});
-    mDisplayList->ref(listener);
-}
-
-SkCanvas* DisplayListCanvas::asSkCanvas() {
-    LOG_ALWAYS_FATAL_IF(!mDisplayList,
-            "attempting to get an SkCanvas when we are not recording!");
-    if (!mSkiaCanvasProxy) {
-        mSkiaCanvasProxy.reset(new SkiaCanvasProxy(this));
-    }
-
-    // SkCanvas instances default to identity transform, but should inherit
-    // the state of this Canvas; if this code was in the SkiaCanvasProxy
-    // constructor, we couldn't cache mSkiaCanvasProxy.
-    SkMatrix parentTransform;
-    getMatrix(&parentTransform);
-    mSkiaCanvasProxy.get()->setMatrix(parentTransform);
-
-    return mSkiaCanvasProxy.get();
-}
-
-int DisplayListCanvas::save(SaveFlags::Flags flags) {
-    addStateOp(new (alloc()) SaveOp((int) flags));
-    return mState.save((int) flags);
-}
-
-void DisplayListCanvas::restore() {
-    if (mRestoreSaveCount < 0) {
-        restoreToCount(getSaveCount() - 1);
-        return;
-    }
-
-    mRestoreSaveCount--;
-    flushTranslate();
-    mState.restore();
-}
-
-void DisplayListCanvas::restoreToCount(int saveCount) {
-    mRestoreSaveCount = saveCount;
-    flushTranslate();
-    mState.restoreToCount(saveCount);
-}
-
-int DisplayListCanvas::saveLayer(float left, float top, float right, float bottom,
-        const SkPaint* paint, SaveFlags::Flags flags) {
-    // force matrix/clip isolation for layer
-    flags |= SaveFlags::MatrixClip;
-
-    paint = refPaint(paint);
-    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, (int) flags));
-    return mState.save((int) flags);
-}
-
-void DisplayListCanvas::translate(float dx, float dy) {
-    if (dx == 0.0f && dy == 0.0f) return;
-
-    mHasDeferredTranslate = true;
-    mTranslateX += dx;
-    mTranslateY += dy;
-    flushRestoreToCount();
-    mState.translate(dx, dy, 0.0f);
-}
-
-void DisplayListCanvas::rotate(float degrees) {
-    if (degrees == 0.0f) return;
-
-    addStateOp(new (alloc()) RotateOp(degrees));
-    mState.rotate(degrees);
-}
-
-void DisplayListCanvas::scale(float sx, float sy) {
-    if (sx == 1.0f && sy == 1.0f) return;
-
-    addStateOp(new (alloc()) ScaleOp(sx, sy));
-    mState.scale(sx, sy);
-}
-
-void DisplayListCanvas::skew(float sx, float sy) {
-    addStateOp(new (alloc()) SkewOp(sx, sy));
-    mState.skew(sx, sy);
-}
-
-void DisplayListCanvas::setMatrix(const SkMatrix& matrix) {
-    addStateOp(new (alloc()) SetMatrixOp(matrix));
-    mState.setMatrix(matrix);
-}
-
-void DisplayListCanvas::concat(const SkMatrix& matrix) {
-    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
-    mState.concatMatrix(matrix);
-}
-
-bool DisplayListCanvas::getClipBounds(SkRect* outRect) const {
-    Rect bounds = mState.getLocalClipBounds();
-    *outRect = SkRect::MakeLTRB(bounds.left, bounds.top, bounds.right, bounds.bottom);
-    return !(outRect->isEmpty());
-}
-
-bool DisplayListCanvas::quickRejectRect(float left, float top, float right, float bottom) const {
-    return mState.quickRejectConservative(left, top, right, bottom);
-}
-
-bool DisplayListCanvas::quickRejectPath(const SkPath& path) const {
-    SkRect bounds = path.getBounds();
-    return mState.quickRejectConservative(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
-}
-
-
-bool DisplayListCanvas::clipRect(float left, float top, float right, float bottom,
-        SkRegion::Op op) {
-    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
-    return mState.clipRect(left, top, right, bottom, op);
-}
-
-bool DisplayListCanvas::clipPath(const SkPath* path, SkRegion::Op op) {
-    path = refPath(path);
-    addStateOp(new (alloc()) ClipPathOp(path, op));
-    return mState.clipPath(path, op);
-}
-
-bool DisplayListCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
-    region = refRegion(region);
-    addStateOp(new (alloc()) ClipRegionOp(region, op));
-    return mState.clipRegion(region, op);
-}
-
-void DisplayListCanvas::drawRenderNode(RenderNode* renderNode) {
-    LOG_ALWAYS_FATAL_IF(!renderNode, "missing rendernode");
-    DrawRenderNodeOp* op = new (alloc()) DrawRenderNodeOp(
-            renderNode,
-            *mState.currentTransform(),
-            mState.clipIsSimple());
-    addRenderNodeOp(op);
-}
-
-void DisplayListCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
-    // We ref the DeferredLayerUpdater due to its thread-safe ref-counting
-    // semantics.
-    mDisplayList->ref(layerHandle);
-    addDrawOp(new (alloc()) DrawLayerOp(layerHandle->backingLayer()));
-}
-
-void DisplayListCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
-    bitmap = refBitmap(*bitmap);
-    paint = refPaint(paint);
-
-    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, paint));
-}
-
-void DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float left, float top,
-        const SkPaint* paint) {
-    save(SaveFlags::Matrix);
-    translate(left, top);
-    drawBitmap(&bitmap, paint);
-    restore();
-}
-
-void DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
-        const SkPaint* paint) {
-    if (matrix.isIdentity()) {
-        drawBitmap(&bitmap, paint);
-    } else if (!(matrix.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask))
-            && MathUtils::isPositive(matrix.getScaleX())
-            && MathUtils::isPositive(matrix.getScaleY())) {
-        // SkMatrix::isScaleTranslate() not available in L
-        SkRect src;
-        SkRect dst;
-        bitmap.getBounds(&src);
-        matrix.mapRect(&dst, src);
-        drawBitmap(bitmap, src.fLeft, src.fTop, src.fRight, src.fBottom,
-                   dst.fLeft, dst.fTop, dst.fRight, dst.fBottom, paint);
-    } else {
-        save(SaveFlags::Matrix);
-        concat(matrix);
-        drawBitmap(&bitmap, paint);
-        restore();
-    }
-}
-
-void DisplayListCanvas::drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
-        float srcRight, float srcBottom, float dstLeft, float dstTop,
-        float dstRight, float dstBottom, const SkPaint* paint) {
-    if (srcLeft == 0 && srcTop == 0
-            && srcRight == bitmap.width()
-            && srcBottom == bitmap.height()
-            && (srcBottom - srcTop == dstBottom - dstTop)
-            && (srcRight - srcLeft == dstRight - dstLeft)) {
-        // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        save(SaveFlags::Matrix);
-        translate(dstLeft, dstTop);
-        drawBitmap(&bitmap, paint);
-        restore();
-    } else {
-        paint = refPaint(paint);
-
-        if (paint && paint->getShader()) {
-            float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
-            float scaleY = (dstBottom - dstTop) / (srcBottom - srcTop);
-            if (!MathUtils::areEqual(scaleX, 1.0f) || !MathUtils::areEqual(scaleY, 1.0f)) {
-                // Apply the scale transform on the canvas, so that the shader
-                // effectively calculates positions relative to src rect space
-
-                save(SaveFlags::Matrix);
-                translate(dstLeft, dstTop);
-                scale(scaleX, scaleY);
-
-                dstLeft = 0.0f;
-                dstTop = 0.0f;
-                dstRight = srcRight - srcLeft;
-                dstBottom = srcBottom - srcTop;
-
-                addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
-                        srcLeft, srcTop, srcRight, srcBottom,
-                        dstLeft, dstTop, dstRight, dstBottom, paint));
-                restore();
-                return;
-            }
-        }
-
-        addDrawOp(new (alloc()) DrawBitmapRectOp(refBitmap(bitmap),
-                srcLeft, srcTop, srcRight, srcBottom,
-                dstLeft, dstTop, dstRight, dstBottom, paint));
-    }
-}
-
-void DisplayListCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
-        const float* vertices, const int* colors, const SkPaint* paint) {
-    int vertexCount = (meshWidth + 1) * (meshHeight + 1);
-    vertices = refBuffer<float>(vertices, vertexCount * 2); // 2 floats per vertex
-    paint = refPaint(paint);
-    colors = refBuffer<int>(colors, vertexCount); // 1 color per vertex
-
-    addDrawOp(new (alloc()) DrawBitmapMeshOp(refBitmap(bitmap), meshWidth, meshHeight,
-           vertices, colors, paint));
-}
-
-void DisplayListCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& patch,
-        float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
-    const SkBitmap* bitmapPtr = refBitmap(bitmap);
-    const Res_png_9patch* patchPtr = refPatch(&patch);
-    paint = refPaint(paint);
-
-    addDrawOp(new (alloc()) DrawPatchOp(bitmapPtr, patchPtr,
-            dstLeft, dstTop, dstRight, dstBottom, paint));
-}
-
-void DisplayListCanvas::drawColor(int color, SkXfermode::Mode mode) {
-    addDrawOp(new (alloc()) DrawColorOp(color, mode));
-}
-
-void DisplayListCanvas::drawPaint(const SkPaint& paint) {
-    SkRect bounds;
-    if (getClipBounds(&bounds)) {
-        drawRect(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, paint);
-    }
-}
-
-
-void DisplayListCanvas::drawRect(float left, float top, float right, float bottom,
-        const SkPaint& paint) {
-    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, const SkPaint& paint) {
-    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawRoundRect(
-        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
-        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
-        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-        CanvasPropertyPaint* paint) {
-    mDisplayList->ref(left);
-    mDisplayList->ref(top);
-    mDisplayList->ref(right);
-    mDisplayList->ref(bottom);
-    mDisplayList->ref(rx);
-    mDisplayList->ref(ry);
-    mDisplayList->ref(paint);
-    refBitmapsInShader(paint->value.getShader());
-    addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
-            &right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
-}
-
-void DisplayListCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
-    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
-    mDisplayList->ref(x);
-    mDisplayList->ref(y);
-    mDisplayList->ref(radius);
-    mDisplayList->ref(paint);
-    refBitmapsInShader(paint->value.getShader());
-    addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
-            &radius->value, &paint->value));
-}
-
-void DisplayListCanvas::drawOval(float left, float top, float right, float bottom,
-        const SkPaint& paint) {
-    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
-    if (fabs(sweepAngle) >= 360.0f) {
-        drawOval(left, top, right, bottom, paint);
-    } else {
-        addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
-                        startAngle, sweepAngle, useCenter, refPaint(&paint)));
-    }
-}
-
-void DisplayListCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
-    addDrawOp(new (alloc()) DrawPathOp(refPath(&path), refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawLines(const float* points, int count, const SkPaint& paint) {
-    points = refBuffer<float>(points, count);
-
-    addDrawOp(new (alloc()) DrawLinesOp(points, count, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint& paint) {
-    points = refBuffer<float>(points, count);
-
-    addDrawOp(new (alloc()) DrawPointsOp(points, count, refPaint(&paint)));
-}
-
-void DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
-    mDisplayList->ref(tree);
-    mDisplayList->vectorDrawables.push_back(tree);
-    addDrawOp(new (alloc()) DrawVectorDrawableOp(tree, tree->stagingProperties()->getBounds()));
-}
-
-void DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count,
-        const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
-    if (!glyphs || count <= 0) return;
-
-    int bytesCount = 2 * count;
-    DrawOp* op = new (alloc()) DrawTextOnPathOp(refBuffer<glyph_t>(glyphs, count),
-            bytesCount, count, refPath(&path),
-            hOffset, vOffset, refPaint(&paint));
-    addDrawOp(op);
-}
-
-void DisplayListCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions,
-        int count, const SkPaint& paint, float x, float y,
-        float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
-        float totalAdvance) {
-
-    if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
-
-    int bytesCount = count * 2;
-    positions = refBuffer<float>(positions, count * 2);
-    Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom);
-
-    DrawOp* op = new (alloc()) DrawTextOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count,
-            x, y, positions, refPaint(&paint), totalAdvance, bounds);
-    addDrawOp(op);
-    drawTextDecorations(x, y, totalAdvance, paint);
-}
-
-void DisplayListCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
-    if (paint.getStyle() != SkPaint::kFill_Style ||
-            (paint.isAntiAlias() && !mState.currentTransform()->isSimple())) {
-        SkRegion::Iterator it(region);
-        while (!it.done()) {
-            const SkIRect& r = it.rect();
-            drawRect(r.fLeft, r.fTop, r.fRight, r.fBottom, paint);
-            it.next();
-        }
-    } else {
-        int count = 0;
-        Vector<float> rects;
-        SkRegion::Iterator it(region);
-        while (!it.done()) {
-            const SkIRect& r = it.rect();
-            rects.push(r.fLeft);
-            rects.push(r.fTop);
-            rects.push(r.fRight);
-            rects.push(r.fBottom);
-            count += 4;
-            it.next();
-        }
-        drawRects(rects.array(), count, &paint);
-    }
-}
-
-void DisplayListCanvas::drawRects(const float* rects, int count, const SkPaint* paint) {
-    if (count <= 0) return;
-
-    rects = refBuffer<float>(rects, count);
-    paint = refPaint(paint);
-    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
-}
-
-void DisplayListCanvas::setDrawFilter(SkDrawFilter* filter) {
-    mDrawFilter.reset(SkSafeRef(filter));
-}
-
-void DisplayListCanvas::insertReorderBarrier(bool enableReorder) {
-    flushRestoreToCount();
-    flushTranslate();
-    mDeferredBarrierType = enableReorder ? kBarrier_OutOfOrder : kBarrier_InOrder;
-}
-
-void DisplayListCanvas::flushRestoreToCount() {
-    if (mRestoreSaveCount >= 0) {
-        addOpAndUpdateChunk(new (alloc()) RestoreToCountOp(mRestoreSaveCount));
-        mRestoreSaveCount = -1;
-    }
-}
-
-void DisplayListCanvas::flushTranslate() {
-    if (mHasDeferredTranslate) {
-        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
-            addOpAndUpdateChunk(new (alloc()) TranslateOp(mTranslateX, mTranslateY));
-            mTranslateX = mTranslateY = 0.0f;
-        }
-        mHasDeferredTranslate = false;
-    }
-}
-
-size_t DisplayListCanvas::addOpAndUpdateChunk(DisplayListOp* op) {
-    int insertIndex = mDisplayList->ops.size();
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("unsupported");
-#else
-    mDisplayList->ops.push_back(op);
-#endif
-    if (mDeferredBarrierType != kBarrier_None) {
-        // op is first in new chunk
-        mDisplayList->chunks.emplace_back();
-        DisplayList::Chunk& newChunk = mDisplayList->chunks.back();
-        newChunk.beginOpIndex = insertIndex;
-        newChunk.endOpIndex = insertIndex + 1;
-        newChunk.reorderChildren = (mDeferredBarrierType == kBarrier_OutOfOrder);
-
-        int nextChildIndex = mDisplayList->children.size();
-        newChunk.beginChildIndex = newChunk.endChildIndex = nextChildIndex;
-        mDeferredBarrierType = kBarrier_None;
-    } else {
-        // standard case - append to existing chunk
-        mDisplayList->chunks.back().endOpIndex = insertIndex + 1;
-    }
-    return insertIndex;
-}
-
-size_t DisplayListCanvas::flushAndAddOp(DisplayListOp* op) {
-    flushRestoreToCount();
-    flushTranslate();
-    return addOpAndUpdateChunk(op);
-}
-
-size_t DisplayListCanvas::addStateOp(StateOp* op) {
-    return flushAndAddOp(op);
-}
-
-size_t DisplayListCanvas::addDrawOp(DrawOp* op) {
-    Rect localBounds;
-    if (op->getLocalBounds(localBounds)) {
-        bool rejected = quickRejectRect(localBounds.left, localBounds.top,
-                localBounds.right, localBounds.bottom);
-        op->setQuickRejected(rejected);
-    }
-
-    mDisplayList->hasDrawOps = true;
-    return flushAndAddOp(op);
-}
-
-size_t DisplayListCanvas::addRenderNodeOp(DrawRenderNodeOp* op) {
-    int opIndex = addDrawOp(op);
-#if !HWUI_NEW_OPS
-    int childIndex = mDisplayList->addChild(op);
-
-    // update the chunk's child indices
-    DisplayList::Chunk& chunk = mDisplayList->chunks.back();
-    chunk.endChildIndex = childIndex + 1;
-
-    if (op->renderNode->stagingProperties().isProjectionReceiver()) {
-        // use staging property, since recording on UI thread
-        mDisplayList->projectionReceiveIndex = opIndex;
-    }
-#endif
-    return opIndex;
-}
-
-void DisplayListCanvas::refBitmapsInShader(const SkShader* shader) {
-    if (!shader) return;
-
-    // If this paint has an SkShader that has an SkBitmap add
-    // it to the bitmap pile
-    SkBitmap bitmap;
-    SkShader::TileMode xy[2];
-    if (shader->isABitmap(&bitmap, nullptr, xy)) {
-        refBitmap(bitmap);
-        return;
-    }
-    SkShader::ComposeRec rec;
-    if (shader->asACompose(&rec)) {
-        refBitmapsInShader(rec.fShaderA);
-        refBitmapsInShader(rec.fShaderB);
-        return;
-    }
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
deleted file mode 100644
index 664f79e..0000000
--- a/libs/hwui/DisplayListCanvas.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
-#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
-
-#include "CanvasState.h"
-#include "DisplayList.h"
-#include "RenderNode.h"
-#include "ResourceCache.h"
-#include "SkiaCanvasProxy.h"
-#include "hwui/Canvas.h"
-#include "utils/Macros.h"
-
-#include <SkDrawFilter.h>
-#include <SkMatrix.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-#include <SkRegion.h>
-#include <SkTLazy.h>
-#include <cutils/compiler.h>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_DISPLAY_LIST
-    #define DISPLAY_LIST_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define DISPLAY_LIST_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Display list
-///////////////////////////////////////////////////////////////////////////////
-
-class DeferredDisplayList;
-class DeferredLayerUpdater;
-class DisplayListOp;
-class DrawOp;
-class DrawRenderNodeOp;
-class RenderNode;
-class StateOp;
-
-/**
- * Records drawing commands in a display list for later playback into an OpenGLRenderer.
- */
-class ANDROID_API DisplayListCanvas: public Canvas, public CanvasStateClient {
-public:
-    DisplayListCanvas(int width, int height);
-    virtual ~DisplayListCanvas();
-
-    virtual void resetRecording(int width, int height) override;
-    virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override;
-
-// ----------------------------------------------------------------------------
-// HWUI Canvas state operations
-// ----------------------------------------------------------------------------
-
-    virtual void insertReorderBarrier(bool enableReorder) override;
-
-// ----------------------------------------------------------------------------
-// HWUI Canvas draw operations
-// ----------------------------------------------------------------------------
-
-    // Shapes
-    virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
-                CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
-                CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
-                CanvasPropertyPaint* paint) override;
-    virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
-                CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override;
-
-// ----------------------------------------------------------------------------
-// HWUI Canvas draw operations - special
-// ----------------------------------------------------------------------------
-    virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
-    virtual void drawRenderNode(RenderNode* renderNode) override;
-    virtual void callDrawGLFunction(Functor* functor,
-            GlFunctorLifecycleListener* listener) override;
-
-// ----------------------------------------------------------------------------
-// CanvasStateClient interface
-// ----------------------------------------------------------------------------
-    virtual void onViewportInitialized() override { }
-    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override { }
-    virtual GLuint getTargetFbo() const override { return -1; }
-
-// ----------------------------------------------------------------------------
-// android/graphics/Canvas interface
-// ----------------------------------------------------------------------------
-    virtual SkCanvas* asSkCanvas() override;
-
-    virtual void setBitmap(const SkBitmap& bitmap) override {
-        LOG_ALWAYS_FATAL("DisplayListCanvas is not backed by a bitmap.");
-    }
-
-    virtual bool isOpaque() override { return false; }
-    virtual int width() override { return mState.getWidth(); }
-    virtual int height() override { return mState.getHeight(); }
-
-    virtual void setHighContrastText(bool highContrastText) override {
-        mHighContrastText = highContrastText;
-    }
-    virtual bool isHighContrastText() override { return mHighContrastText; }
-
-// ----------------------------------------------------------------------------
-// android/graphics/Canvas state operations
-// ----------------------------------------------------------------------------
-    // Save (layer)
-    virtual int getSaveCount() const override { return mState.getSaveCount(); }
-    virtual int save(SaveFlags::Flags flags) override;
-    virtual void restore() override;
-    virtual void restoreToCount(int saveCount) override;
-
-    virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
-        SaveFlags::Flags flags) override;
-    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, SaveFlags::Flags flags) override {
-        SkPaint paint;
-        paint.setAlpha(alpha);
-        return saveLayer(left, top, right, bottom, &paint, flags);
-    }
-
-    // Matrix
-    virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
-    virtual void setMatrix(const SkMatrix& matrix) override;
-
-    virtual void concat(const SkMatrix& matrix) override;
-    virtual void rotate(float degrees) override;
-    virtual void scale(float sx, float sy) override;
-    virtual void skew(float sx, float sy) override;
-    virtual void translate(float dx, float dy) override;
-
-    // Clip
-    virtual bool getClipBounds(SkRect* outRect) const override;
-    virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
-    virtual bool quickRejectPath(const SkPath& path) const override;
-
-    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) override;
-    virtual bool clipPath(const SkPath* path, SkRegion::Op op) override;
-    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) override;
-
-    // Misc
-    virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); }
-    virtual void setDrawFilter(SkDrawFilter* filter) override;
-
-// ----------------------------------------------------------------------------
-// android/graphics/Canvas draw operations
-// ----------------------------------------------------------------------------
-    virtual void drawColor(int color, SkXfermode::Mode mode) override;
-    virtual void drawPaint(const SkPaint& paint) override;
-
-    // Geometry
-    virtual void drawPoint(float x, float y, const SkPaint& paint) override {
-        float points[2] = { x, y };
-        drawPoints(points, 2, paint);
-    }
-    virtual void drawPoints(const float* points, int count, const SkPaint& paint) override;
-    virtual void drawLine(float startX, float startY, float stopX, float stopY,
-            const SkPaint& paint) override {
-        float points[4] = { startX, startY, stopX, stopY };
-        drawLines(points, 4, paint);
-    }
-    virtual void drawLines(const float* points, int count, const SkPaint& paint) override;
-    virtual void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
-    virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
-    virtual void drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, const SkPaint& paint) override;
-    virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
-    virtual void drawOval(float left, float top, float right, float bottom, const SkPaint& paint) override;
-    virtual void drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) override;
-    virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
-    virtual void drawVertices(SkCanvas::VertexMode vertexMode, int vertexCount,
-            const float* verts, const float* tex, const int* colors,
-            const uint16_t* indices, int indexCount, const SkPaint& paint) override
-        { /* DisplayListCanvas does not support drawVertices(); ignore */ }
-
-    // Bitmap-based
-    virtual void drawBitmap(const SkBitmap& bitmap, float left, float top, const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, const SkMatrix& matrix,
-                            const SkPaint* paint) override;
-    virtual void drawBitmap(const SkBitmap& bitmap, float srcLeft, float srcTop,
-            float srcRight, float srcBottom, float dstLeft, float dstTop,
-            float dstRight, float dstBottom, const SkPaint* paint) override;
-    virtual void drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
-            const float* vertices, const int* colors, const SkPaint* paint) override;
-    virtual void drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& chunk,
-            float dstLeft, float dstTop, float dstRight, float dstBottom,
-            const SkPaint* paint) override;
-
-    virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
-
-    // Text
-    virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
-            const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
-            float boundsRight, float boundsBottom, float totalAdvance) override;
-    virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
-            float hOffset, float vOffset, const SkPaint& paint) override;
-    virtual bool drawTextAbsolutePos() const override { return false; }
-
-private:
-
-    CanvasState mState;
-    std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
-
-    enum DeferredBarrierType {
-        kBarrier_None,
-        kBarrier_InOrder,
-        kBarrier_OutOfOrder,
-    };
-
-    void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
-    void drawRects(const float* rects, int count, const SkPaint* paint);
-
-    void flushRestoreToCount();
-    void flushTranslate();
-    void flushReorderBarrier();
-
-    LinearAllocator& alloc() { return mDisplayList->allocator; }
-
-    // Each method returns final index of op
-    size_t addOpAndUpdateChunk(DisplayListOp* op);
-    // flushes any deferred operations, and appends the op
-    size_t flushAndAddOp(DisplayListOp* op);
-
-    size_t addStateOp(StateOp* op);
-    size_t addDrawOp(DrawOp* op);
-    size_t addRenderNodeOp(DrawRenderNodeOp* op);
-
-    void refBitmapsInShader(const SkShader* shader);
-
-    template<class T>
-    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
-        if (!srcBuffer) return nullptr;
-
-        T* dstBuffer = (T*) mDisplayList->allocator.alloc<T>(count * sizeof(T));
-        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
-        return dstBuffer;
-    }
-
-    inline const SkPath* refPath(const SkPath* path) {
-        if (!path) return nullptr;
-
-        // The points/verbs within the path are refcounted so this copy operation
-        // is inexpensive and maintains the generationID of the original path.
-        const SkPath* cachedPath = new SkPath(*path);
-        mDisplayList->pathResources.push_back(cachedPath);
-        return cachedPath;
-    }
-
-    inline const SkPaint* refPaint(const SkPaint* paint) {
-        if (!paint) return nullptr;
-
-        // If there is a draw filter apply it here and store the modified paint
-        // so that we don't need to modify the paint every time we access it.
-        SkTLazy<SkPaint> filteredPaint;
-        if (mDrawFilter.get()) {
-            filteredPaint.set(*paint);
-            mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
-            paint = filteredPaint.get();
-        }
-
-        // compute the hash key for the paint and check the cache.
-        const uint32_t key = paint->getHash();
-        const SkPaint* cachedPaint = mPaintMap.valueFor(key);
-        // In the unlikely event that 2 unique paints have the same hash we do a
-        // object equality check to ensure we don't erroneously dedup them.
-        if (cachedPaint == nullptr || *cachedPaint != *paint) {
-            cachedPaint = new SkPaint(*paint);
-            std::unique_ptr<const SkPaint> copy(cachedPaint);
-            mDisplayList->paints.push_back(std::move(copy));
-
-            // replaceValueFor() performs an add if the entry doesn't exist
-            mPaintMap.replaceValueFor(key, cachedPaint);
-            refBitmapsInShader(cachedPaint->getShader());
-        }
-
-        return cachedPaint;
-    }
-
-    inline const SkRegion* refRegion(const SkRegion* region) {
-        if (!region) {
-            return region;
-        }
-
-        const SkRegion* cachedRegion = mRegionMap.valueFor(region);
-        // TODO: Add generation ID to SkRegion
-        if (cachedRegion == nullptr) {
-            std::unique_ptr<const SkRegion> copy(new SkRegion(*region));
-            cachedRegion = copy.get();
-            mDisplayList->regions.push_back(std::move(copy));
-
-            // replaceValueFor() performs an add if the entry doesn't exist
-            mRegionMap.replaceValueFor(region, cachedRegion);
-        }
-
-        return cachedRegion;
-    }
-
-    inline const SkBitmap* refBitmap(const SkBitmap& bitmap) {
-        // Note that this assumes the bitmap is immutable. There are cases this won't handle
-        // correctly, such as creating the bitmap from scratch, drawing with it, changing its
-        // contents, and drawing again. The only fix would be to always copy it the first time,
-        // which doesn't seem worth the extra cycles for this unlikely case.
-        SkBitmap* localBitmap = alloc().create<SkBitmap>(bitmap);
-        mDisplayList->bitmapResources.push_back(localBitmap);
-        return localBitmap;
-    }
-
-    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
-        mDisplayList->patchResources.push_back(patch);
-        mResourceCache.incrementRefcount(patch);
-        return patch;
-    }
-
-    DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
-    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
-    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
-
-    ResourceCache& mResourceCache;
-    DisplayList* mDisplayList;
-
-    float mTranslateX;
-    float mTranslateY;
-    bool mHasDeferredTranslate;
-    DeferredBarrierType mDeferredBarrierType;
-    bool mHighContrastText;
-
-    int mRestoreSaveCount;
-
-    SkAutoTUnref<SkDrawFilter> mDrawFilter;
-
-    friend class RenderNode;
-
-}; // class DisplayListCanvas
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
deleted file mode 100644
index 2a85913..0000000
--- a/libs/hwui/DisplayListOp.h
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_DISPLAY_OPERATION_H
-#define ANDROID_HWUI_DISPLAY_OPERATION_H
-
-#include "OpenGLRenderer.h"
-#include "AssetAtlas.h"
-#include "DeferredDisplayList.h"
-#include "DisplayListCanvas.h"
-#include "GammaFontRenderer.h"
-#include "Patch.h"
-#include "RenderNode.h"
-#include "renderstate/RenderState.h"
-#include "UvMapper.h"
-#include "utils/LinearAllocator.h"
-#include "utils/PaintUtils.h"
-#include "VectorDrawable.h"
-
-#include <algorithm>
-
-#include <SkColor.h>
-#include <SkPath.h>
-#include <SkPathOps.h>
-#include <SkXfermode.h>
-
-#include <private/hwui/DrawGlInfo.h>
-
-// Use OP_LOG for logging with arglist, OP_LOGS if just printing char*
-#define OP_LOGS(s) OP_LOG("%s", (s))
-#define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ )
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Structure for storing canvas operations when they are recorded into a DisplayList, so that they
- * may be replayed to an OpenGLRenderer.
- *
- * To avoid individual memory allocations, DisplayListOps may only be allocated into a
- * LinearAllocator's managed memory buffers.  Each pointer held by a DisplayListOp is either a
- * pointer into memory also allocated in the LinearAllocator (mostly for text and float buffers) or
- * references a externally refcounted object (Sk... and Skia... objects). ~DisplayListOp() is
- * never called as LinearAllocators are simply discarded, so no memory management should be done in
- * this class.
- */
-class DisplayListOp {
-public:
-    // These objects should always be allocated with a LinearAllocator, and never destroyed/deleted.
-    // standard new() intentionally not implemented, and delete/deconstructor should never be used.
-    virtual ~DisplayListOp() { LOG_ALWAYS_FATAL("Destructor not supported"); }
-    static void operator delete(void* ptr) { LOG_ALWAYS_FATAL("delete not supported"); }
-    static void* operator new(size_t size) = delete; /** PURPOSELY OMITTED **/
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        // FIXME: Quick hack to keep old pipeline working, delete this when
-        // we no longer need to support HWUI_NEWOPS := false
-        return allocator.alloc<char>(size);
-    }
-
-    enum OpLogFlag {
-        kOpLogFlag_Recurse = 0x1,
-        kOpLogFlag_JSON = 0x2 // TODO: add?
-    };
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) = 0;
-
-    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
-            bool useQuickReject) = 0;
-
-    virtual void output(int level, uint32_t logFlags = 0) const = 0;
-
-    // NOTE: it would be nice to declare constants and overriding the implementation in each op to
-    // point at the constants, but that seems to require a .cpp file
-    virtual const char* name() = 0;
-};
-
-class StateOp : public DisplayListOp {
-public:
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        // default behavior only affects immediate, deferrable state, issue directly to renderer
-        applyState(deferStruct.mRenderer, saveCount);
-    }
-
-    /**
-     * State operations are applied directly to the renderer, but can cause the deferred drawing op
-     * list to flush
-     */
-    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        applyState(replayStruct.mRenderer, saveCount);
-    }
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const = 0;
-};
-
-class DrawOp : public DisplayListOp {
-friend class MergingDrawBatch;
-public:
-    DrawOp(const SkPaint* paint)
-            : mPaint(paint), mQuickRejected(false) {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        if (mQuickRejected && CC_LIKELY(useQuickReject)) {
-            return;
-        }
-
-        deferStruct.mDeferredList.addDrawOp(deferStruct.mRenderer, this);
-    }
-
-    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        if (mQuickRejected && CC_LIKELY(useQuickReject)) {
-            return;
-        }
-
-        applyDraw(replayStruct.mRenderer, replayStruct.mDirty);
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) = 0;
-
-    /**
-     * Draw multiple instances of an operation, must be overidden for operations that merge
-     *
-     * Currently guarantees certain similarities between ops (see MergingDrawBatch::canMergeWith),
-     * and pure translation transformations. Other guarantees of similarity should be enforced by
-     * reducing which operations are tagged as mergeable.
-     */
-    virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const std::vector<OpStatePair>& ops, const Rect& bounds) {
-        for (unsigned int i = 0; i < ops.size(); i++) {
-            renderer.restoreDisplayState(*(ops[i].state), true);
-            ops[i].op->applyDraw(renderer, dirty);
-        }
-    }
-
-    /**
-     * When this method is invoked the state field is initialized to have the
-     * final rendering state. We can thus use it to process data as it will be
-     * used at draw time.
-     *
-     * Additionally, this method allows subclasses to provide defer-time preferences for batching
-     * and merging.
-     *
-     * if a subclass can set deferInfo.mergeable to true, it should implement multiDraw()
-     */
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) {}
-
-    /**
-     * Query the conservative, local bounds (unmapped) bounds of the op.
-     *
-     * returns true if bounds exist
-     */
-    virtual bool getLocalBounds(Rect& localBounds) {
-        return false;
-    }
-
-    // TODO: better refine localbounds usage
-    void setQuickRejected(bool quickRejected) { mQuickRejected = quickRejected; }
-    bool getQuickRejected() { return mQuickRejected; }
-
-    virtual bool hasTextShadow() const {
-        return false;
-    }
-
-    inline float strokeWidthOutset() {
-        // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced
-        // 1.0 stroke, treat 1.0 as minimum.
-
-        // TODO: it would be nice if this could take scale into account, but scale isn't stable
-        // since higher levels of the view hierarchy can change scale out from underneath it.
-        return std::max(mPaint->getStrokeWidth(), 1.0f) * 0.5f;
-    }
-
-protected:
-    // Helper method for determining op opaqueness. Assumes op fills its bounds in local
-    // coordinates, and that paint's alpha is used
-    inline bool isOpaqueOverBounds(const DeferredDisplayState& state) {
-        // ensure that local bounds cover mapped bounds
-        if (!state.mMatrix.isSimple()) return false;
-
-        if (state.mRoundRectClipState) return false;
-
-        // check state/paint for transparency
-        if (mPaint) {
-            if (mPaint->getAlpha() != 0xFF) {
-                return false;
-            }
-            if (mPaint->getShader() && !mPaint->getShader()->isOpaque()) {
-                return false;
-            }
-            if (PaintUtils::isBlendedColorFilter(mPaint->getColorFilter())) {
-                return false;
-            }
-        }
-
-        if (state.mAlpha != 1.0f) return false;
-
-        SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(mPaint);
-        return (mode == SkXfermode::kSrcOver_Mode ||
-                mode == SkXfermode::kSrc_Mode);
-
-    }
-
-    const SkPaint* mPaint;
-    bool mQuickRejected;
-};
-
-class DrawBoundedOp : public DrawOp {
-public:
-    DrawBoundedOp(float left, float top, float right, float bottom, const SkPaint* paint)
-            : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
-
-    DrawBoundedOp(const Rect& localBounds, const SkPaint* paint)
-            : DrawOp(paint), mLocalBounds(localBounds) {}
-
-    // Calculates bounds as smallest rect encompassing all points
-    // NOTE: requires at least 1 vertex, and doesn't account for stroke size (should be handled in
-    // subclass' constructor)
-    DrawBoundedOp(const float* points, int count, const SkPaint* paint)
-            : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
-        for (int i = 2; i < count; i += 2) {
-            mLocalBounds.left = std::min(mLocalBounds.left, points[i]);
-            mLocalBounds.right = std::max(mLocalBounds.right, points[i]);
-            mLocalBounds.top = std::min(mLocalBounds.top, points[i + 1]);
-            mLocalBounds.bottom = std::max(mLocalBounds.bottom, points[i + 1]);
-        }
-    }
-
-    // default empty constructor for bounds, to be overridden in child constructor body
-    DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { }
-
-    virtual bool getLocalBounds(Rect& localBounds) override {
-        localBounds.set(mLocalBounds);
-        PaintUtils::TextShadow textShadow;
-        if (PaintUtils::getTextShadow(mPaint, &textShadow)) {
-            Rect shadow(mLocalBounds);
-            shadow.translate(textShadow.dx, textShadow.dx);
-            shadow.outset(textShadow.radius);
-            localBounds.unionWith(shadow);
-        }
-        return true;
-    }
-
-protected:
-    Rect mLocalBounds; // displayed area in LOCAL coord. doesn't incorporate stroke, so check paint
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// STATE OPERATIONS - these may affect the state of the canvas/renderer, but do
-//         not directly draw or alter output
-///////////////////////////////////////////////////////////////////////////////
-
-class SaveOp : public StateOp {
-public:
-    SaveOp(int flags)
-            : mFlags(flags) {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        int newSaveCount = deferStruct.mRenderer.save(mFlags);
-        deferStruct.mDeferredList.addSave(deferStruct.mRenderer, this, newSaveCount);
-    }
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.save(mFlags);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Save flags %x", mFlags);
-    }
-
-    virtual const char* name() override { return "Save"; }
-
-    int getFlags() const { return mFlags; }
-private:
-    int mFlags;
-};
-
-class RestoreToCountOp : public StateOp {
-public:
-    RestoreToCountOp(int count)
-            : mCount(count) {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        deferStruct.mDeferredList.addRestoreToCount(deferStruct.mRenderer,
-                this, saveCount + mCount);
-        deferStruct.mRenderer.restoreToCount(saveCount + mCount);
-    }
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.restoreToCount(saveCount + mCount);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Restore to count %d", mCount);
-    }
-
-    virtual const char* name() override { return "RestoreToCount"; }
-
-private:
-    int mCount;
-};
-
-class SaveLayerOp : public StateOp {
-public:
-    SaveLayerOp(float left, float top, float right, float bottom, int alpha, int flags)
-            : mArea(left, top, right, bottom)
-            , mPaint(&mCachedPaint)
-            , mFlags(flags)
-            , mConvexMask(nullptr) {
-        mCachedPaint.setAlpha(alpha);
-    }
-
-    SaveLayerOp(float left, float top, float right, float bottom, const SkPaint* paint, int flags)
-            : mArea(left, top, right, bottom)
-            , mPaint(paint)
-            , mFlags(flags)
-            , mConvexMask(nullptr)
-    {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        // NOTE: don't bother with actual saveLayer, instead issuing it at flush time
-        int newSaveCount = deferStruct.mRenderer.getSaveCount();
-        deferStruct.mDeferredList.addSaveLayer(deferStruct.mRenderer, this, newSaveCount);
-
-        // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just
-        // setup the snapshot for deferral, and re-issue the op at flush time
-        deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom,
-                mPaint, mFlags);
-    }
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom,
-                mPaint, mFlags, mConvexMask);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("SaveLayer%s of area " RECT_STRING,
-                (isSaveLayerAlpha() ? "Alpha" : ""),RECT_ARGS(mArea));
-    }
-
-    virtual const char* name() override {
-        return isSaveLayerAlpha() ? "SaveLayerAlpha" : "SaveLayer";
-    }
-
-    int getFlags() { return mFlags; }
-
-    // Called to make SaveLayerOp clip to the provided mask when drawing back/restored
-    void setMask(const SkPath* convexMask) {
-        mConvexMask = convexMask;
-    }
-
-private:
-    bool isSaveLayerAlpha() const {
-        SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(mPaint);
-        int alpha = PaintUtils::getAlphaDirect(mPaint);
-        return alpha < 255 && mode == SkXfermode::kSrcOver_Mode;
-    }
-
-    Rect mArea;
-    const SkPaint* mPaint;
-    SkPaint mCachedPaint;
-    int mFlags;
-
-    // Convex path, points at data in RenderNode, valid for the duration of the frame only
-    // Only used for masking the SaveLayer which wraps projected RenderNodes
-    const SkPath* mConvexMask;
-};
-
-class TranslateOp : public StateOp {
-public:
-    TranslateOp(float dx, float dy)
-            : mDx(dx), mDy(dy) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.translate(mDx, mDy);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Translate by %f %f", mDx, mDy);
-    }
-
-    virtual const char* name() override { return "Translate"; }
-
-private:
-    float mDx;
-    float mDy;
-};
-
-class RotateOp : public StateOp {
-public:
-    RotateOp(float degrees)
-            : mDegrees(degrees) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.rotate(mDegrees);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Rotate by %f degrees", mDegrees);
-    }
-
-    virtual const char* name() override { return "Rotate"; }
-
-private:
-    float mDegrees;
-};
-
-class ScaleOp : public StateOp {
-public:
-    ScaleOp(float sx, float sy)
-            : mSx(sx), mSy(sy) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.scale(mSx, mSy);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Scale by %f %f", mSx, mSy);
-    }
-
-    virtual const char* name() override { return "Scale"; }
-
-private:
-    float mSx;
-    float mSy;
-};
-
-class SkewOp : public StateOp {
-public:
-    SkewOp(float sx, float sy)
-            : mSx(sx), mSy(sy) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.skew(mSx, mSy);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Skew by %f %f", mSx, mSy);
-    }
-
-    virtual const char* name() override { return "Skew"; }
-
-private:
-    float mSx;
-    float mSy;
-};
-
-class SetMatrixOp : public StateOp {
-public:
-    SetMatrixOp(const SkMatrix& matrix)
-            : mMatrix(matrix) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        // Setting a matrix on a Canvas isn't equivalent to setting a total matrix on the scene.
-        // Set a canvas-relative matrix on the renderer instead.
-        renderer.setLocalMatrix(mMatrix);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        if (mMatrix.isIdentity()) {
-            OP_LOGS("SetMatrix (reset)");
-        } else {
-            OP_LOG("SetMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix));
-        }
-    }
-
-    virtual const char* name() override { return "SetMatrix"; }
-
-private:
-    const SkMatrix mMatrix;
-};
-
-class ConcatMatrixOp : public StateOp {
-public:
-    ConcatMatrixOp(const SkMatrix& matrix)
-            : mMatrix(matrix) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.concatMatrix(mMatrix);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("ConcatMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix));
-    }
-
-    virtual const char* name() override { return "ConcatMatrix"; }
-
-private:
-    const SkMatrix mMatrix;
-};
-
-class ClipOp : public StateOp {
-public:
-    ClipOp(SkRegion::Op op) : mOp(op) {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        // NOTE: must defer op BEFORE applying state, since it may read clip
-        deferStruct.mDeferredList.addClip(deferStruct.mRenderer, this);
-
-        // TODO: Can we avoid applying complex clips at defer time?
-        applyState(deferStruct.mRenderer, saveCount);
-    }
-
-    bool canCauseComplexClip() {
-        return ((mOp != SkRegion::kIntersect_Op) && (mOp != SkRegion::kReplace_Op)) || !isRect();
-    }
-
-protected:
-    virtual bool isRect() { return false; }
-
-    SkRegion::Op mOp;
-};
-
-class ClipRectOp : public ClipOp {
-public:
-    ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
-            : ClipOp(op), mArea(left, top, right, bottom) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
-    }
-
-    virtual const char* name() override { return "ClipRect"; }
-
-protected:
-    virtual bool isRect() override { return true; }
-
-private:
-    Rect mArea;
-};
-
-class ClipPathOp : public ClipOp {
-public:
-    ClipPathOp(const SkPath* path, SkRegion::Op op)
-            : ClipOp(op), mPath(path) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.clipPath(mPath, mOp);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        SkRect bounds = mPath->getBounds();
-        OP_LOG("ClipPath bounds " RECT_STRING,
-                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
-    }
-
-    virtual const char* name() override { return "ClipPath"; }
-
-private:
-    const SkPath* mPath;
-};
-
-class ClipRegionOp : public ClipOp {
-public:
-    ClipRegionOp(const SkRegion* region, SkRegion::Op op)
-            : ClipOp(op), mRegion(region) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.clipRegion(mRegion, mOp);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        SkIRect bounds = mRegion->getBounds();
-        OP_LOG("ClipRegion bounds %d %d %d %d",
-                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
-    }
-
-    virtual const char* name() override { return "ClipRegion"; }
-
-private:
-    const SkRegion* mRegion;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// DRAW OPERATIONS - these are operations that can draw to the canvas's device
-///////////////////////////////////////////////////////////////////////////////
-
-class DrawBitmapOp : public DrawBoundedOp {
-public:
-    DrawBitmapOp(const SkBitmap* bitmap, const SkPaint* paint)
-            : DrawBoundedOp(0, 0, bitmap->width(), bitmap->height(), paint)
-            , mBitmap(bitmap)
-            , mEntryValid(false), mEntry(nullptr) {
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawBitmap(mBitmap, mPaint);
-    }
-
-    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
-        if (!mEntryValid) {
-            mEntryValid = true;
-            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap->pixelRef());
-        }
-        return mEntry;
-    }
-
-#define SET_TEXTURE(ptr, posRect, offsetRect, texCoordsRect, xDim, yDim) \
-    TextureVertex::set((ptr)++, (posRect).xDim - (offsetRect).left, (posRect).yDim - (offsetRect).top, \
-            (texCoordsRect).xDim, (texCoordsRect).yDim)
-
-    /**
-     * This multi-draw operation builds a mesh on the stack by generating a quad
-     * for each bitmap in the batch. This method is also responsible for dirtying
-     * the current layer, if any.
-     */
-    virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const std::vector<OpStatePair>& ops, const Rect& bounds) override {
-        const DeferredDisplayState& firstState = *(ops[0].state);
-        renderer.restoreDisplayState(firstState, true); // restore all but the clip
-
-        TextureVertex vertices[6 * ops.size()];
-        TextureVertex* vertex = &vertices[0];
-
-        const bool hasLayer = renderer.hasLayer();
-        bool pureTranslate = true;
-
-        // TODO: manually handle rect clip for bitmaps by adjusting texCoords per op,
-        // and allowing them to be merged in getBatchId()
-        for (unsigned int i = 0; i < ops.size(); i++) {
-            const DeferredDisplayState& state = *(ops[i].state);
-            const Rect& opBounds = state.mBounds;
-            // When we reach multiDraw(), the matrix can be either
-            // pureTranslate or simple (translate and/or scale).
-            // If the matrix is not pureTranslate, then we have a scale
-            pureTranslate &= state.mMatrix.isPureTranslate();
-
-            Rect texCoords(0, 0, 1, 1);
-            ((DrawBitmapOp*) ops[i].op)->uvMap(renderer, texCoords);
-
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, top);
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
-
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, left, bottom);
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, top);
-            SET_TEXTURE(vertex, opBounds, bounds, texCoords, right, bottom);
-
-            if (hasLayer) {
-                renderer.dirtyLayer(opBounds.left, opBounds.top, opBounds.right, opBounds.bottom);
-            }
-        }
-
-        renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0],
-                pureTranslate, bounds, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw bitmap %p of size %dx%d%s",
-                mBitmap, mBitmap->width(), mBitmap->height(),
-                mEntry ? " using AssetAtlas" : "");
-    }
-
-    virtual const char* name() override { return "DrawBitmap"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = getAtlasEntry(renderer) ?
-                (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
-
-        // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation
-        // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
-        // MergingDrawBatch::canMergeWith()
-        // TODO: support clipped bitmaps by handling them in SET_TEXTURE
-        deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() &&
-                !state.mClipSideFlags &&
-                PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode &&
-                (mBitmap->colorType() != kAlpha_8_SkColorType);
-    }
-
-    void uvMap(OpenGLRenderer& renderer, Rect& texCoords) {
-        if (getAtlasEntry(renderer)) {
-            mEntry->uvMapper.map(texCoords);
-        }
-    }
-
-    const SkBitmap* bitmap() { return mBitmap; }
-protected:
-    const SkBitmap* mBitmap;
-    bool mEntryValid;
-    AssetAtlas::Entry* mEntry;
-};
-
-class DrawBitmapRectOp : public DrawBoundedOp {
-public:
-    DrawBitmapRectOp(const SkBitmap* bitmap,
-            float srcLeft, float srcTop, float srcRight, float srcBottom,
-            float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint)
-            : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
-            mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawBitmap(mBitmap, mSrc, mLocalBounds, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw bitmap %p src=" RECT_STRING ", dst=" RECT_STRING,
-                mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
-    }
-
-    virtual const char* name() override { return "DrawBitmapRect"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-    }
-
-private:
-    const SkBitmap* mBitmap;
-    Rect mSrc;
-};
-
-class DrawBitmapMeshOp : public DrawBoundedOp {
-public:
-    DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight,
-            const float* vertices, const int* colors, const SkPaint* paint)
-            : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint),
-            mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
-            mVertices(vertices), mColors(colors) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
-                mVertices, mColors, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
-    }
-
-    virtual const char* name() override { return "DrawBitmapMesh"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-    }
-
-private:
-    const SkBitmap* mBitmap;
-    int mMeshWidth;
-    int mMeshHeight;
-    const float* mVertices;
-    const int* mColors;
-};
-
-class DrawPatchOp : public DrawBoundedOp {
-public:
-    DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch,
-            float left, float top, float right, float bottom, const SkPaint* paint)
-            : DrawBoundedOp(left, top, right, bottom, paint),
-            mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(nullptr),
-            mEntryValid(false), mEntry(nullptr) {
-    };
-
-    AssetAtlas::Entry* getAtlasEntry(OpenGLRenderer& renderer) {
-        if (!mEntryValid) {
-            mEntryValid = true;
-            mEntry = renderer.renderState().assetAtlas().getEntry(mBitmap->pixelRef());
-        }
-        return mEntry;
-    }
-
-    const Patch* getMesh(OpenGLRenderer& renderer) {
-        if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
-            PatchCache& cache = renderer.getCaches().patchCache;
-            mMesh = cache.get(getAtlasEntry(renderer), mBitmap->width(), mBitmap->height(),
-                    mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
-            mGenerationId = cache.getGenerationId();
-        }
-        return mMesh;
-    }
-
-    /**
-     * This multi-draw operation builds an indexed mesh on the stack by copying
-     * and transforming the vertices of each 9-patch in the batch. This method
-     * is also responsible for dirtying the current layer, if any.
-     */
-    virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const std::vector<OpStatePair>& ops, const Rect& bounds) override {
-        const DeferredDisplayState& firstState = *(ops[0].state);
-        renderer.restoreDisplayState(firstState, true); // restore all but the clip
-
-        // Batches will usually contain a small number of items so it's
-        // worth performing a first iteration to count the exact number
-        // of vertices we need in the new mesh
-        uint32_t totalVertices = 0;
-        for (unsigned int i = 0; i < ops.size(); i++) {
-            totalVertices += ((DrawPatchOp*) ops[i].op)->getMesh(renderer)->verticesCount;
-        }
-
-        const bool hasLayer = renderer.hasLayer();
-
-        uint32_t indexCount = 0;
-
-        TextureVertex vertices[totalVertices];
-        TextureVertex* vertex = &vertices[0];
-
-        // Create a mesh that contains the transformed vertices for all the
-        // 9-patch objects that are part of the batch. Note that onDefer()
-        // enforces ops drawn by this function to have a pure translate or
-        // identity matrix
-        for (unsigned int i = 0; i < ops.size(); i++) {
-            DrawPatchOp* patchOp = (DrawPatchOp*) ops[i].op;
-            const DeferredDisplayState* state = ops[i].state;
-            const Patch* opMesh = patchOp->getMesh(renderer);
-            uint32_t vertexCount = opMesh->verticesCount;
-            if (vertexCount == 0) continue;
-
-            // We use the bounds to know where to translate our vertices
-            // Using patchOp->state.mBounds wouldn't work because these
-            // bounds are clipped
-            const float tx = (int) floorf(state->mMatrix.getTranslateX() +
-                    patchOp->mLocalBounds.left + 0.5f);
-            const float ty = (int) floorf(state->mMatrix.getTranslateY() +
-                    patchOp->mLocalBounds.top + 0.5f);
-
-            // Copy & transform all the vertices for the current operation
-            TextureVertex* opVertices = opMesh->vertices.get();
-            for (uint32_t j = 0; j < vertexCount; j++, opVertices++) {
-                TextureVertex::set(vertex++,
-                        opVertices->x + tx, opVertices->y + ty,
-                        opVertices->u, opVertices->v);
-            }
-
-            // Dirty the current layer if possible. When the 9-patch does not
-            // contain empty quads we can take a shortcut and simply set the
-            // dirty rect to the object's bounds.
-            if (hasLayer) {
-                if (!opMesh->hasEmptyQuads) {
-                    renderer.dirtyLayer(tx, ty,
-                            tx + patchOp->mLocalBounds.getWidth(),
-                            ty + patchOp->mLocalBounds.getHeight());
-                } else {
-                    const size_t count = opMesh->quads.size();
-                    for (size_t i = 0; i < count; i++) {
-                        const Rect& quadBounds = opMesh->quads[i];
-                        const float x = tx + quadBounds.left;
-                        const float y = ty + quadBounds.top;
-                        renderer.dirtyLayer(x, y,
-                                x + quadBounds.getWidth(), y + quadBounds.getHeight());
-                    }
-                }
-            }
-
-            indexCount += opMesh->indexCount;
-        }
-
-        renderer.drawPatches(mBitmap, getAtlasEntry(renderer),
-                &vertices[0], indexCount, mPaint);
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        // We're not calling the public variant of drawPatch() here
-        // This method won't perform the quickReject() since we've already done it at this point
-        renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(renderer),
-                mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
-                mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw patch " RECT_STRING "%s", RECT_ARGS(mLocalBounds),
-                mEntry ? " with AssetAtlas" : "");
-    }
-
-    virtual const char* name() override { return "DrawPatch"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = getAtlasEntry(renderer) ? (mergeid_t) mEntry->getMergeId() : (mergeid_t) mBitmap;
-        deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
-                PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
-        deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) && mBitmap->isOpaque();
-    }
-
-private:
-    const SkBitmap* mBitmap;
-    const Res_png_9patch* mPatch;
-
-    uint32_t mGenerationId;
-    const Patch* mMesh;
-
-    bool mEntryValid;
-    AssetAtlas::Entry* mEntry;
-};
-
-class DrawColorOp : public DrawOp {
-public:
-    DrawColorOp(int color, SkXfermode::Mode mode)
-            : DrawOp(nullptr), mColor(color), mMode(mode) {};
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawColor(mColor, mMode);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw color %#x, mode %d", mColor, mMode);
-    }
-
-    virtual const char* name() override { return "DrawColor"; }
-
-private:
-    int mColor;
-    SkXfermode::Mode mMode;
-};
-
-class DrawStrokableOp : public DrawBoundedOp {
-public:
-    DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint)
-            : DrawBoundedOp(left, top, right, bottom, paint) {};
-    DrawStrokableOp(const Rect& localBounds, const SkPaint* paint)
-            : DrawBoundedOp(localBounds, paint) {};
-
-    virtual bool getLocalBounds(Rect& localBounds) override {
-        localBounds.set(mLocalBounds);
-        if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
-            localBounds.outset(strokeWidthOutset());
-        }
-        return true;
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        if (mPaint->getPathEffect()) {
-            deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
-        } else {
-            deferInfo.batchId = mPaint->isAntiAlias() ?
-                    DeferredDisplayList::kOpBatch_AlphaVertices :
-                    DeferredDisplayList::kOpBatch_Vertices;
-        }
-    }
-};
-
-class DrawRectOp : public DrawStrokableOp {
-public:
-    DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint)
-            : DrawStrokableOp(left, top, right, bottom, paint) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
-                mLocalBounds.right, mLocalBounds.bottom, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Rect " RECT_STRING, RECT_ARGS(mLocalBounds));
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        DrawStrokableOp::onDefer(renderer, deferInfo, state);
-        deferInfo.opaqueOverBounds = isOpaqueOverBounds(state) &&
-                mPaint->getStyle() == SkPaint::kFill_Style;
-    }
-
-    virtual const char* name() override { return "DrawRect"; }
-};
-
-class DrawRectsOp : public DrawBoundedOp {
-public:
-    DrawRectsOp(const float* rects, int count, const SkPaint* paint)
-            : DrawBoundedOp(rects, count, paint),
-            mRects(rects), mCount(count) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawRects(mRects, mCount, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Rects count %d", mCount);
-    }
-
-    virtual const char* name() override { return "DrawRects"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_Vertices;
-    }
-
-private:
-    const float* mRects;
-    int mCount;
-};
-
-class DrawRoundRectOp : public DrawStrokableOp {
-public:
-    DrawRoundRectOp(float left, float top, float right, float bottom,
-            float rx, float ry, const SkPaint* paint)
-            : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
-                mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw RoundRect " RECT_STRING ", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        DrawStrokableOp::onDefer(renderer, deferInfo, state);
-        if (!mPaint->getPathEffect()) {
-            renderer.getCaches().tessellationCache.precacheRoundRect(state.mMatrix, *mPaint,
-                    mLocalBounds.getWidth(), mLocalBounds.getHeight(), mRx, mRy);
-        }
-    }
-
-    virtual const char* name() override { return "DrawRoundRect"; }
-
-private:
-    float mRx;
-    float mRy;
-};
-
-class DrawRoundRectPropsOp : public DrawOp {
-public:
-    DrawRoundRectPropsOp(float* left, float* top, float* right, float* bottom,
-            float *rx, float *ry, const SkPaint* paint)
-            : DrawOp(paint), mLeft(left), mTop(top), mRight(right), mBottom(bottom),
-            mRx(rx), mRy(ry) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawRoundRect(*mLeft, *mTop, *mRight, *mBottom,
-                *mRx, *mRy, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw RoundRect Props " RECT_STRING ", rx %f, ry %f",
-                *mLeft, *mTop, *mRight, *mBottom, *mRx, *mRy);
-    }
-
-    virtual const char* name() override { return "DrawRoundRectProps"; }
-
-private:
-    float* mLeft;
-    float* mTop;
-    float* mRight;
-    float* mBottom;
-    float* mRx;
-    float* mRy;
-};
-
-class DrawCircleOp : public DrawStrokableOp {
-public:
-    DrawCircleOp(float x, float y, float radius, const SkPaint* paint)
-            : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
-            mX(x), mY(y), mRadius(radius) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawCircle(mX, mY, mRadius, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
-    }
-
-    virtual const char* name() override { return "DrawCircle"; }
-
-private:
-    float mX;
-    float mY;
-    float mRadius;
-};
-
-class DrawCirclePropsOp : public DrawOp {
-public:
-    DrawCirclePropsOp(float* x, float* y, float* radius, const SkPaint* paint)
-            : DrawOp(paint), mX(x), mY(y), mRadius(radius) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawCircle(*mX, *mY, *mRadius, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Circle Props x %p, y %p, r %p", mX, mY, mRadius);
-    }
-
-    virtual const char* name() override { return "DrawCircleProps"; }
-
-private:
-    float* mX;
-    float* mY;
-    float* mRadius;
-};
-
-class DrawVectorDrawableOp : public DrawOp {
-public:
-    DrawVectorDrawableOp(VectorDrawableRoot* tree, const SkRect& bounds)
-            : DrawOp(nullptr), mTree(tree), mDst(bounds) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        const SkBitmap& bitmap = mTree->getBitmapUpdateIfDirty();
-        SkPaint* paint = mTree->getPaint();
-        renderer.drawBitmap(&bitmap, Rect(0, 0, bitmap.width(), bitmap.height()),
-                mDst, paint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Vector Drawable %p", mTree);
-    }
-
-    virtual const char* name() override { return "DrawVectorDrawable"; }
-
-private:
-    VectorDrawableRoot* mTree;
-    SkRect mDst;
-
-};
-
-class DrawOvalOp : public DrawStrokableOp {
-public:
-    DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint)
-            : DrawStrokableOp(left, top, right, bottom, paint) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
-                mLocalBounds.right, mLocalBounds.bottom, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Oval " RECT_STRING, RECT_ARGS(mLocalBounds));
-    }
-
-    virtual const char* name() override { return "DrawOval"; }
-};
-
-class DrawArcOp : public DrawStrokableOp {
-public:
-    DrawArcOp(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint)
-            : DrawStrokableOp(left, top, right, bottom, paint),
-            mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
-                mLocalBounds.right, mLocalBounds.bottom,
-                mStartAngle, mSweepAngle, mUseCenter, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Arc " RECT_STRING ", start %f, sweep %f, useCenter %d",
-                RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
-    }
-
-    virtual const char* name() override { return "DrawArc"; }
-
-private:
-    float mStartAngle;
-    float mSweepAngle;
-    bool mUseCenter;
-};
-
-class DrawPathOp : public DrawBoundedOp {
-public:
-    DrawPathOp(const SkPath* path, const SkPaint* paint)
-            : DrawBoundedOp(paint), mPath(path) {
-        float left, top, offset;
-        uint32_t width, height;
-        PathCache::computePathBounds(path, paint, left, top, offset, width, height);
-        left -= offset;
-        top -= offset;
-        mLocalBounds.set(left, top, left + width, top + height);
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawPath(mPath, mPaint);
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        renderer.getCaches().pathCache.precache(mPath, mPaint);
-
-        deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Path %p in " RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
-    }
-
-    virtual const char* name() override { return "DrawPath"; }
-
-private:
-    const SkPath* mPath;
-};
-
-class DrawLinesOp : public DrawBoundedOp {
-public:
-    DrawLinesOp(const float* points, int count, const SkPaint* paint)
-            : DrawBoundedOp(points, count, paint),
-            mPoints(points), mCount(count) {
-        mLocalBounds.outset(strokeWidthOutset());
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawLines(mPoints, mCount, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Lines count %d", mCount);
-    }
-
-    virtual const char* name() override { return "DrawLines"; }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        deferInfo.batchId = mPaint->isAntiAlias() ?
-                DeferredDisplayList::kOpBatch_AlphaVertices :
-                DeferredDisplayList::kOpBatch_Vertices;
-    }
-
-protected:
-    const float* mPoints;
-    int mCount;
-};
-
-class DrawPointsOp : public DrawLinesOp {
-public:
-    DrawPointsOp(const float* points, int count, const SkPaint* paint)
-            : DrawLinesOp(points, count, paint) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawPoints(mPoints, mCount, mPaint);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Points count %d", mCount);
-    }
-
-    virtual const char* name() override { return "DrawPoints"; }
-};
-
-class DrawSomeTextOp : public DrawOp {
-public:
-    DrawSomeTextOp(const glyph_t* text, int bytesCount, int count, const SkPaint* paint)
-            : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw some text, %d bytes", mBytesCount);
-    }
-
-    virtual bool hasTextShadow() const override {
-        return PaintUtils::hasTextShadow(mPaint);
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        FontRenderer& fontRenderer = renderer.getCaches().fontRenderer.getFontRenderer();
-        fontRenderer.precache(mPaint, mText, mCount, SkMatrix::I());
-
-        deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
-                DeferredDisplayList::kOpBatch_Text :
-                DeferredDisplayList::kOpBatch_ColorText;
-    }
-
-protected:
-    const glyph_t* mText;
-    int mBytesCount;
-    int mCount;
-};
-
-class DrawTextOnPathOp : public DrawSomeTextOp {
-public:
-    DrawTextOnPathOp(const glyph_t* text, int bytesCount, int count,
-            const SkPath* path, float hOffset, float vOffset, const SkPaint* paint)
-            : DrawSomeTextOp(text, bytesCount, count, paint),
-            mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
-        /* TODO: inherit from DrawBounded and init mLocalBounds */
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
-                mHOffset, mVOffset, mPaint);
-    }
-
-    virtual const char* name() override { return "DrawTextOnPath"; }
-
-private:
-    const SkPath* mPath;
-    float mHOffset;
-    float mVOffset;
-};
-
-class DrawTextOp : public DrawStrokableOp {
-public:
-    DrawTextOp(const glyph_t* text, int bytesCount, int count, float x, float y,
-            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds)
-            : DrawStrokableOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
-            mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
-        mPrecacheTransform = SkMatrix::InvalidMatrix();
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        FontRenderer& fontRenderer = renderer.getCaches().fontRenderer.getFontRenderer();
-        SkMatrix transform;
-        renderer.findBestFontTransform(state.mMatrix, &transform);
-        if (mPrecacheTransform != transform) {
-            fontRenderer.precache(mPaint, mText, mCount, transform);
-            mPrecacheTransform = transform;
-        }
-        deferInfo.batchId = mPaint->getColor() == SK_ColorBLACK ?
-                DeferredDisplayList::kOpBatch_Text :
-                DeferredDisplayList::kOpBatch_ColorText;
-
-        deferInfo.mergeId = reinterpret_cast<mergeid_t>(mPaint->getColor());
-
-        // don't merge decorated text - the decorations won't draw in order
-        bool hasDecorations = mPaint->getFlags()
-                & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag);
-
-        deferInfo.mergeable = state.mMatrix.isPureTranslate()
-                && !hasDecorations
-                && PaintUtils::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        Rect bounds;
-        getLocalBounds(bounds);
-        renderer.drawText(mText, mBytesCount, mCount, mX, mY,
-                mPositions, mPaint, mTotalAdvance, bounds);
-    }
-
-    virtual void multiDraw(OpenGLRenderer& renderer, Rect& dirty,
-            const std::vector<OpStatePair>& ops, const Rect& bounds) override {
-        for (unsigned int i = 0; i < ops.size(); i++) {
-            const DeferredDisplayState& state = *(ops[i].state);
-            DrawOpMode drawOpMode = (i == ops.size() - 1) ? DrawOpMode::kFlush : DrawOpMode::kDefer;
-            renderer.restoreDisplayState(state, true); // restore all but the clip
-
-            DrawTextOp& op = *((DrawTextOp*)ops[i].op);
-            // quickReject() will not occure in drawText() so we can use mLocalBounds
-            // directly, we do not need to account for shadow by calling getLocalBounds()
-            renderer.drawText(op.mText, op.mBytesCount, op.mCount, op.mX, op.mY,
-                    op.mPositions, op.mPaint, op.mTotalAdvance, op.mLocalBounds,
-                    drawOpMode);
-        }
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
-    }
-
-    virtual const char* name() override { return "DrawText"; }
-
-private:
-    const glyph_t* mText;
-    int mBytesCount;
-    int mCount;
-    float mX;
-    float mY;
-    const float* mPositions;
-    float mTotalAdvance;
-    SkMatrix mPrecacheTransform;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// SPECIAL DRAW OPERATIONS
-///////////////////////////////////////////////////////////////////////////////
-
-class DrawFunctorOp : public DrawOp {
-public:
-    DrawFunctorOp(Functor* functor)
-            : DrawOp(nullptr), mFunctor(functor) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.startMark("GL functor");
-        renderer.callDrawGLFunction(mFunctor, dirty);
-        renderer.endMark();
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Functor %p", mFunctor);
-    }
-
-    virtual const char* name() override { return "DrawFunctor"; }
-
-private:
-    Functor* mFunctor;
-};
-
-class DrawRenderNodeOp : public DrawBoundedOp {
-    friend class RenderNode; // grant RenderNode access to info of child
-    friend class DisplayList; // grant DisplayList access to info of child
-    friend class DisplayListCanvas;
-    friend class TestUtils;
-public:
-    DrawRenderNodeOp(RenderNode* renderNode, const mat4& transformFromParent, bool clipIsSimple)
-            : DrawBoundedOp(0, 0,
-                    renderNode->stagingProperties().getWidth(),
-                    renderNode->stagingProperties().getHeight(),
-                    nullptr)
-            , renderNode(renderNode)
-            , mRecordedWithPotentialStencilClip(!clipIsSimple || !transformFromParent.isSimple())
-            , localMatrix(transformFromParent)
-            , skipInOrderDraw(false) {}
-
-    virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        if (renderNode->isRenderable() && !skipInOrderDraw) {
-            renderNode->defer(deferStruct, level + 1);
-        }
-    }
-
-    virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
-            bool useQuickReject) override {
-        if (renderNode->isRenderable() && !skipInOrderDraw) {
-            renderNode->replay(replayStruct, level + 1);
-        }
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        LOG_ALWAYS_FATAL("should not be called, because replay() is overridden");
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw RenderNode %p %s", renderNode, renderNode->getName());
-        if (renderNode && (logFlags & kOpLogFlag_Recurse)) {
-            renderNode->output(level + 1);
-        }
-    }
-
-    virtual const char* name() override { return "DrawRenderNode"; }
-
-private:
-    RenderNode* renderNode;
-
-    /**
-     * This RenderNode was drawn into a DisplayList with the canvas in a state that will likely
-     * require rendering with stencil clipping. Either:
-     *
-     * 1) A path clip or rotated rect clip was in effect on the canvas at record time
-     * 2) The RenderNode was recorded with a non-simple canvas transform (e.g. rotation)
-     *
-     * Note: even if this is false, non-rect clipping may still be applied applied either due to
-     * property-driven rotation (either in this RenderNode, or any ancestor), or record time
-     * clipping in an ancestor. These are handled in RenderNode::prepareTreeImpl since they are
-     * dynamic (relative to a static DisplayList of a parent), and don't affect this flag.
-     */
-    bool mRecordedWithPotentialStencilClip;
-
-    ///////////////////////////
-    // Properties below are used by RenderNode::computeOrderingImpl() and issueOperations()
-    ///////////////////////////
-    /**
-     * Records transform vs parent, used for computing total transform without rerunning DL contents
-     */
-    const mat4 localMatrix;
-
-    /**
-     * Holds the transformation between the projection surface ViewGroup and this RenderNode
-     * drawing instance. Represents any translations / transformations done within the drawing of
-     * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
-     * DisplayList draw instance.
-     *
-     * Note: doesn't include transformation within the RenderNode, or its properties.
-     */
-    mat4 transformFromCompositingAncestor;
-    bool skipInOrderDraw;
-};
-
-/**
- * Not a canvas operation, used only by 3d / z ordering logic in RenderNode::iterate()
- */
-class DrawShadowOp : public DrawOp {
-public:
-    DrawShadowOp(const mat4& transformXY, const mat4& transformZ,
-            float casterAlpha, const SkPath* casterOutline)
-        : DrawOp(nullptr)
-        , mTransformXY(transformXY)
-        , mTransformZ(transformZ)
-        , mCasterAlpha(casterAlpha)
-        , mCasterOutline(casterOutline) {
-    }
-
-    virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
-            const DeferredDisplayState& state) override {
-        renderer.getCaches().tessellationCache.precacheShadows(&state.mMatrix,
-                renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline,
-                &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius());
-    }
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        TessellationCache::vertexBuffer_pair_t buffers;
-        Matrix4 drawTransform(*(renderer.currentTransform()));
-        renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform,
-                renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline,
-                &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(),
-                buffers);
-
-        renderer.drawShadow(mCasterAlpha, buffers.first, buffers.second);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOGS("DrawShadow");
-    }
-
-    virtual const char* name() override { return "DrawShadow"; }
-
-private:
-    bool isCasterOpaque() { return mCasterAlpha >= 1.0f; }
-
-    const mat4 mTransformXY;
-    const mat4 mTransformZ;
-    const float mCasterAlpha;
-    const SkPath* mCasterOutline;
-};
-
-class DrawLayerOp : public DrawOp {
-public:
-    DrawLayerOp(Layer* layer)
-            : DrawOp(nullptr), mLayer(layer) {}
-
-    virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override {
-        renderer.drawLayer(mLayer);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("Draw Layer %p", mLayer);
-    }
-
-    virtual const char* name() override { return "DrawLayer"; }
-
-private:
-    Layer* mLayer;
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_DISPLAY_OPERATION_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 276c18d..25dc92c 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -16,6 +16,9 @@
 
 #include "FontRenderer.h"
 
+#include "BakedOpDispatcher.h"
+#include "BakedOpRenderer.h"
+#include "BakedOpState.h"
 #include "Caches.h"
 #include "Debug.h"
 #include "Extensions.h"
@@ -27,15 +30,6 @@
 #include "utils/Blur.h"
 #include "utils/Timing.h"
 
-
-#if HWUI_NEW_OPS
-#include "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "BakedOpState.h"
-#else
-#include "OpenGLRenderer.h"
-#endif
-
 #include <algorithm>
 #include <cutils/properties.h>
 #include <SkGlyph.h>
@@ -67,7 +61,6 @@
     int transformFlags = pureTranslate
             ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None;
     Glop glop;
-#if HWUI_NEW_OPS
     GlopBuilder(renderer->renderState(), renderer->caches(), &glop)
             .setRoundRectClipState(bakedState->roundRectClipState)
             .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
@@ -77,16 +70,6 @@
             .build();
     // Note: don't pass dirty bounds here, so user must manage passing dirty bounds to renderer
     renderer->renderGlop(nullptr, clip, glop);
-#else
-    GlopBuilder(renderer->mRenderState, renderer->mCaches, &glop)
-            .setRoundRectClipState(renderer->currentSnapshot()->roundRectClipState)
-            .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
-            .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, renderer->currentSnapshot()->alpha)
-            .setTransform(*(renderer->currentSnapshot()), transformFlags)
-            .setModelViewOffsetRect(0, 0, Rect())
-            .build();
-    renderer->renderGlop(glop);
-#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index e10a81b..dedc494 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_FONT_RENDERER_H
-#define ANDROID_HWUI_FONT_RENDERER_H
+#pragma once
 
 #include "font/FontUtil.h"
 #include "font/CacheTexture.h"
@@ -44,31 +43,21 @@
 namespace android {
 namespace uirenderer {
 
-#if HWUI_NEW_OPS
 class BakedOpState;
 class BakedOpRenderer;
 struct ClipBase;
-#else
-class OpenGLRenderer;
-#endif
 
 class TextDrawFunctor {
 public:
     TextDrawFunctor(
-#if HWUI_NEW_OPS
             BakedOpRenderer* renderer,
             const BakedOpState* bakedState,
             const ClipBase* clip,
-#else
-            OpenGLRenderer* renderer,
-#endif
             float x, float y, bool pureTranslate,
             int alpha, SkXfermode::Mode mode, const SkPaint* paint)
         : renderer(renderer)
-#if HWUI_NEW_OPS
         , bakedState(bakedState)
         , clip(clip)
-#endif
         , x(x)
         , y(y)
         , pureTranslate(pureTranslate)
@@ -79,13 +68,9 @@
 
     void draw(CacheTexture& texture, bool linearFiltering);
 
-#if HWUI_NEW_OPS
     BakedOpRenderer* renderer;
     const BakedOpState* bakedState;
     const ClipBase* clip;
-#else
-    OpenGLRenderer* renderer;
-#endif
     float x;
     float y;
     bool pureTranslate;
@@ -218,5 +203,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_FONT_RENDERER_H
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 37d9d0e7..be4fdac 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -477,7 +477,7 @@
         projectionReceiverOutline->transform(
                 skCurrentTransform,
                 &transformedMaskPath);
-        mCanvasState.setProjectionPathMask(mAllocator, &transformedMaskPath);
+        mCanvasState.setProjectionPathMask(&transformedMaskPath);
     }
 
     for (size_t i = 0; i < renderNode.mProjectedNodes.size(); i++) {
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index adadd32..570322d 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -15,11 +15,7 @@
  */
 #include "FrameInfoVisualizer.h"
 
-#if HWUI_NEW_OPS
 #include "BakedOpRenderer.h"
-#else
-#include "OpenGLRenderer.h"
-#endif
 #include "utils/Color.h"
 
 #include <cutils/compiler.h>
diff --git a/libs/hwui/FrameInfoVisualizer.h b/libs/hwui/FrameInfoVisualizer.h
index 83adf19..fc958b8 100644
--- a/libs/hwui/FrameInfoVisualizer.h
+++ b/libs/hwui/FrameInfoVisualizer.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef DRAWPROFILER_H
-#define DRAWPROFILER_H
+
+#pragma once
 
 #include "FrameInfo.h"
 #include "Properties.h"
@@ -28,13 +28,8 @@
 namespace android {
 namespace uirenderer {
 
-#if HWUI_NEW_OPS
 class BakedOpRenderer;
 typedef BakedOpRenderer ContentRenderer;
-#else
-class OpenGLRenderer;
-typedef OpenGLRenderer ContentRenderer;
-#endif
 
 // TODO: This is a bit awkward as it needs to match the thing in CanvasContext
 // A better abstraction here would be nice but iterators are painful
@@ -93,5 +88,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* DRAWPROFILER_H */
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 6433c86..46dd598 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_GLOP_H
-#define ANDROID_HWUI_GLOP_H
+#pragma once
 
 #include "FloatColor.h"
 #include "Matrix.h"
@@ -68,7 +67,7 @@
         OffsetByFudgeFactor = 1 << 0,
 
         // Canvas transform isn't applied to the mesh at draw time,
-        //since it's already built in.
+        // since it's already built in.
         MeshIgnoresCanvasTransform = 1 << 1, // TODO: remove for HWUI_NEW_OPS
     };
 };
@@ -168,14 +167,6 @@
         GLenum dst;
     } blend;
 
-#if !HWUI_NEW_OPS
-    /**
-     * Bounds of the drawing command in layer space. Only mapped into layer
-     * space once GlopBuilder::build() is called.
-     */
-    Rect bounds; // TODO: remove for HWUI_NEW_OPS
-#endif
-
     /**
      * Additional render state to enumerate:
      * - scissor + (bits for whether each of LTRB needed?)
@@ -185,5 +176,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif // ANDROID_HWUI_GLOP_H
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index e502725..1091736 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -17,8 +17,10 @@
 
 #include "Caches.h"
 #include "Glop.h"
+#include "Layer.h"
 #include "Matrix.h"
 #include "Patch.h"
+#include "PathCache.h"
 #include "renderstate/MeshState.h"
 #include "renderstate/RenderState.h"
 #include "SkiaShader.h"
@@ -165,20 +167,6 @@
     return *this;
 }
 
-GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int elementCount) {
-    TRIGGER_STAGE(kMeshStage);
-
-    mOutGlop->mesh.primitiveMode = GL_TRIANGLES;
-    mOutGlop->mesh.indices = { 0, nullptr };
-    mOutGlop->mesh.vertices = {
-            0,
-            VertexAttribFlags::TextureCoord,
-            &vertexData[0].x, &vertexData[0].u, nullptr,
-            kTextureVertexStride };
-    mOutGlop->mesh.elementCount = elementCount;
-    return *this;
-}
-
 GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) {
     TRIGGER_STAGE(kMeshStage);
 
@@ -514,9 +502,6 @@
 
     mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f);
     mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
-#if !HWUI_NEW_OPS
-    mOutGlop->bounds = destination;
-#endif
     return *this;
 }
 
@@ -540,9 +525,6 @@
 
     mOutGlop->transform.modelView.loadTranslate(left, top, 0.0f);
     mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f);
-#if !HWUI_NEW_OPS
-    mOutGlop->bounds = destination;
-#endif
     return *this;
 }
 
@@ -550,10 +532,6 @@
     TRIGGER_STAGE(kModelViewStage);
 
     mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
-#if !HWUI_NEW_OPS
-    mOutGlop->bounds = source;
-    mOutGlop->bounds.translate(offsetX, offsetY);
-#endif
     return *this;
 }
 
@@ -573,10 +551,6 @@
     }
 
     mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
-#if !HWUI_NEW_OPS
-    mOutGlop->bounds = source;
-    mOutGlop->bounds.translate(offsetX, offsetY);
-#endif
     return *this;
 }
 
@@ -676,9 +650,6 @@
 
     // Final step: populate program and map bounds into render target space
     mOutGlop->fill.program = mCaches.programCache.get(mDescription);
-#if !HWUI_NEW_OPS
-    mOutGlop->transform.meshTransform().mapRect(mOutGlop->bounds);
-#endif
 }
 
 void GlopBuilder::dump(const Glop& glop) {
@@ -718,9 +689,6 @@
     ALOGD_IF(glop.roundRectClipState, "Glop RRCS %p", glop.roundRectClipState);
 
     ALOGD("Glop blend %d %d", glop.blend.src, glop.blend.dst);
-#if !HWUI_NEW_OPS
-    ALOGD("Glop bounds " RECT_STRING, RECT_ARGS(glop.bounds));
-#endif
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 1c520c2..1152461 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -13,11 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef RENDERSTATE_GLOPBUILDER_H
-#define RENDERSTATE_GLOPBUILDER_H
+
+#pragma once
 
 #include "Glop.h"
-#include "OpenGLRenderer.h"
 #include "Program.h"
 #include "renderstate/Blend.h"
 #include "utils/Macros.h"
@@ -30,9 +29,13 @@
 
 class Caches;
 class Matrix4;
+class Patch;
 class RenderState;
 class Texture;
+class UvMapper;
 class VertexBuffer;
+struct PathTexture;
+struct ShadowTexture;
 
 namespace TextureFillFlags {
     enum {
@@ -53,7 +56,6 @@
     GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs);
     GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer);
     GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount);
-    GlopBuilder& setMeshTexturedMesh(TextureVertex* vertexData, int elementCount); // TODO: delete
     GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); // TODO: use indexed quads
     GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount
     GlopBuilder& setMeshPatchQuads(const Patch& patch);
@@ -75,9 +77,6 @@
     // Similarly setFillLayer normally forces its own wrap & filter mode
     GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
 
-    GlopBuilder& setTransform(const Snapshot& snapshot, const int transformFlags) {
-        return setTransform(*snapshot.transform, transformFlags);
-    }
     GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
 
     GlopBuilder& setModelViewMapUnitToRect(const Rect destination);
@@ -133,5 +132,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif // RENDERSTATE_GLOPBUILDER_H
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index cdbbbab..8c797d5e 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -17,9 +17,6 @@
 #include "Layer.h"
 
 #include "Caches.h"
-#include "DeferredDisplayList.h"
-#include "LayerRenderer.h"
-#include "OpenGLRenderer.h"
 #include "RenderNode.h"
 #include "renderstate/RenderState.h"
 #include "utils/TraceUtils.h"
@@ -35,13 +32,12 @@
 namespace android {
 namespace uirenderer {
 
-Layer::Layer(Type layerType, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
+Layer::Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight)
         : GpuMemoryTracker(GpuObjectType::Layer)
         , state(State::Uncached)
         , caches(Caches::getInstance())
         , renderState(renderState)
-        , texture(caches)
-        , type(layerType) {
+        , texture(caches) {
     // TODO: This is a violation of Android's typical ref counting, but it
     // preserves the old inc/dec ref locations. This should be changed...
     incStrong(nullptr);
@@ -55,8 +51,7 @@
     renderState.unregisterLayer(this);
     SkSafeUnref(colorFilter);
 
-    if (stencil || fbo || texture.mId) {
-        removeFbo();
+    if (texture.mId) {
         texture.deleteTexture();
     }
 
@@ -64,116 +59,9 @@
 }
 
 void Layer::onGlContextLost() {
-    removeFbo();
     texture.deleteTexture();
 }
 
-uint32_t Layer::computeIdealWidth(uint32_t layerWidth) {
-    return uint32_t(ceilf(layerWidth / float(LAYER_SIZE)) * LAYER_SIZE);
-}
-
-uint32_t Layer::computeIdealHeight(uint32_t layerHeight) {
-    return uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE);
-}
-
-void Layer::requireRenderer() {
-    if (!renderer) {
-        renderer.reset(new LayerRenderer(renderState, this));
-        renderer->initProperties();
-    }
-}
-
-void Layer::updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer) {
-    if (renderer && rendererLightPosDirty) {
-        // re-init renderer's light position, based upon last cached location in window
-        Vector3 lightPos = rootRenderer.getLightCenter();
-        cachedInvTransformInWindow.mapPoint3d(lightPos);
-        renderer->initLight(rootRenderer.getLightRadius(),
-                rootRenderer.getAmbientShadowAlpha(),
-                rootRenderer.getSpotShadowAlpha());
-        renderer->setLightCenter(lightPos);
-        rendererLightPosDirty = false;
-    }
-}
-
-bool Layer::resize(const uint32_t width, const uint32_t height) {
-    uint32_t desiredWidth = computeIdealWidth(width);
-    uint32_t desiredHeight = computeIdealWidth(height);
-
-    if (desiredWidth <= getWidth() && desiredHeight <= getHeight()) {
-        return true;
-    }
-
-    ATRACE_NAME("resizeLayer");
-
-    const uint32_t maxTextureSize = caches.maxTextureSize;
-    if (desiredWidth > maxTextureSize || desiredHeight > maxTextureSize) {
-        ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
-                desiredWidth, desiredHeight, maxTextureSize, maxTextureSize);
-        return false;
-    }
-
-    uint32_t oldWidth = getWidth();
-    uint32_t oldHeight = getHeight();
-
-    setSize(desiredWidth, desiredHeight);
-
-    if (fbo) {
-        caches.textureState().activateTexture(0);
-        bindTexture();
-        allocateTexture();
-
-        if (glGetError() != GL_NO_ERROR) {
-            setSize(oldWidth, oldHeight);
-            return false;
-        }
-    }
-
-    if (stencil) {
-        stencil->bind();
-        stencil->resize(desiredWidth, desiredHeight);
-
-        if (glGetError() != GL_NO_ERROR) {
-            setSize(oldWidth, oldHeight);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-void Layer::removeFbo(bool flush) {
-    if (stencil) {
-        GLuint previousFbo = renderState.getFramebuffer();
-        renderState.bindFramebuffer(fbo);
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
-        renderState.bindFramebuffer(previousFbo);
-
-        caches.renderBufferCache.put(stencil);
-        stencil = nullptr;
-    }
-
-    if (fbo) {
-        if (flush) LayerRenderer::flushLayer(renderState, this);
-        renderState.deleteFramebuffer(fbo);
-        fbo = 0;
-    }
-}
-
-void Layer::updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom) {
-    requireRenderer();
-    this->renderNode = renderNode;
-    const Rect r(left, top, right, bottom);
-    dirtyRect.unionWith(r);
-    deferredUpdateScheduled = true;
-}
-
-void Layer::setPaint(const SkPaint* paint) {
-    alpha = PaintUtils::getAlphaDirect(paint);
-    mode = PaintUtils::getXfermodeDirect(paint);
-    setColorFilter((paint) ? paint->getColorFilter() : nullptr);
-}
-
 void Layer::setColorFilter(SkColorFilter* filter) {
     SkRefCnt_SafeAssign(colorFilter, filter);
 }
@@ -184,12 +72,6 @@
     }
 }
 
-void Layer::bindStencilRenderBuffer() const {
-    if (stencil) {
-        stencil->bind();
-    }
-}
-
 void Layer::generateTexture() {
     if (!texture.mId) {
         glGenTextures(1, &texture.mId);
@@ -206,86 +88,6 @@
     texture.mId = 0;
 }
 
-void Layer::allocateTexture() {
-#if DEBUG_LAYERS
-    ALOGD("  Allocate layer: %dx%d", getWidth(), getHeight());
-#endif
-    if (texture.mId) {
-        texture.updateSize(getWidth(), getHeight(), GL_RGBA);
-        glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
-                GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
-    }
-}
-
-void Layer::defer(const OpenGLRenderer& rootRenderer) {
-    ATRACE_LAYER_WORK("Optimize");
-
-    updateLightPosFromRenderer(rootRenderer);
-    const float width = layer.getWidth();
-    const float height = layer.getHeight();
-
-    if (dirtyRect.isEmpty() || (dirtyRect.left <= 0 && dirtyRect.top <= 0 &&
-            dirtyRect.right >= width && dirtyRect.bottom >= height)) {
-        dirtyRect.set(0, 0, width, height);
-    }
-
-    deferredList.reset(new DeferredDisplayList(dirtyRect));
-
-    DeferStateStruct deferredState(*deferredList, *renderer,
-            RenderNode::kReplayFlag_ClipChildren);
-
-    renderer->setupFrameState(width, height, dirtyRect.left, dirtyRect.top,
-            dirtyRect.right, dirtyRect.bottom, !isBlend());
-
-    renderNode->computeOrdering();
-    renderNode->defer(deferredState, 0);
-
-    deferredUpdateScheduled = false;
-}
-
-void Layer::cancelDefer() {
-    renderNode = nullptr;
-    deferredUpdateScheduled = false;
-    deferredList.reset(nullptr);
-}
-
-void Layer::flush() {
-    // renderer is checked as layer may be destroyed/put in layer cache with flush scheduled
-    if (deferredList && renderer) {
-        ATRACE_LAYER_WORK("Issue");
-        renderer->startMark((renderNode.get() != nullptr) ? renderNode->getName() : "Layer");
-
-        renderer->prepareDirty(layer.getWidth(), layer.getHeight(),
-                dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend());
-
-        deferredList->flush(*renderer, dirtyRect);
-
-        renderer->finish();
-
-        dirtyRect.setEmpty();
-        renderNode = nullptr;
-
-        renderer->endMark();
-    }
-}
-
-void Layer::render(const OpenGLRenderer& rootRenderer) {
-    ATRACE_LAYER_WORK("Direct-Issue");
-
-    updateLightPosFromRenderer(rootRenderer);
-    renderer->prepareDirty(layer.getWidth(), layer.getHeight(),
-            dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend());
-
-    renderer->drawRenderNode(renderNode.get(), dirtyRect, RenderNode::kReplayFlag_ClipChildren);
-
-    renderer->finish();
-
-    dirtyRect.setEmpty();
-
-    deferredUpdateScheduled = false;
-    renderNode = nullptr;
-}
-
 void Layer::postDecStrong() {
     renderState.postDecStrong(this);
 }
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 1e5498b..8ac11d1 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_LAYER_H
-#define ANDROID_HWUI_LAYER_H
+#pragma once
 
 #include <cutils/compiler.h>
 #include <sys/types.h>
@@ -46,22 +45,13 @@
 
 // Forward declarations
 class Caches;
-class RenderNode;
 class RenderState;
-class OpenGLRenderer;
-class DeferredDisplayList;
-struct DeferStateStruct;
 
 /**
  * A layer has dimensions and is backed by an OpenGL texture or FBO.
  */
 class Layer : public VirtualLightRefBase, GpuMemoryTracker {
 public:
-    enum class Type {
-        Texture,
-        DisplayList,
-    };
-
     // layer lifecycle, controlled from outside
     enum class State {
         Uncached = 0,
@@ -73,45 +63,9 @@
     };
     State state; // public for logging/debugging purposes
 
-    Layer(Type type, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
+    Layer(RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
     ~Layer();
 
-    static uint32_t computeIdealWidth(uint32_t layerWidth);
-    static uint32_t computeIdealHeight(uint32_t layerHeight);
-
-    /**
-     * Calling this method will remove (either by recycling or
-     * destroying) the associated FBO, if present, and any render
-     * buffer (stencil for instance.)
-     */
-    void removeFbo(bool flush = true);
-
-    /**
-     * Sets this layer's region to a rectangle. Computes the appropriate
-     * texture coordinates.
-     */
-    void setRegionAsRect() {
-        const android::Rect& bounds = region.getBounds();
-        regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
-               bounds.rightBottom().x, bounds.rightBottom().y);
-
-        const float texX = 1.0f / float(texture.mWidth);
-        const float texY = 1.0f / float(texture.mHeight);
-        const float height = layer.getHeight();
-        texCoords.set(
-               regionRect.left * texX, (height - regionRect.top) * texY,
-               regionRect.right * texX, (height - regionRect.bottom) * texY);
-
-        regionRect.translate(layer.left, layer.top);
-    }
-
-    void setWindowTransform(Matrix4& windowTransform) {
-        cachedInvTransformInWindow.loadInverse(windowTransform);
-        rendererLightPosDirty = true;
-    }
-
-    void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
-
     inline uint32_t getWidth() const {
         return texture.mWidth;
     }
@@ -120,23 +74,10 @@
         return texture.mHeight;
     }
 
-    /**
-     * Resize the layer and its texture if needed.
-     *
-     * @param width The new width of the layer
-     * @param height The new height of the layer
-     *
-     * @return True if the layer was resized or nothing happened, false if
-     *         a failure occurred during the resizing operation
-     */
-    bool resize(const uint32_t width, const uint32_t height);
-
     void setSize(uint32_t width, uint32_t height) {
         texture.updateSize(width, height, texture.format());
     }
 
-    ANDROID_API void setPaint(const SkPaint* paint);
-
     inline void setBlend(bool blend) {
         texture.blend = blend;
     }
@@ -170,36 +111,6 @@
         return mode;
     }
 
-    inline void setEmpty(bool empty) {
-        this->empty = empty;
-    }
-
-    inline bool isEmpty() const {
-        return empty;
-    }
-
-    inline void setFbo(GLuint fbo) {
-        this->fbo = fbo;
-    }
-
-    inline GLuint getFbo() const {
-        return fbo;
-    }
-
-    inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
-        if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
-            this->stencil = renderBuffer;
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
-                    GL_RENDERBUFFER, stencil->getName());
-        } else {
-            ALOGE("The specified render buffer is not a stencil buffer");
-        }
-    }
-
-    inline RenderBuffer* getStencilRenderBuffer() const {
-        return stencil;
-    }
-
     inline GLuint getTextureId() const {
         return texture.id();
     }
@@ -228,52 +139,21 @@
         texture.setFilter(filter, bindTexture, force, renderTarget);
     }
 
-    inline bool isCacheable() const {
-        return cacheable;
-    }
-
-    inline void setCacheable(bool cacheable) {
-        this->cacheable = cacheable;
-    }
-
-    inline bool isDirty() const {
-        return dirty;
-    }
-
-    inline void setDirty(bool dirty) {
-        this->dirty = dirty;
-    }
-
-    inline bool isTextureLayer() const {
-        return type == Type::Texture;
-    }
-
     inline SkColorFilter* getColorFilter() const {
         return colorFilter;
     }
 
-    ANDROID_API void setColorFilter(SkColorFilter* filter);
-
-    inline void setConvexMask(const SkPath* convexMask) {
-        this->convexMask = convexMask;
-    }
-
-    inline const SkPath* getConvexMask() {
-        return convexMask;
-    }
-
-    void bindStencilRenderBuffer() const;
+    void setColorFilter(SkColorFilter* filter);
 
     void bindTexture() const;
     void generateTexture();
-    void allocateTexture();
 
     /**
      * When the caller frees the texture itself, the caller
      * must call this method to tell this layer that it lost
      * the texture.
      */
-    ANDROID_API void clearTexture();
+    void clearTexture();
 
     inline mat4& getTexTransform() {
         return texTransform;
@@ -283,11 +163,6 @@
         return transform;
     }
 
-    void defer(const OpenGLRenderer& rootRenderer);
-    void cancelDefer();
-    void flush();
-    void render(const OpenGLRenderer& rootRenderer);
-
     /**
      * Posts a decStrong call to the appropriate thread.
      * Thread-safe.
@@ -314,79 +189,22 @@
     Rect clipRect;
 
     /**
-     * Dirty region indicating what parts of the layer
-     * have been drawn.
-     */
-    Region region;
-    /**
-     * If the region is a rectangle, coordinates of the
-     * region are stored here.
-     */
-    Rect regionRect;
-
-    /**
      * If the layer can be rendered as a mesh, this is non-null.
      */
     TextureVertex* mesh = nullptr;
     GLsizei meshElementCount = 0;
 
-    /**
-     * Used for deferred updates.
-     */
-    bool deferredUpdateScheduled = false;
-    std::unique_ptr<OpenGLRenderer> renderer;
-    sp<RenderNode> renderNode;
-    Rect dirtyRect;
-    bool debugDrawUpdate = false;
-    bool hasDrawnSinceUpdate = false;
-    bool wasBuildLayered = false;
-
 private:
-    void requireRenderer();
-    void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
-
     Caches& caches;
 
     RenderState& renderState;
 
     /**
-     * Name of the FBO used to render the layer. If the name is 0
-     * this layer is not backed by an FBO, but a simple texture.
-     */
-    GLuint fbo = 0;
-
-    /**
-     * The render buffer used as the stencil buffer.
-     */
-    RenderBuffer* stencil = nullptr;
-
-    /**
-     * Indicates whether this layer has been used already.
-     */
-    bool empty = true;
-
-    /**
      * The texture backing this layer.
      */
     Texture texture;
 
     /**
-     * If set to true (by default), the layer can be reused.
-     */
-    bool cacheable = true;
-
-    /**
-     * Denotes whether the layer is a DisplayList, or Texture layer.
-     */
-    const Type type;
-
-    /**
-     * When set to true, this layer is dirty and should be cleared
-     * before any rendering occurs.
-     */
-    bool dirty = false;
-
-    /**
      * Indicates the render target.
      */
     GLenum renderTarget = GL_TEXTURE_2D;
@@ -421,28 +239,7 @@
      */
     mat4 transform;
 
-    /**
-     * Cached transform of layer in window, updated only on creation / resize
-     */
-    mat4 cachedInvTransformInWindow;
-    bool rendererLightPosDirty = true;
-
-    /**
-     * Used to defer display lists when the layer is updated with a
-     * display list.
-     */
-    std::unique_ptr<DeferredDisplayList> deferredList;
-
-    /**
-     * This convex path should be used to mask the layer's draw to the screen.
-     *
-     * Data not owned/managed by layer object.
-     */
-    const SkPath* convexMask = nullptr;
-
 }; // struct Layer
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_LAYER_H
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
deleted file mode 100644
index f5681ce..0000000
--- a/libs/hwui/LayerCache.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "LayerCache.h"
-
-#include "Caches.h"
-#include "Properties.h"
-
-#include <utils/Log.h>
-
-#include <GLES2/gl2.h>
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-LayerCache::LayerCache()
-        : mSize(0)
-        , mMaxSize(Properties::layerPoolSize) {}
-
-LayerCache::~LayerCache() {
-    clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-size_t LayerCache::getCount() {
-    return mCache.size();
-}
-
-uint32_t LayerCache::getSize() {
-    return mSize;
-}
-
-uint32_t LayerCache::getMaxSize() {
-    return mMaxSize;
-}
-
-void LayerCache::setMaxSize(uint32_t maxSize) {
-    clear();
-    mMaxSize = maxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-int LayerCache::LayerEntry::compare(const LayerCache::LayerEntry& lhs,
-        const LayerCache::LayerEntry& rhs) {
-    int deltaInt = int(lhs.mWidth) - int(rhs.mWidth);
-    if (deltaInt != 0) return deltaInt;
-
-    return int(lhs.mHeight) - int(rhs.mHeight);
-}
-
-void LayerCache::deleteLayer(Layer* layer) {
-    if (layer) {
-        LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
-                layer->getFbo());
-        mSize -= layer->getWidth() * layer->getHeight() * 4;
-        layer->state = Layer::State::DeletedFromCache;
-        layer->decStrong(nullptr);
-    }
-}
-
-void LayerCache::clear() {
-    for (auto entry : mCache) {
-        deleteLayer(entry.mLayer);
-    }
-    mCache.clear();
-}
-
-Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uint32_t height) {
-    Layer* layer = nullptr;
-
-    LayerEntry entry(width, height);
-    auto iter = mCache.find(entry);
-
-    if (iter != mCache.end()) {
-        entry = *iter;
-        mCache.erase(iter);
-
-        layer = entry.mLayer;
-        layer->state = Layer::State::RemovedFromCache;
-        mSize -= layer->getWidth() * layer->getHeight() * 4;
-
-        LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
-    } else {
-        LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight);
-
-        layer = new Layer(Layer::Type::DisplayList, renderState, entry.mWidth, entry.mHeight);
-        layer->setBlend(true);
-        layer->generateTexture();
-        layer->bindTexture();
-        layer->setFilter(GL_NEAREST);
-        layer->setWrap(GL_CLAMP_TO_EDGE, false);
-
-#if DEBUG_LAYERS
-        dump();
-#endif
-    }
-
-    return layer;
-}
-
-void LayerCache::dump() {
-    for (auto entry : mCache) {
-        ALOGD("  Layer size %dx%d", entry.mWidth, entry.mHeight);
-    }
-}
-
-bool LayerCache::put(Layer* layer) {
-    if (!layer->isCacheable()) return false;
-
-    const uint32_t size = layer->getWidth() * layer->getHeight() * 4;
-    // Don't even try to cache a layer that's bigger than the cache
-    if (size < mMaxSize) {
-        // TODO: Use an LRU
-        while (mSize + size > mMaxSize) {
-            Layer* victim = mCache.begin()->mLayer;
-            deleteLayer(victim);
-            mCache.erase(mCache.begin());
-
-            LAYER_LOGD("  Deleting layer %.2fx%.2f", victim->layer.getWidth(),
-                    victim->layer.getHeight());
-        }
-
-        layer->cancelDefer();
-
-        LayerEntry entry(layer);
-
-        mCache.insert(entry);
-        mSize += size;
-
-        layer->state = Layer::State::InCache;
-        return true;
-    }
-
-    layer->state = Layer::State::FailedToCache;
-    return false;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
deleted file mode 100644
index 6fe7b3a..0000000
--- a/libs/hwui/LayerCache.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_LAYER_CACHE_H
-#define ANDROID_HWUI_LAYER_CACHE_H
-
-#include "Debug.h"
-#include "Layer.h"
-
-#include <set>
-
-namespace android {
-namespace uirenderer {
-
-class RenderState;
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-#if DEBUG_LAYERS
-    #define LAYER_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define LAYER_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache
-///////////////////////////////////////////////////////////////////////////////
-
-class LayerCache {
-public:
-    LayerCache();
-    ~LayerCache();
-
-    /**
-     * Returns a layer large enough for the specified dimensions. If no suitable
-     * layer can be found, a new one is created and returned. If creating a new
-     * layer fails, NULL is returned.
-     *
-     * When a layer is obtained from the cache, it is removed and the total
-     * size of the cache goes down.
-     *
-     * @param width The desired width of the layer
-     * @param height The desired height of the layer
-     */
-    Layer* get(RenderState& renderState, const uint32_t width, const uint32_t height);
-
-    /**
-     * Adds the layer to the cache. The layer will not be added if there is
-     * not enough space available. Adding a layer can cause other layers to
-     * be removed from the cache.
-     *
-     * @param layer The layer to add to the cache
-     *
-     * @return True if the layer was added, false otherwise.
-     */
-    bool put(Layer* layer);
-    /**
-     * Clears the cache. This causes all layers to be deleted.
-     */
-    void clear();
-
-    /**
-     * Sets the maximum size of the cache in bytes.
-     */
-    void setMaxSize(uint32_t maxSize);
-    /**
-     * Returns the maximum size of the cache in bytes.
-     */
-    uint32_t getMaxSize();
-    /**
-     * Returns the current size of the cache in bytes.
-     */
-    uint32_t getSize();
-
-    size_t getCount();
-
-    /**
-     * Prints out the content of the cache.
-     */
-    void dump();
-
-private:
-    struct LayerEntry {
-        LayerEntry():
-            mLayer(nullptr), mWidth(0), mHeight(0) {
-        }
-
-        LayerEntry(const uint32_t layerWidth, const uint32_t layerHeight): mLayer(nullptr) {
-            mWidth = Layer::computeIdealWidth(layerWidth);
-            mHeight = Layer::computeIdealHeight(layerHeight);
-        }
-
-        LayerEntry(Layer* layer):
-            mLayer(layer), mWidth(layer->getWidth()), mHeight(layer->getHeight()) {
-        }
-
-        static int compare(const LayerEntry& lhs, const LayerEntry& rhs);
-
-        bool operator==(const LayerEntry& other) const {
-            return compare(*this, other) == 0;
-        }
-
-        bool operator!=(const LayerEntry& other) const {
-            return compare(*this, other) != 0;
-        }
-
-        bool operator<(const LayerEntry& other) const {
-            return LayerEntry::compare(*this, other) < 0;
-        }
-
-        Layer* mLayer;
-        uint32_t mWidth;
-        uint32_t mHeight;
-    }; // struct LayerEntry
-
-    void deleteLayer(Layer* layer);
-
-    std::multiset<LayerEntry> mCache;
-
-    uint32_t mSize;
-    uint32_t mMaxSize;
-}; // class LayerCache
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_LAYER_CACHE_H
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 405165f..8d50dc2 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include "LayerCache.h"
 #include "LayerRenderer.h"
 #include "Matrix.h"
 #include "Properties.h"
@@ -27,257 +26,15 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
-
 namespace android {
 namespace uirenderer {
 
-///////////////////////////////////////////////////////////////////////////////
-// Rendering
-///////////////////////////////////////////////////////////////////////////////
-
-LayerRenderer::LayerRenderer(RenderState& renderState, Layer* layer)
-        : OpenGLRenderer(renderState)
-        , mLayer(layer) {
-}
-
-LayerRenderer::~LayerRenderer() {
-}
-
-void LayerRenderer::prepareDirty(int viewportWidth, int viewportHeight,
-        float left, float top, float right, float bottom, bool opaque) {
-    LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
-
-    mRenderState.bindFramebuffer(mLayer->getFbo());
-
-    const float width = mLayer->layer.getWidth();
-    const float height = mLayer->layer.getHeight();
-
-    Rect dirty(left, top, right, bottom);
-    if (dirty.isEmpty() || (dirty.left <= 0 && dirty.top <= 0 &&
-            dirty.right >= width && dirty.bottom >= height)) {
-        mLayer->region.clear();
-        dirty.set(0.0f, 0.0f, width, height);
-    } else {
-        dirty.doIntersect(0.0f, 0.0f, width, height);
-        android::Rect r(dirty.left, dirty.top, dirty.right, dirty.bottom);
-        mLayer->region.subtractSelf(r);
-    }
-    mLayer->clipRect.set(dirty);
-
-    OpenGLRenderer::prepareDirty(viewportWidth, viewportHeight,
-            dirty.left, dirty.top, dirty.right, dirty.bottom, opaque);
-}
-
-void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
-    if (mLayer->isDirty()) {
-        mRenderState.scissor().setEnabled(false);
-        glClear(GL_COLOR_BUFFER_BIT);
-
-        mRenderState.scissor().reset();
-        mLayer->setDirty(false);
-    } else {
-        OpenGLRenderer::clear(left, top, right, bottom, opaque);
-    }
-}
-
-bool LayerRenderer::finish() {
-    bool retval = OpenGLRenderer::finish();
-
-    generateMesh();
-
-    LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->getFbo());
-
-    // No need to unbind our FBO, this will be taken care of by the caller
-    // who will invoke OpenGLRenderer::resume()
-    return retval;
-}
-
-GLuint LayerRenderer::getTargetFbo() const {
-    return mLayer->getFbo();
-}
-
-bool LayerRenderer::suppressErrorChecks() const {
-    return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Layer support
-///////////////////////////////////////////////////////////////////////////////
-
-bool LayerRenderer::hasLayer() const {
-    return true;
-}
-
-void LayerRenderer::ensureStencilBuffer() {
-    attachStencilBufferToLayer(mLayer);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Dirty region tracking
-///////////////////////////////////////////////////////////////////////////////
-
-Region* LayerRenderer::getRegion() const {
-    if (mState.currentFlags() & Snapshot::kFlagFboTarget) {
-        return OpenGLRenderer::getRegion();
-    }
-    return &mLayer->region;
-}
-
-// TODO: This implementation uses a very simple approach to fixing T-junctions which keeps the
-//       results as rectangles, and is thus not necessarily efficient in the geometry
-//       produced. Eventually, it may be better to develop triangle-based mechanism.
-void LayerRenderer::generateMesh() {
-    if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
-        if (mLayer->mesh) {
-            delete[] mLayer->mesh;
-            mLayer->mesh = nullptr;
-            mLayer->meshElementCount = 0;
-        }
-
-        mLayer->setRegionAsRect();
-        return;
-    }
-
-    // avoid T-junctions as they cause artifacts in between the resultant
-    // geometry when complex transforms occur.
-    // TODO: generate the safeRegion only if necessary based on drawing transform (see
-    // OpenGLRenderer::composeLayerRegion())
-    Region safeRegion = Region::createTJunctionFreeRegion(mLayer->region);
-
-    size_t count;
-    const android::Rect* rects = safeRegion.getArray(&count);
-
-    GLsizei elementCount = count * 6;
-
-    if (mLayer->mesh && mLayer->meshElementCount < elementCount) {
-        delete[] mLayer->mesh;
-        mLayer->mesh = nullptr;
-    }
-
-    if (!mLayer->mesh) {
-        mLayer->mesh = new TextureVertex[count * 4];
-    }
-    mLayer->meshElementCount = elementCount;
-
-    const float texX = 1.0f / float(mLayer->getWidth());
-    const float texY = 1.0f / float(mLayer->getHeight());
-    const float height = mLayer->layer.getHeight();
-
-    TextureVertex* mesh = mLayer->mesh;
-
-    for (size_t i = 0; i < count; i++) {
-        const android::Rect* r = &rects[i];
-
-        const float u1 = r->left * texX;
-        const float v1 = (height - r->top) * texY;
-        const float u2 = r->right * texX;
-        const float v2 = (height - r->bottom) * texY;
-
-        TextureVertex::set(mesh++, r->left, r->top, u1, v1);
-        TextureVertex::set(mesh++, r->right, r->top, u2, v1);
-        TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
-        TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Layers management
-///////////////////////////////////////////////////////////////////////////////
-
-Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height) {
-    ATRACE_FORMAT("Allocate %ux%u HW Layer", width, height);
-    LAYER_RENDERER_LOGD("Requesting new render layer %dx%d", width, height);
-
-    Caches& caches = Caches::getInstance();
-    GLuint fbo = renderState.createFramebuffer();
-    if (!fbo) {
-        ALOGW("Could not obtain an FBO");
-        return nullptr;
-    }
-
-    caches.textureState().activateTexture(0);
-    Layer* layer = caches.layerCache.get(renderState, width, height);
-    if (!layer) {
-        ALOGW("Could not obtain a layer");
-        return nullptr;
-    }
-
-    // We first obtain a layer before comparing against the max texture size
-    // because layers are not allocated at the exact desired size. They are
-    // always created slightly larger to improve recycling
-    const uint32_t maxTextureSize = caches.maxTextureSize;
-    if (layer->getWidth() > maxTextureSize || layer->getHeight() > maxTextureSize) {
-        ALOGW("Layer exceeds max. dimensions supported by the GPU (%dx%d, max=%dx%d)",
-                width, height, maxTextureSize, maxTextureSize);
-
-        // Creating a new layer always increment its refcount by 1, this allows
-        // us to destroy the layer object if one was created for us
-        layer->decStrong(nullptr);
-
-        return nullptr;
-    }
-
-    layer->setFbo(fbo);
-    layer->layer.set(0.0f, 0.0f, width, height);
-    layer->texCoords.set(0.0f, height / float(layer->getHeight()),
-            width / float(layer->getWidth()), 0.0f);
-    layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
-    layer->setColorFilter(nullptr);
-    layer->setDirty(true);
-    layer->region.clear();
-
-    GLuint previousFbo = renderState.getFramebuffer();
-
-    renderState.bindFramebuffer(layer->getFbo());
-    layer->bindTexture();
-
-    // Initialize the texture if needed
-    if (layer->isEmpty()) {
-        layer->setEmpty(false);
-        layer->allocateTexture();
-
-        // This should only happen if we run out of memory
-        if (CC_UNLIKELY(GLUtils::dumpGLErrors())) {
-            LOG_ALWAYS_FATAL("Could not allocate texture for layer (fbo=%d %dx%d)",
-                    fbo, width, height);
-            renderState.bindFramebuffer(previousFbo);
-            layer->decStrong(nullptr);
-            return nullptr;
-        }
-    }
-
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-            layer->getTextureId(), 0);
-
-    renderState.bindFramebuffer(previousFbo);
-
-    return layer;
-}
-
-bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) {
-    if (layer) {
-        LAYER_RENDERER_LOGD("Resizing layer fbo = %d to %dx%d", layer->getFbo(), width, height);
-
-        if (layer->resize(width, height)) {
-            layer->layer.set(0.0f, 0.0f, width, height);
-            layer->texCoords.set(0.0f, height / float(layer->getHeight()),
-                    width / float(layer->getWidth()), 0.0f);
-        } else {
-            return false;
-        }
-    }
-
-    return true;
-}
-
 Layer* LayerRenderer::createTextureLayer(RenderState& renderState) {
     LAYER_RENDERER_LOGD("Creating new texture layer");
 
-    Layer* layer = new Layer(Layer::Type::Texture, renderState, 0, 0);
-    layer->setCacheable(false);
+    Layer* layer = new Layer(renderState, 0, 0);
     layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
     layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f);
-    layer->region.clear();
     layer->setRenderTarget(GL_NONE); // see ::updateTextureLayer()
 
     Caches::getInstance().textureState().activateTexture(0);
@@ -287,69 +44,20 @@
 }
 
 void LayerRenderer::updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
-        bool isOpaque, bool forceFilter, GLenum renderTarget, const float* textureTransform) {
-    if (layer) {
-        layer->setBlend(!isOpaque);
-        layer->setForceFilter(forceFilter);
-        layer->setSize(width, height);
-        layer->layer.set(0.0f, 0.0f, width, height);
-        layer->region.set(width, height);
-        layer->regionRect.set(0.0f, 0.0f, width, height);
-        layer->getTexTransform().load(textureTransform);
+    bool isOpaque, bool forceFilter, GLenum renderTarget, const float* textureTransform) {
+    layer->setBlend(!isOpaque);
+    layer->setForceFilter(forceFilter);
+    layer->setSize(width, height);
+    layer->layer.set(0.0f, 0.0f, width, height);
+    layer->getTexTransform().load(textureTransform);
 
-        if (renderTarget != layer->getRenderTarget()) {
-            layer->setRenderTarget(renderTarget);
-            layer->bindTexture();
-            layer->setFilter(GL_NEAREST, false, true);
-            layer->setWrap(GL_CLAMP_TO_EDGE, false, true);
-        }
+    if (renderTarget != layer->getRenderTarget()) {
+        layer->setRenderTarget(renderTarget);
+        layer->bindTexture();
+        layer->setFilter(GL_NEAREST, false, true);
+        layer->setWrap(GL_CLAMP_TO_EDGE, false, true);
     }
 }
 
-void LayerRenderer::destroyLayer(Layer* layer) {
-    if (layer) {
-        ATRACE_FORMAT("Destroy %ux%u HW Layer", layer->getWidth(), layer->getHeight());
-        LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
-                layer->getWidth(), layer->getHeight(), layer->getFbo());
-
-        if (!Caches::getInstance().layerCache.put(layer)) {
-            LAYER_RENDERER_LOGD("  Destroyed!");
-            layer->decStrong(nullptr);
-        } else {
-            LAYER_RENDERER_LOGD("  Cached!");
-#if DEBUG_LAYER_RENDERER
-            Caches::getInstance().layerCache.dump();
-#endif
-            layer->removeFbo();
-            layer->region.clear();
-        }
-    }
-}
-
-void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) {
-#ifdef GL_EXT_discard_framebuffer
-    if (!layer) return;
-
-    GLuint fbo = layer->getFbo();
-    if (fbo) {
-        // If possible, discard any enqueud operations on deferred
-        // rendering architectures
-        if (Caches::getInstance().extensions().hasDiscardFramebuffer()) {
-            GLuint previousFbo = renderState.getFramebuffer();
-            if (fbo != previousFbo) {
-                renderState.bindFramebuffer(fbo);
-            }
-
-            const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 };
-            glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
-
-            if (fbo != previousFbo) {
-                renderState.bindFramebuffer(previousFbo);
-            }
-        }
-    }
-#endif
-}
-
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 1fb6b14..7460e3e 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -14,12 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_LAYER_RENDERER_H
-#define ANDROID_HWUI_LAYER_RENDERER_H
+#pragma once
 
 #include <cutils/compiler.h>
 
-#include "OpenGLRenderer.h"
 #include "Layer.h"
 
 #include <SkBitmap.h>
@@ -44,40 +42,12 @@
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
 
-class LayerRenderer: public OpenGLRenderer {
+class LayerRenderer {
 public:
-    LayerRenderer(RenderState& renderState, Layer* layer);
-    virtual ~LayerRenderer();
-
-    virtual void onViewportInitialized() override { /* do nothing */ }
-    virtual void prepareDirty(int viewportWidth, int viewportHeight,
-            float left, float top, float right, float bottom, bool opaque) override;
-    virtual void clear(float left, float top, float right, float bottom, bool opaque) override;
-    virtual bool finish() override;
-
     static Layer* createTextureLayer(RenderState& renderState);
-    static Layer* createRenderLayer(RenderState& renderState, uint32_t width, uint32_t height);
-    static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
     static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
             bool isOpaque, bool forceFilter, GLenum renderTarget, const float* textureTransform);
-    static void destroyLayer(Layer* layer);
-
-    static void flushLayer(RenderState& renderState, Layer* layer);
-
-protected:
-    virtual void ensureStencilBuffer() override;
-    virtual bool hasLayer() const override;
-    virtual Region* getRegion() const override;
-    virtual GLuint getTargetFbo() const override;
-    virtual bool suppressErrorChecks() const override;
-
-private:
-    void generateMesh();
-
-    Layer* mLayer;
 }; // class LayerRenderer
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_LAYER_RENDERER_H
diff --git a/libs/hwui/OpDumper.cpp b/libs/hwui/OpDumper.cpp
index ec9ffde..f4b7ee0 100644
--- a/libs/hwui/OpDumper.cpp
+++ b/libs/hwui/OpDumper.cpp
@@ -16,6 +16,7 @@
 
 #include "OpDumper.h"
 
+#include "ClipArea.h"
 #include "RecordedOp.h"
 
 namespace android {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
deleted file mode 100644
index 9d821f3..0000000
--- a/libs/hwui/OpenGLRenderer.cpp
+++ /dev/null
@@ -1,2451 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <GpuMemoryTracker.h>
-#include "OpenGLRenderer.h"
-
-#include "DeferredDisplayList.h"
-#include "GammaFontRenderer.h"
-#include "Glop.h"
-#include "GlopBuilder.h"
-#include "Patch.h"
-#include "PathTessellator.h"
-#include "Properties.h"
-#include "RenderNode.h"
-#include "renderstate/MeshState.h"
-#include "renderstate/RenderState.h"
-#include "ShadowTessellator.h"
-#include "SkiaShader.h"
-#include "Vector.h"
-#include "VertexBuffer.h"
-#include "hwui/Canvas.h"
-#include "utils/GLUtils.h"
-#include "utils/PaintUtils.h"
-#include "utils/TraceUtils.h"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <SkColor.h>
-#include <SkPaintDefaults.h>
-#include <SkPathOps.h>
-#include <SkShader.h>
-#include <SkTypeface.h>
-
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <private/hwui/DrawGlInfo.h>
-
-#include <ui/Rect.h>
-
-#if DEBUG_DETAILED_EVENTS
-    #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__)
-#else
-    #define EVENT_LOGD(...)
-#endif
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-OpenGLRenderer::OpenGLRenderer(RenderState& renderState)
-        : mState(*this)
-        , mCaches(Caches::getInstance())
-        , mRenderState(renderState)
-        , mFrameStarted(false)
-        , mScissorOptimizationDisabled(false)
-        , mDirty(false)
-        , mLightCenter((Vector3){FLT_MIN, FLT_MIN, FLT_MIN})
-        , mLightRadius(FLT_MIN)
-        , mAmbientShadowAlpha(0)
-        , mSpotShadowAlpha(0) {
-}
-
-OpenGLRenderer::~OpenGLRenderer() {
-    // The context has already been destroyed at this point, do not call
-    // GL APIs. All GL state should be kept in Caches.h
-}
-
-void OpenGLRenderer::initProperties() {
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get(PROPERTY_DISABLE_SCISSOR_OPTIMIZATION, property, "false")) {
-        mScissorOptimizationDisabled = !strcasecmp(property, "true");
-        INIT_LOGD("  Scissor optimization %s",
-                mScissorOptimizationDisabled ? "disabled" : "enabled");
-    } else {
-        INIT_LOGD("  Scissor optimization enabled");
-    }
-}
-
-void OpenGLRenderer::initLight(float lightRadius, uint8_t ambientShadowAlpha,
-        uint8_t spotShadowAlpha) {
-    mLightRadius = lightRadius;
-    mAmbientShadowAlpha = ambientShadowAlpha;
-    mSpotShadowAlpha = spotShadowAlpha;
-}
-
-void OpenGLRenderer::setLightCenter(const Vector3& lightCenter) {
-    mLightCenter = lightCenter;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Setup
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::onViewportInitialized() {
-    glDisable(GL_DITHER);
-    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-}
-
-void OpenGLRenderer::setupFrameState(int viewportWidth, int viewportHeight,
-        float left, float top, float right, float bottom, bool opaque) {
-    mCaches.clearGarbage();
-    mState.initializeSaveStack(viewportWidth, viewportHeight,
-            left, top, right, bottom, mLightCenter);
-    mOpaque = opaque;
-    mTilingClip.set(left, top, right, bottom);
-}
-
-void OpenGLRenderer::startFrame() {
-    if (mFrameStarted) return;
-    mFrameStarted = true;
-
-    mState.setDirtyClip(true);
-
-    discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom);
-
-    mRenderState.setViewport(mState.getWidth(), mState.getHeight());
-
-    debugOverdraw(true, true);
-
-    clear(mTilingClip.left, mTilingClip.top,
-            mTilingClip.right, mTilingClip.bottom, mOpaque);
-}
-
-void OpenGLRenderer::prepareDirty(int viewportWidth, int viewportHeight,
-        float left, float top, float right, float bottom, bool opaque) {
-
-    setupFrameState(viewportWidth, viewportHeight, left, top, right, bottom, opaque);
-
-    // Layer renderers will start the frame immediately
-    // The framebuffer renderer will first defer the display list
-    // for each layer and wait until the first drawing command
-    // to start the frame
-    if (currentSnapshot()->fbo == 0) {
-        mRenderState.blend().syncEnabled();
-        updateLayers();
-    } else {
-        startFrame();
-    }
-}
-
-void OpenGLRenderer::discardFramebuffer(float left, float top, float right, float bottom) {
-    // If we know that we are going to redraw the entire framebuffer,
-    // perform a discard to let the driver know we don't need to preserve
-    // the back buffer for this frame.
-    if (mCaches.extensions().hasDiscardFramebuffer() &&
-            left <= 0.0f && top <= 0.0f && right >= mState.getWidth() && bottom >= mState.getHeight()) {
-        const bool isFbo = getTargetFbo() == 0;
-        const GLenum attachments[] = {
-                isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0,
-                isFbo ? (const GLenum) GL_STENCIL_EXT : (const GLenum) GL_STENCIL_ATTACHMENT };
-        glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, attachments);
-    }
-}
-
-void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
-    if (!opaque) {
-        mRenderState.scissor().setEnabled(true);
-        mRenderState.scissor().set(left, getViewportHeight() - bottom, right - left, bottom - top);
-        glClear(GL_COLOR_BUFFER_BIT);
-        mDirty = true;
-        return;
-    }
-
-    mRenderState.scissor().reset();
-}
-
-bool OpenGLRenderer::finish() {
-    renderOverdraw();
-    mTempPaths.clear();
-
-    // When finish() is invoked on FBO 0 we've reached the end
-    // of the current frame
-    if (getTargetFbo() == 0) {
-        mCaches.pathCache.trim();
-        mCaches.tessellationCache.trim();
-    }
-
-    if (!suppressErrorChecks()) {
-        GL_CHECKPOINT(MODERATE);
-
-#if DEBUG_MEMORY_USAGE
-        mCaches.dumpMemoryUsage();
-        GPUMemoryTracker::dump();
-#else
-        if (Properties::debugLevel & kDebugMemory) {
-            mCaches.dumpMemoryUsage();
-        }
-#endif
-    }
-
-    mFrameStarted = false;
-
-    return reportAndClearDirty();
-}
-
-void OpenGLRenderer::resumeAfterLayer() {
-    mRenderState.setViewport(getViewportWidth(), getViewportHeight());
-    mRenderState.bindFramebuffer(currentSnapshot()->fbo);
-    debugOverdraw(true, false);
-
-    mRenderState.scissor().reset();
-    dirtyClip();
-}
-
-void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
-    if (mState.currentlyIgnored()) return;
-
-    Rect clip(mState.currentRenderTargetClip());
-    clip.snapToPixelBoundaries();
-
-    // Since we don't know what the functor will draw, let's dirty
-    // the entire clip region
-    if (hasLayer()) {
-        dirtyLayerUnchecked(clip, getRegion());
-    }
-
-    DrawGlInfo info;
-    info.clipLeft = clip.left;
-    info.clipTop = clip.top;
-    info.clipRight = clip.right;
-    info.clipBottom = clip.bottom;
-    info.isLayer = hasLayer();
-    info.width = getViewportWidth();
-    info.height = getViewportHeight();
-    currentTransform()->copyTo(&info.transform[0]);
-
-    bool prevDirtyClip = mState.getDirtyClip();
-    // setup GL state for functor
-    if (mState.getDirtyClip()) {
-        setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt()
-    }
-    if (mRenderState.scissor().setEnabled(true) || prevDirtyClip) {
-        setScissorFromClip();
-    }
-
-    mRenderState.invokeFunctor(functor, DrawGlInfo::kModeDraw, &info);
-    // Scissor may have been modified, reset dirty clip
-    dirtyClip();
-
-    mDirty = true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Debug
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::eventMarkDEBUG(const char* fmt, ...) const {
-#if DEBUG_DETAILED_EVENTS
-    const int BUFFER_SIZE = 256;
-    va_list ap;
-    char buf[BUFFER_SIZE];
-
-    va_start(ap, fmt);
-    vsnprintf(buf, BUFFER_SIZE, fmt, ap);
-    va_end(ap);
-
-    eventMark(buf);
-#endif
-}
-
-
-void OpenGLRenderer::eventMark(const char* name) const {
-    mCaches.eventMark(0, name);
-}
-
-void OpenGLRenderer::startMark(const char* name) const {
-    mCaches.startMark(0, name);
-}
-
-void OpenGLRenderer::endMark() const {
-    mCaches.endMark();
-}
-
-void OpenGLRenderer::debugOverdraw(bool enable, bool clear) {
-    mRenderState.debugOverdraw(enable, clear);
-}
-
-void OpenGLRenderer::renderOverdraw() {
-    if (Properties::debugOverdraw && getTargetFbo() == 0) {
-        const Rect* clip = &mTilingClip;
-
-        mRenderState.scissor().setEnabled(true);
-        mRenderState.scissor().set(clip->left,
-                mState.firstSnapshot()->getViewportHeight() - clip->bottom,
-                clip->right - clip->left,
-                clip->bottom - clip->top);
-
-        // 1x overdraw
-        mRenderState.stencil().enableDebugTest(2);
-        drawColor(mCaches.getOverdrawColor(1), SkXfermode::kSrcOver_Mode);
-
-        // 2x overdraw
-        mRenderState.stencil().enableDebugTest(3);
-        drawColor(mCaches.getOverdrawColor(2), SkXfermode::kSrcOver_Mode);
-
-        // 3x overdraw
-        mRenderState.stencil().enableDebugTest(4);
-        drawColor(mCaches.getOverdrawColor(3), SkXfermode::kSrcOver_Mode);
-
-        // 4x overdraw and higher
-        mRenderState.stencil().enableDebugTest(4, true);
-        drawColor(mCaches.getOverdrawColor(4), SkXfermode::kSrcOver_Mode);
-
-        mRenderState.stencil().disable();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Layers
-///////////////////////////////////////////////////////////////////////////////
-
-bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
-    if (layer->deferredUpdateScheduled && layer->renderer
-            && layer->renderNode.get() && layer->renderNode->isRenderable()) {
-
-        if (inFrame) {
-            debugOverdraw(false, false);
-        }
-
-        if (CC_UNLIKELY(inFrame || Properties::drawDeferDisabled)) {
-            layer->render(*this);
-        } else {
-            layer->defer(*this);
-        }
-
-        if (inFrame) {
-            resumeAfterLayer();
-        }
-
-        layer->debugDrawUpdate = Properties::debugLayersUpdates;
-        layer->hasDrawnSinceUpdate = false;
-
-        return true;
-    }
-
-    return false;
-}
-
-void OpenGLRenderer::updateLayers() {
-    // If draw deferring is enabled this method will simply defer
-    // the display list of each individual layer. The layers remain
-    // in the layer updates list which will be cleared by flushLayers().
-    int count = mLayerUpdates.size();
-    if (count > 0) {
-        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
-            startMark("Layer Updates");
-        } else {
-            startMark("Defer Layer Updates");
-        }
-
-        // Note: it is very important to update the layers in order
-        for (int i = 0; i < count; i++) {
-            Layer* layer = mLayerUpdates[i].get();
-            updateLayer(layer, false);
-        }
-
-        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
-            mLayerUpdates.clear();
-            mRenderState.bindFramebuffer(getTargetFbo());
-        }
-        endMark();
-    }
-}
-
-void OpenGLRenderer::flushLayers() {
-    int count = mLayerUpdates.size();
-    if (count > 0) {
-        startMark("Apply Layer Updates");
-
-        // Note: it is very important to update the layers in order
-        for (int i = 0; i < count; i++) {
-            mLayerUpdates[i]->flush();
-        }
-
-        mLayerUpdates.clear();
-        mRenderState.bindFramebuffer(getTargetFbo());
-
-        endMark();
-    }
-}
-
-void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
-    if (layer) {
-        // Make sure we don't introduce duplicates.
-        // SortedVector would do this automatically but we need to respect
-        // the insertion order. The linear search is not an issue since
-        // this list is usually very short (typically one item, at most a few)
-        for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
-            if (mLayerUpdates[i] == layer) {
-                return;
-            }
-        }
-        mLayerUpdates.push_back(layer);
-    }
-}
-
-void OpenGLRenderer::cancelLayerUpdate(Layer* layer) {
-    if (layer) {
-        for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
-            if (mLayerUpdates[i] == layer) {
-                mLayerUpdates.erase(mLayerUpdates.begin() + i);
-                break;
-            }
-        }
-    }
-}
-
-void OpenGLRenderer::flushLayerUpdates() {
-    ATRACE_NAME("Update HW Layers");
-    mRenderState.blend().syncEnabled();
-    updateLayers();
-    flushLayers();
-    // Wait for all the layer updates to be executed
-    glFinish();
-}
-
-void OpenGLRenderer::markLayersAsBuildLayers() {
-    for (size_t i = 0; i < mLayerUpdates.size(); i++) {
-        mLayerUpdates[i]->wasBuildLayered = true;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// State management
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {
-    bool restoreViewport = removed.flags & Snapshot::kFlagIsFboLayer;
-    bool restoreClip = removed.flags & Snapshot::kFlagClipSet;
-    bool restoreLayer = removed.flags & Snapshot::kFlagIsLayer;
-
-    if (restoreViewport) {
-        mRenderState.setViewport(getViewportWidth(), getViewportHeight());
-    }
-
-    if (restoreClip) {
-        dirtyClip();
-    }
-
-    if (restoreLayer) {
-        endMark(); // Savelayer
-        ATRACE_END(); // SaveLayer
-        startMark("ComposeLayer");
-        composeLayer(removed, restored);
-        endMark();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Layers
-///////////////////////////////////////////////////////////////////////////////
-
-int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
-        const SkPaint* paint, int flags, const SkPath* convexMask) {
-    // force matrix/clip isolation for layer
-    flags |= SaveFlags::MatrixClip;
-
-    const int count = mState.saveSnapshot(flags);
-
-    if (!mState.currentlyIgnored()) {
-        createLayer(left, top, right, bottom, paint, flags, convexMask);
-    }
-
-    return count;
-}
-
-void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer) {
-    const Rect untransformedBounds(bounds);
-
-    currentTransform()->mapRect(bounds);
-
-    // Layers only make sense if they are in the framebuffer's bounds
-    bounds.doIntersect(mState.currentRenderTargetClip());
-    if (!bounds.isEmpty()) {
-        // We cannot work with sub-pixels in this case
-        bounds.snapToPixelBoundaries();
-
-        // When the layer is not an FBO, we may use glCopyTexImage so we
-        // need to make sure the layer does not extend outside the bounds
-        // of the framebuffer
-        const Snapshot& previous = *(currentSnapshot()->previous);
-        Rect previousViewport(0, 0, previous.getViewportWidth(), previous.getViewportHeight());
-
-        bounds.doIntersect(previousViewport);
-        if (!bounds.isEmpty() && fboLayer) {
-            clip.set(bounds);
-            mat4 inverse;
-            inverse.loadInverse(*currentTransform());
-            inverse.mapRect(clip);
-            clip.snapToPixelBoundaries();
-            clip.doIntersect(untransformedBounds);
-            if (!clip.isEmpty()) {
-                clip.translate(-untransformedBounds.left, -untransformedBounds.top);
-                bounds.set(untransformedBounds);
-            }
-        }
-    }
-}
-
-void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect& clip,
-        bool fboLayer, int alpha) {
-    if (bounds.isEmpty() || bounds.getWidth() > mCaches.maxTextureSize ||
-            bounds.getHeight() > mCaches.maxTextureSize ||
-            (fboLayer && clip.isEmpty())) {
-        writableSnapshot()->empty = fboLayer;
-    } else {
-        writableSnapshot()->invisible = writableSnapshot()->invisible || (alpha <= 0 && fboLayer);
-    }
-}
-
-int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom,
-        const SkPaint* paint, int flags) {
-    const int count = mState.saveSnapshot(flags);
-
-    if (!mState.currentlyIgnored() && (flags & SaveFlags::ClipToLayer)) {
-        // initialize the snapshot as though it almost represents an FBO layer so deferred draw
-        // operations will be able to store and restore the current clip and transform info, and
-        // quick rejection will be correct (for display lists)
-
-        Rect bounds(left, top, right, bottom);
-        Rect clip;
-        calculateLayerBoundsAndClip(bounds, clip, true);
-        updateSnapshotIgnoreForLayer(bounds, clip, true, PaintUtils::getAlphaDirect(paint));
-
-        if (!mState.currentlyIgnored()) {
-            writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f);
-            writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom);
-            writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight());
-            writableSnapshot()->roundRectClipState = nullptr;
-        }
-    }
-
-    return count;
-}
-
-/**
- * Layers are viewed by Skia are slightly different than layers in image editing
- * programs (for instance.) When a layer is created, previously created layers
- * and the frame buffer still receive every drawing command. For instance, if a
- * layer is created and a shape intersecting the bounds of the layers and the
- * framebuffer is draw, the shape will be drawn on both (unless the layer was
- * created with the SaveFlags::ClipToLayer flag.)
- *
- * A way to implement layers is to create an FBO for each layer, backed by an RGBA
- * texture. Unfortunately, this is inefficient as it requires every primitive to
- * be drawn n + 1 times, where n is the number of active layers. In practice this
- * means, for every primitive:
- *   - Switch active frame buffer
- *   - Change viewport, clip and projection matrix
- *   - Issue the drawing
- *
- * Switching rendering target n + 1 times per drawn primitive is extremely costly.
- * To avoid this, layers are implemented in a different way here, at least in the
- * general case. FBOs are used, as an optimization, when the "clip to layer" flag
- * is set. When this flag is set we can redirect all drawing operations into a
- * single FBO.
- *
- * This implementation relies on the frame buffer being at least RGBA 8888. When
- * a layer is created, only a texture is created, not an FBO. The content of the
- * frame buffer contained within the layer's bounds is copied into this texture
- * using glCopyTexImage2D(). The layer's region is then cleared(1) in the frame
- * buffer and drawing continues as normal. This technique therefore treats the
- * frame buffer as a scratch buffer for the layers.
- *
- * To compose the layers back onto the frame buffer, each layer texture
- * (containing the original frame buffer data) is drawn as a simple quad over
- * the frame buffer. The trick is that the quad is set as the composition
- * destination in the blending equation, and the frame buffer becomes the source
- * of the composition.
- *
- * Drawing layers with an alpha value requires an extra step before composition.
- * An empty quad is drawn over the layer's region in the frame buffer. This quad
- * is drawn with the rgba color (0,0,0,alpha). The alpha value offered by the
- * quad is used to multiply the colors in the frame buffer. This is achieved by
- * changing the GL blend functions for the GL_FUNC_ADD blend equation to
- * GL_ZERO, GL_SRC_ALPHA.
- *
- * Because glCopyTexImage2D() can be slow, an alternative implementation might
- * be use to draw a single clipped layer. The implementation described above
- * is correct in every case.
- *
- * (1) The frame buffer is actually not cleared right away. To allow the GPU
- *     to potentially optimize series of calls to glCopyTexImage2D, the frame
- *     buffer is left untouched until the first drawing operation. Only when
- *     something actually gets drawn are the layers regions cleared.
- */
-bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom,
-        const SkPaint* paint, int flags, const SkPath* convexMask) {
-    LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top);
-    LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
-
-    const bool fboLayer = flags & SaveFlags::ClipToLayer;
-
-    // Window coordinates of the layer
-    Rect clip;
-    Rect bounds(left, top, right, bottom);
-    calculateLayerBoundsAndClip(bounds, clip, fboLayer);
-    updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, PaintUtils::getAlphaDirect(paint));
-
-    // Bail out if we won't draw in this snapshot
-    if (mState.currentlyIgnored()) {
-        return false;
-    }
-
-    mCaches.textureState().activateTexture(0);
-    Layer* layer = mCaches.layerCache.get(mRenderState, bounds.getWidth(), bounds.getHeight());
-    if (!layer) {
-        return false;
-    }
-
-    layer->setPaint(paint);
-    layer->layer.set(bounds);
-    layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->getHeight()),
-            bounds.getWidth() / float(layer->getWidth()), 0.0f);
-
-    layer->setBlend(true);
-    layer->setDirty(false);
-    layer->setConvexMask(convexMask); // note: the mask must be cleared before returning to the cache
-
-    // Save the layer in the snapshot
-    writableSnapshot()->flags |= Snapshot::kFlagIsLayer;
-    writableSnapshot()->layer = layer;
-
-    ATRACE_FORMAT_BEGIN("%ssaveLayer %ux%u",
-            fboLayer ? "" : "unclipped ",
-            layer->getWidth(), layer->getHeight());
-    startMark("SaveLayer");
-    if (fboLayer) {
-        return createFboLayer(layer, bounds, clip);
-    } else {
-        // Copy the framebuffer into the layer
-        layer->bindTexture();
-        if (!bounds.isEmpty()) {
-            if (layer->isEmpty()) {
-                // Workaround for some GL drivers. When reading pixels lying outside
-                // of the window we should get undefined values for those pixels.
-                // Unfortunately some drivers will turn the entire target texture black
-                // when reading outside of the window.
-                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->getWidth(), layer->getHeight(),
-                        0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
-                layer->setEmpty(false);
-            }
-
-            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
-                    bounds.left, getViewportHeight() - bounds.bottom,
-                    bounds.getWidth(), bounds.getHeight());
-
-            // Enqueue the buffer coordinates to clear the corresponding region later
-            mLayers.push_back(Rect(bounds));
-        }
-    }
-
-    return true;
-}
-
-bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) {
-    layer->clipRect.set(clip);
-    layer->setFbo(mRenderState.createFramebuffer());
-
-    writableSnapshot()->region = &writableSnapshot()->layer->region;
-    writableSnapshot()->flags |= Snapshot::kFlagFboTarget | Snapshot::kFlagIsFboLayer;
-    writableSnapshot()->fbo = layer->getFbo();
-    writableSnapshot()->resetTransform(-bounds.left, -bounds.top, 0.0f);
-    writableSnapshot()->resetClip(clip.left, clip.top, clip.right, clip.bottom);
-    writableSnapshot()->initializeViewport(bounds.getWidth(), bounds.getHeight());
-    writableSnapshot()->roundRectClipState = nullptr;
-
-    debugOverdraw(false, false);
-    // Bind texture to FBO
-    mRenderState.bindFramebuffer(layer->getFbo());
-    layer->bindTexture();
-
-    // Initialize the texture if needed
-    if (layer->isEmpty()) {
-        layer->allocateTexture();
-        layer->setEmpty(false);
-    }
-
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-            layer->getTextureId(), 0);
-
-    // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
-    mRenderState.scissor().setEnabled(true);
-    mRenderState.scissor().set(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f,
-            clip.getWidth() + 2.0f, clip.getHeight() + 2.0f);
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    dirtyClip();
-
-    // Change the ortho projection
-    mRenderState.setViewport(bounds.getWidth(), bounds.getHeight());
-    return true;
-}
-
-/**
- * Read the documentation of createLayer() before doing anything in this method.
- */
-void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& restored) {
-    if (!removed.layer) {
-        ALOGE("Attempting to compose a layer that does not exist");
-        return;
-    }
-
-    Layer* layer = removed.layer;
-    const Rect& rect = layer->layer;
-    const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer;
-
-    bool clipRequired = false;
-    mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom,
-            &clipRequired, nullptr, false); // safely ignore return, should never be rejected
-    mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired);
-
-    if (fboLayer) {
-        // Detach the texture from the FBO
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-
-        layer->removeFbo(false);
-
-        // Unbind current FBO and restore previous one
-        mRenderState.bindFramebuffer(restored.fbo);
-        debugOverdraw(true, false);
-    }
-
-    if (!fboLayer && layer->getAlpha() < 255) {
-        SkPaint layerPaint;
-        layerPaint.setAlpha(layer->getAlpha());
-        layerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
-        layerPaint.setColorFilter(layer->getColorFilter());
-
-        drawColorRect(rect.left, rect.top, rect.right, rect.bottom, &layerPaint, true);
-        // Required below, composeLayerRect() will divide by 255
-        layer->setAlpha(255);
-    }
-
-    mRenderState.meshState().unbindMeshBuffer();
-
-    mCaches.textureState().activateTexture(0);
-
-    // When the layer is stored in an FBO, we can save a bit of fillrate by
-    // drawing only the dirty region
-    if (fboLayer) {
-        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *restored.transform);
-        composeLayerRegion(layer, rect);
-    } else if (!rect.isEmpty()) {
-        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
-
-        save(0);
-        // the layer contains screen buffer content that shouldn't be alpha modulated
-        // (and any necessary alpha modulation was handled drawing into the layer)
-        writableSnapshot()->alpha = 1.0f;
-        composeLayerRectSwapped(layer, rect);
-        restore();
-    }
-
-    dirtyClip();
-
-    // Failing to add the layer to the cache should happen only if the layer is too large
-    layer->setConvexMask(nullptr);
-    if (!mCaches.layerCache.put(layer)) {
-        LAYER_LOGD("Deleting layer");
-        layer->decStrong(nullptr);
-    }
-}
-
-void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
-    const bool tryToSnap = !layer->getForceFilter()
-            && layer->getWidth() == (uint32_t) rect.getWidth()
-            && layer->getHeight() == (uint32_t) rect.getHeight();
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO
-            .setFillTextureLayer(*layer, getLayerAlpha(layer))
-            .setTransform(*currentSnapshot(), TransformFlags::None)
-            .setModelViewMapUnitToRectOptionalSnap(tryToSnap, rect)
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::composeLayerRectSwapped(Layer* layer, const Rect& rect) {
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUvQuad(nullptr, layer->texCoords)
-            .setFillLayer(layer->getTexture(), layer->getColorFilter(),
-                    getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::Swap)
-            .setTransform(*currentSnapshot(), TransformFlags::MeshIgnoresCanvasTransform)
-            .setModelViewMapUnitToRect(rect)
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect) {
-    if (layer->isTextureLayer()) {
-        EVENT_LOGD("composeTextureLayerRect");
-        drawTextureLayer(layer, rect);
-    } else {
-        EVENT_LOGD("composeHardwareLayerRect");
-
-        const bool tryToSnap = layer->getWidth() == static_cast<uint32_t>(rect.getWidth())
-                && layer->getHeight() == static_cast<uint32_t>(rect.getHeight());
-        Glop glop;
-        GlopBuilder(mRenderState, mCaches, &glop)
-                .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-                .setMeshTexturedUvQuad(nullptr, layer->texCoords)
-                .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap)
-                .setTransform(*currentSnapshot(), TransformFlags::None)
-                .setModelViewMapUnitToRectOptionalSnap(tryToSnap, rect)
-                .build();
-        renderGlop(glop);
-    }
-}
-
-/**
- * Issues the command X, and if we're composing a save layer to the fbo or drawing a newly updated
- * hardware layer with overdraw debug on, draws again to the stencil only, so that these draw
- * operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used
- * by saveLayer's restore
- */
-#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
-        DRAW_COMMAND; \
-        if (CC_UNLIKELY(Properties::debugOverdraw && getTargetFbo() == 0 && (COND))) { \
-            glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
-            DRAW_COMMAND; \
-            glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
-        } \
-    }
-
-#define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND)
-
-// This class is purely for inspection. It inherits from SkShader, but Skia does not know how to
-// use it. The OpenGLRenderer will look at it to find its Layer and whether it is opaque.
-class LayerShader : public SkShader {
-public:
-    LayerShader(Layer* layer, const SkMatrix* localMatrix)
-    : INHERITED(localMatrix)
-    , mLayer(layer) {
-    }
-
-    virtual bool asACustomShader(void** data) const override {
-        if (data) {
-            *data = static_cast<void*>(mLayer);
-        }
-        return true;
-    }
-
-    virtual bool isOpaque() const override {
-        return !mLayer->isBlend();
-    }
-
-protected:
-    virtual void shadeSpan(int x, int y, SkPMColor[], int count) {
-        LOG_ALWAYS_FATAL("LayerShader should never be drawn with raster backend.");
-    }
-
-    virtual void flatten(SkWriteBuffer&) const override {
-        LOG_ALWAYS_FATAL("LayerShader should never be flattened.");
-    }
-
-    virtual Factory getFactory() const override {
-        LOG_ALWAYS_FATAL("LayerShader should never be created from a stream.");
-        return nullptr;
-    }
-private:
-    // Unowned.
-    Layer* mLayer;
-    typedef SkShader INHERITED;
-};
-
-void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
-    if (CC_UNLIKELY(layer->region.isEmpty())) return; // nothing to draw
-
-    if (layer->getConvexMask()) {
-        save(SaveFlags::MatrixClip);
-
-        // clip to the area of the layer the mask can be larger
-        clipRect(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kIntersect_Op);
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setColor(SkColorSetARGB(int(getLayerAlpha(layer) * 255), 0, 0, 0));
-
-        // create LayerShader to map SaveLayer content into subsequent draw
-        SkMatrix shaderMatrix;
-        shaderMatrix.setTranslate(rect.left, rect.bottom);
-        shaderMatrix.preScale(1, -1);
-        LayerShader layerShader(layer, &shaderMatrix);
-        paint.setShader(&layerShader);
-
-        // Since the drawing primitive is defined in local drawing space,
-        // we don't need to modify the draw matrix
-        const SkPath* maskPath = layer->getConvexMask();
-        DRAW_DOUBLE_STENCIL(drawConvexPath(*maskPath, &paint));
-
-        paint.setShader(nullptr);
-        restore();
-
-        return;
-    }
-
-    if (layer->region.isRect()) {
-        layer->setRegionAsRect();
-
-        DRAW_DOUBLE_STENCIL(composeLayerRect(layer, layer->regionRect));
-
-        layer->region.clear();
-        return;
-    }
-
-    EVENT_LOGD("composeLayerRegion");
-    // standard Region based draw
-    size_t count;
-    const android::Rect* rects;
-    Region safeRegion;
-    if (CC_LIKELY(hasRectToRectTransform())) {
-        rects = layer->region.getArray(&count);
-    } else {
-        safeRegion = Region::createTJunctionFreeRegion(layer->region);
-        rects = safeRegion.getArray(&count);
-    }
-
-    const float texX = 1.0f / float(layer->getWidth());
-    const float texY = 1.0f / float(layer->getHeight());
-    const float height = rect.getHeight();
-
-    TextureVertex quadVertices[count * 4];
-    TextureVertex* mesh = &quadVertices[0];
-    for (size_t i = 0; i < count; i++) {
-        const android::Rect* r = &rects[i];
-
-        const float u1 = r->left * texX;
-        const float v1 = (height - r->top) * texY;
-        const float u2 = r->right * texX;
-        const float v2 = (height - r->bottom) * texY;
-
-        // TODO: Reject quads outside of the clip
-        TextureVertex::set(mesh++, r->left, r->top, u1, v1);
-        TextureVertex::set(mesh++, r->right, r->top, u2, v1);
-        TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
-        TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
-    }
-    Rect modelRect = Rect(rect.getWidth(), rect.getHeight());
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedIndexedQuads(&quadVertices[0], count * 6)
-            .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewOffsetRectSnap(rect.left, rect.top, modelRect)
-            .build();
-    DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, renderGlop(glop));
-
-#if DEBUG_LAYERS_AS_REGIONS
-    drawRegionRectsDebug(layer->region);
-#endif
-
-    layer->region.clear();
-}
-
-#if DEBUG_LAYERS_AS_REGIONS
-void OpenGLRenderer::drawRegionRectsDebug(const Region& region) {
-    size_t count;
-    const android::Rect* rects = region.getArray(&count);
-
-    uint32_t colors[] = {
-            0x7fff0000, 0x7f00ff00,
-            0x7f0000ff, 0x7fff00ff,
-    };
-
-    int offset = 0;
-    int32_t top = rects[0].top;
-
-    for (size_t i = 0; i < count; i++) {
-        if (top != rects[i].top) {
-            offset ^= 0x2;
-            top = rects[i].top;
-        }
-
-        SkPaint paint;
-        paint.setColor(colors[offset + (i & 0x1)]);
-        Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
-        drawColorRect(r.left, r.top, r.right, r.bottom, paint);
-    }
-}
-#endif
-
-void OpenGLRenderer::drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty) {
-    Vector<float> rects;
-
-    SkRegion::Iterator it(region);
-    while (!it.done()) {
-        const SkIRect& r = it.rect();
-        rects.push(r.fLeft);
-        rects.push(r.fTop);
-        rects.push(r.fRight);
-        rects.push(r.fBottom);
-        it.next();
-    }
-
-    drawColorRects(rects.array(), rects.size(), &paint, true, dirty, false);
-}
-
-void OpenGLRenderer::dirtyLayer(const float left, const float top,
-        const float right, const float bottom, const Matrix4& transform) {
-    if (hasLayer()) {
-        Rect bounds(left, top, right, bottom);
-        transform.mapRect(bounds);
-        dirtyLayerUnchecked(bounds, getRegion());
-    }
-}
-
-void OpenGLRenderer::dirtyLayer(const float left, const float top,
-        const float right, const float bottom) {
-    if (hasLayer()) {
-        Rect bounds(left, top, right, bottom);
-        dirtyLayerUnchecked(bounds, getRegion());
-    }
-}
-
-void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
-    bounds.doIntersect(mState.currentRenderTargetClip());
-    if (!bounds.isEmpty()) {
-        bounds.snapToPixelBoundaries();
-        android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
-        if (!dirty.isEmpty()) {
-            region->orSelf(dirty);
-        }
-    }
-}
-
-void OpenGLRenderer::clearLayerRegions() {
-    const size_t quadCount = mLayers.size();
-    if (quadCount == 0) return;
-
-    if (!mState.currentlyIgnored()) {
-        EVENT_LOGD("clearLayerRegions");
-        // Doing several glScissor/glClear here can negatively impact
-        // GPUs with a tiler architecture, instead we draw quads with
-        // the Clear blending mode
-
-        // The list contains bounds that have already been clipped
-        // against their initial clip rect, and the current clip
-        // is likely different so we need to disable clipping here
-        bool scissorChanged = mRenderState.scissor().setEnabled(false);
-
-        Vertex mesh[quadCount * 4];
-        Vertex* vertex = mesh;
-
-        for (uint32_t i = 0; i < quadCount; i++) {
-            const Rect& bounds = mLayers[i];
-
-            Vertex::set(vertex++, bounds.left, bounds.top);
-            Vertex::set(vertex++, bounds.right, bounds.top);
-            Vertex::set(vertex++, bounds.left, bounds.bottom);
-            Vertex::set(vertex++, bounds.right, bounds.bottom);
-        }
-        // We must clear the list of dirty rects before we
-        // call clearLayerRegions() in renderGlop to prevent
-        // stencil setup from doing the same thing again
-        mLayers.clear();
-
-        const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform;
-        Glop glop;
-        GlopBuilder(mRenderState, mCaches, &glop)
-                .setRoundRectClipState(nullptr) // clear ignores clip state
-                .setMeshIndexedQuads(&mesh[0], quadCount)
-                .setFillClear()
-                .setTransform(*currentSnapshot(), transformFlags)
-                .setModelViewOffsetRect(0, 0, Rect(currentSnapshot()->getRenderTargetClip()))
-                .build();
-        renderGlop(glop, GlopRenderType::LayerClear);
-
-        if (scissorChanged) mRenderState.scissor().setEnabled(true);
-    } else {
-        mLayers.clear();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// State Deferral
-///////////////////////////////////////////////////////////////////////////////
-
-bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) {
-    const Rect& currentClip = mState.currentRenderTargetClip();
-    const mat4* currentMatrix = currentTransform();
-
-    if (stateDeferFlags & kStateDeferFlag_Draw) {
-        // state has bounds initialized in local coordinates
-        if (!state.mBounds.isEmpty()) {
-            currentMatrix->mapRect(state.mBounds);
-            Rect clippedBounds(state.mBounds);
-            // NOTE: if we ever want to use this clipping info to drive whether the scissor
-            // is used, it should more closely duplicate the quickReject logic (in how it uses
-            // snapToPixelBoundaries)
-
-            clippedBounds.doIntersect(currentClip);
-            if (clippedBounds.isEmpty()) {
-                // quick rejected
-                return true;
-            }
-
-            state.mClipSideFlags = kClipSide_None;
-            if (!currentClip.contains(state.mBounds)) {
-                int& flags = state.mClipSideFlags;
-                // op partially clipped, so record which sides are clipped for clip-aware merging
-                if (currentClip.left > state.mBounds.left) flags |= kClipSide_Left;
-                if (currentClip.top > state.mBounds.top) flags |= kClipSide_Top;
-                if (currentClip.right < state.mBounds.right) flags |= kClipSide_Right;
-                if (currentClip.bottom < state.mBounds.bottom) flags |= kClipSide_Bottom;
-            }
-            state.mBounds.set(clippedBounds);
-        } else {
-            // Empty bounds implies size unknown. Label op as conservatively clipped to disable
-            // overdraw avoidance (since we don't know what it overlaps)
-            state.mClipSideFlags = kClipSide_ConservativeFull;
-            state.mBounds.set(currentClip);
-        }
-    }
-
-    state.mClipValid = (stateDeferFlags & kStateDeferFlag_Clip);
-    if (state.mClipValid) {
-        state.mClip.set(currentClip);
-    }
-
-    // Transform and alpha always deferred, since they are used by state operations
-    // (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything)
-    state.mMatrix = *currentMatrix;
-    state.mAlpha = currentSnapshot()->alpha;
-
-    // always store/restore, since these are just pointers
-    state.mRoundRectClipState = currentSnapshot()->roundRectClipState;
-#if !HWUI_NEW_OPS
-    state.mProjectionPathMask = currentSnapshot()->projectionPathMask;
-#endif
-    return false;
-}
-
-void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) {
-    setGlobalMatrix(state.mMatrix);
-    writableSnapshot()->alpha = state.mAlpha;
-    writableSnapshot()->roundRectClipState = state.mRoundRectClipState;
-#if !HWUI_NEW_OPS
-    writableSnapshot()->projectionPathMask = state.mProjectionPathMask;
-#endif
-
-    if (state.mClipValid && !skipClipRestore) {
-        writableSnapshot()->setClip(state.mClip.left, state.mClip.top,
-                state.mClip.right, state.mClip.bottom);
-        dirtyClip();
-    }
-}
-
-/**
- * Merged multidraw (such as in drawText and drawBitmaps rely on the fact that no clipping is done
- * in the draw path. Instead, clipping is done ahead of time - either as a single clip rect (when at
- * least one op is clipped), or disabled entirely (because no merged op is clipped)
- *
- * This method should be called when restoreDisplayState() won't be restoring the clip
- */
-void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) {
-    if (clipRect != nullptr) {
-        writableSnapshot()->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
-    } else {
-        writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight());
-    }
-    dirtyClip();
-    bool enableScissor = (clipRect != nullptr) || mScissorOptimizationDisabled;
-    mRenderState.scissor().setEnabled(enableScissor);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Clipping
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::setScissorFromClip() {
-    Rect clip(mState.currentRenderTargetClip());
-    clip.snapToPixelBoundaries();
-
-    if (mRenderState.scissor().set(clip.left, getViewportHeight() - clip.bottom,
-            clip.getWidth(), clip.getHeight())) {
-        mState.setDirtyClip(false);
-    }
-}
-
-void OpenGLRenderer::ensureStencilBuffer() {
-    // Thanks to the mismatch between EGL and OpenGL ES FBO we
-    // cannot attach a stencil buffer to fbo0 dynamically. Let's
-    // just hope we have one when hasLayer() returns false.
-    if (hasLayer()) {
-        attachStencilBufferToLayer(currentSnapshot()->layer);
-    }
-}
-
-void OpenGLRenderer::attachStencilBufferToLayer(Layer* layer) {
-    // The layer's FBO is already bound when we reach this stage
-    if (!layer->getStencilRenderBuffer()) {
-        RenderBuffer* buffer = mCaches.renderBufferCache.get(
-                Stencil::getLayerStencilFormat(),
-                layer->getWidth(), layer->getHeight());
-        layer->setStencilRenderBuffer(buffer);
-    }
-}
-
-static void handlePoint(std::vector<Vertex>& rectangleVertices, const Matrix4& transform,
-        float x, float y) {
-    Vertex v;
-    v.x = x;
-    v.y = y;
-    transform.mapPoint(v.x, v.y);
-    rectangleVertices.push_back(v);
-}
-
-static void handlePointNoTransform(std::vector<Vertex>& rectangleVertices, float x, float y) {
-    Vertex v;
-    v.x = x;
-    v.y = y;
-    rectangleVertices.push_back(v);
-}
-
-void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) {
-    int quadCount = rectangleList.getTransformedRectanglesCount();
-    std::vector<Vertex> rectangleVertices(quadCount * 4);
-    Rect scissorBox = rectangleList.calculateBounds();
-    scissorBox.snapToPixelBoundaries();
-    for (int i = 0; i < quadCount; ++i) {
-        const TransformedRectangle& tr(rectangleList.getTransformedRectangle(i));
-        const Matrix4& transform = tr.getTransform();
-        Rect bounds = tr.getBounds();
-        if (transform.rectToRect()) {
-            transform.mapRect(bounds);
-            bounds.doIntersect(scissorBox);
-            if (!bounds.isEmpty()) {
-                handlePointNoTransform(rectangleVertices, bounds.left, bounds.top);
-                handlePointNoTransform(rectangleVertices, bounds.right, bounds.top);
-                handlePointNoTransform(rectangleVertices, bounds.left, bounds.bottom);
-                handlePointNoTransform(rectangleVertices, bounds.right, bounds.bottom);
-            }
-        } else {
-            handlePoint(rectangleVertices, transform, bounds.left, bounds.top);
-            handlePoint(rectangleVertices, transform, bounds.right, bounds.top);
-            handlePoint(rectangleVertices, transform, bounds.left, bounds.bottom);
-            handlePoint(rectangleVertices, transform, bounds.right, bounds.bottom);
-        }
-    }
-
-    mRenderState.scissor().set(scissorBox.left, getViewportHeight() - scissorBox.bottom,
-            scissorBox.getWidth(), scissorBox.getHeight());
-    const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform;
-    Glop glop;
-    Vertex* vertices = &rectangleVertices[0];
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshIndexedQuads(vertices, rectangleVertices.size() / 4)
-            .setFillBlack()
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewOffsetRect(0, 0, scissorBox)
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::setStencilFromClip() {
-    if (!Properties::debugOverdraw) {
-        if (!currentSnapshot()->clipIsSimple()) {
-            int incrementThreshold;
-            EVENT_LOGD("setStencilFromClip - enabling");
-
-            // NOTE: The order here is important, we must set dirtyClip to false
-            //       before any draw call to avoid calling back into this method
-            mState.setDirtyClip(false);
-
-            ensureStencilBuffer();
-
-            const ClipArea& clipArea = currentSnapshot()->getClipArea();
-
-            bool isRectangleList = clipArea.isRectangleList();
-            if (isRectangleList) {
-                incrementThreshold = clipArea.getRectangleList().getTransformedRectanglesCount();
-            } else {
-                incrementThreshold = 0;
-            }
-
-            mRenderState.stencil().enableWrite(incrementThreshold);
-
-            // Clean and update the stencil, but first make sure we restrict drawing
-            // to the region's bounds
-            bool resetScissor = mRenderState.scissor().setEnabled(true);
-            if (resetScissor) {
-                // The scissor was not set so we now need to update it
-                setScissorFromClip();
-            }
-
-            mRenderState.stencil().clear();
-
-            // stash and disable the outline clip state, since stencil doesn't account for outline
-            bool storedSkipOutlineClip = mSkipOutlineClip;
-            mSkipOutlineClip = true;
-
-            SkPaint paint;
-            paint.setColor(SK_ColorBLACK);
-            paint.setXfermodeMode(SkXfermode::kSrc_Mode);
-
-            if (isRectangleList) {
-                drawRectangleList(clipArea.getRectangleList());
-            } else {
-                // NOTE: We could use the region contour path to generate a smaller mesh
-                //       Since we are using the stencil we could use the red book path
-                //       drawing technique. It might increase bandwidth usage though.
-
-                // The last parameter is important: we are not drawing in the color buffer
-                // so we don't want to dirty the current layer, if any
-                drawRegionRects(clipArea.getClipRegion(), paint, false);
-            }
-            if (resetScissor) mRenderState.scissor().setEnabled(false);
-            mSkipOutlineClip = storedSkipOutlineClip;
-
-            mRenderState.stencil().enableTest(incrementThreshold);
-
-            // Draw the region used to generate the stencil if the appropriate debug
-            // mode is enabled
-            // TODO: Implement for rectangle list clip areas
-            if (Properties::debugStencilClip == StencilClipDebug::ShowRegion
-                    && !clipArea.isRectangleList()) {
-                paint.setColor(0x7f0000ff);
-                paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
-                drawRegionRects(currentSnapshot()->getClipRegion(), paint);
-            }
-        } else {
-            EVENT_LOGD("setStencilFromClip - disabling");
-            mRenderState.stencil().disable();
-        }
-    }
-}
-
-/**
- * Returns false and sets scissor enable based upon bounds if drawing won't be clipped out.
- *
- * @param paint if not null, the bounds will be expanded to account for stroke depending on paint
- *         style, and tessellated AA ramp
- */
-bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, float bottom,
-        const SkPaint* paint) {
-    bool snapOut = paint && paint->isAntiAlias();
-
-    if (paint && paint->getStyle() != SkPaint::kFill_Style) {
-        float outset = paint->getStrokeWidth() * 0.5f;
-        left -= outset;
-        top -= outset;
-        right += outset;
-        bottom += outset;
-    }
-
-    bool clipRequired = false;
-    bool roundRectClipRequired = false;
-    if (mState.calculateQuickRejectForScissor(left, top, right, bottom,
-            &clipRequired, &roundRectClipRequired, snapOut)) {
-        return true;
-    }
-
-    // not quick rejected, so enable the scissor if clipRequired
-    mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired);
-    mSkipOutlineClip = !roundRectClipRequired;
-    return false;
-}
-
-void OpenGLRenderer::debugClip() {
-#if DEBUG_CLIP_REGIONS
-    if (!currentSnapshot()->clipRegion->isEmpty()) {
-        SkPaint paint;
-        paint.setColor(0x7f00ff00);
-        drawRegionRects(*(currentSnapshot()->clipRegion, paint);
-
-    }
-#endif
-}
-
-void OpenGLRenderer::renderGlop(const Glop& glop, GlopRenderType type) {
-    // TODO: It would be best if we could do this before quickRejectSetupScissor()
-    //       changes the scissor test state
-    if (type != GlopRenderType::LayerClear) {
-        // Regular draws need to clear the dirty area on the layer before they start drawing on top
-        // of it. If this draw *is* a layer clear, it skips the clear step (since it would
-        // infinitely recurse)
-        clearLayerRegions();
-    }
-
-    if (mState.getDirtyClip()) {
-        if (mRenderState.scissor().isEnabled()) {
-            setScissorFromClip();
-        }
-
-        setStencilFromClip();
-    }
-    mRenderState.render(glop, currentSnapshot()->getOrthoMatrix());
-    if (type == GlopRenderType::Standard && !mRenderState.stencil().isWriteEnabled()) {
-        // TODO: specify more clearly when a draw should dirty the layer.
-        // is writing to the stencil the only time we should ignore this?
-#if !HWUI_NEW_OPS
-        dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom);
-#endif
-        mDirty = true;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Drawing
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t replayFlags) {
-    // All the usual checks and setup operations (quickReject, setupDraw, etc.)
-    // will be performed by the display list itself
-    if (renderNode && renderNode->isRenderable()) {
-        // compute 3d ordering
-        renderNode->computeOrdering();
-        if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
-            startFrame();
-            ReplayStateStruct replayStruct(*this, dirty, replayFlags);
-            renderNode->replay(replayStruct, 0);
-            return;
-        }
-
-        DeferredDisplayList deferredList(mState.currentRenderTargetClip());
-        DeferStateStruct deferStruct(deferredList, *this, replayFlags);
-        renderNode->defer(deferStruct, 0);
-
-        flushLayers();
-        startFrame();
-
-        deferredList.flush(*this, dirty);
-    } else {
-        // Even if there is no drawing command(Ex: invisible),
-        // it still needs startFrame to clear buffer and start tiling.
-        startFrame();
-    }
-}
-
-/**
- * Important note: this method is intended to draw batches of bitmaps and
- * will not set the scissor enable or dirty the current layer, if any.
- * The caller is responsible for properly dirtying the current layer.
- */
-void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
-        int bitmapCount, TextureVertex* vertices, bool pureTranslate,
-        const Rect& bounds, const SkPaint* paint) {
-    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
-    if (!texture) return;
-
-    const AutoTexture autoCleanup(texture);
-
-    // TODO: remove layer dirty in multi-draw callers
-    // TODO: snap doesn't need to touch transform, only texture filter.
-    bool snap = pureTranslate;
-    const float x = floorf(bounds.left + 0.5f);
-    const float y = floorf(bounds.top + 0.5f);
-
-    const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
-            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
-    const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedMesh(vertices, bitmapCount * 6)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(bounds.getWidth(), bounds.getHeight()))
-            .build();
-    renderGlop(glop, GlopRenderType::Multi);
-}
-
-void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
-    if (quickRejectSetupScissor(0, 0, bitmap->width(), bitmap->height())) {
-        return;
-    }
-
-    mCaches.textureState().activateTexture(0);
-    Texture* texture = getTexture(bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
-            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUnitQuad(texture->uvMapper)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRectSnap(Rect(texture->width(), texture->height()))
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
-        const float* vertices, const int* colors, const SkPaint* paint) {
-    if (!vertices || mState.currentlyIgnored()) {
-        return;
-    }
-
-    float left = FLT_MAX;
-    float top = FLT_MAX;
-    float right = FLT_MIN;
-    float bottom = FLT_MIN;
-
-    const uint32_t elementCount = meshWidth * meshHeight * 6;
-
-    std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[elementCount]);
-    ColorTextureVertex* vertex = &mesh[0];
-
-    std::unique_ptr<int[]> tempColors;
-    if (!colors) {
-        uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1);
-        tempColors.reset(new int[colorsCount]);
-        memset(tempColors.get(), 0xff, colorsCount * sizeof(int));
-        colors = tempColors.get();
-    }
-
-    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef());
-    const UvMapper& mapper(getMapper(texture));
-
-    for (int32_t y = 0; y < meshHeight; y++) {
-        for (int32_t x = 0; x < meshWidth; x++) {
-            uint32_t i = (y * (meshWidth + 1) + x) * 2;
-
-            float u1 = float(x) / meshWidth;
-            float u2 = float(x + 1) / meshWidth;
-            float v1 = float(y) / meshHeight;
-            float v2 = float(y + 1) / meshHeight;
-
-            mapper.map(u1, v1, u2, v2);
-
-            int ax = i + (meshWidth + 1) * 2;
-            int ay = ax + 1;
-            int bx = i;
-            int by = bx + 1;
-            int cx = i + 2;
-            int cy = cx + 1;
-            int dx = i + (meshWidth + 1) * 2 + 2;
-            int dy = dx + 1;
-
-            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2, colors[ax / 2]);
-            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
-
-            ColorTextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2, colors[dx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1, colors[bx / 2]);
-            ColorTextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1, colors[cx / 2]);
-
-            left = std::min(left, std::min(vertices[ax], std::min(vertices[bx], vertices[cx])));
-            top = std::min(top, std::min(vertices[ay], std::min(vertices[by], vertices[cy])));
-            right = std::max(right, std::max(vertices[ax], std::max(vertices[bx], vertices[cx])));
-            bottom = std::max(bottom, std::max(vertices[ay], std::max(vertices[by], vertices[cy])));
-        }
-    }
-
-    if (quickRejectSetupScissor(left, top, right, bottom)) {
-        return;
-    }
-
-    if (!texture) {
-        texture = mCaches.textureCache.get(bitmap);
-        if (!texture) {
-            return;
-        }
-    }
-    const AutoTexture autoCleanup(texture);
-
-    /*
-     * TODO: handle alpha_8 textures correctly by applying paint color, but *not*
-     * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh.
-     */
-    const int textureFillFlags = TextureFillFlags::None;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshColoredTexturedMesh(mesh.get(), elementCount)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom))
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, const SkPaint* paint) {
-    if (quickRejectSetupScissor(dst)) {
-        return;
-    }
-
-    Texture* texture = getTexture(bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    Rect uv(std::max(0.0f, src.left / texture->width()),
-            std::max(0.0f, src.top / texture->height()),
-            std::min(1.0f, src.right / texture->width()),
-            std::min(1.0f, src.bottom / texture->height()));
-
-    const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType)
-            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
-    const bool tryToSnap = MathUtils::areEqual(src.getWidth(), dst.getWidth())
-            && MathUtils::areEqual(src.getHeight(), dst.getHeight());
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUvQuad(texture->uvMapper, uv)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRectOptionalSnap(tryToSnap, dst)
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
-        AssetAtlas::Entry* entry, float left, float top, float right, float bottom,
-        const SkPaint* paint) {
-    if (!mesh || !mesh->verticesCount || quickRejectSetupScissor(left, top, right, bottom)) {
-        return;
-    }
-
-    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    // 9 patches are built for stretching - always filter
-    int textureFillFlags = TextureFillFlags::ForceFilter;
-    if (bitmap->colorType() == kAlpha_8_SkColorType) {
-        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
-    }
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshPatchQuads(*mesh)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewOffsetRectSnap(left, top, Rect(right - left, bottom - top)) // TODO: get minimal bounds from patch
-            .build();
-    renderGlop(glop);
-}
-
-/**
- * Important note: this method is intended to draw batches of 9-patch objects and
- * will not set the scissor enable or dirty the current layer, if any.
- * The caller is responsible for properly dirtying the current layer.
- */
-void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
-        TextureVertex* vertices, uint32_t elementCount, const SkPaint* paint) {
-    mCaches.textureState().activateTexture(0);
-    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    // TODO: get correct bounds from caller
-    const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform;
-    // 9 patches are built for stretching - always filter
-    int textureFillFlags = TextureFillFlags::ForceFilter;
-    if (bitmap->colorType() == kAlpha_8_SkColorType) {
-        textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
-    }
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedIndexedQuads(vertices, elementCount)
-            .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewOffsetRect(0, 0, Rect())
-            .build();
-    renderGlop(glop, GlopRenderType::Multi);
-}
-
-void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY,
-        const VertexBuffer& vertexBuffer, const SkPaint* paint, int displayFlags) {
-    // not missing call to quickReject/dirtyLayer, always done at a higher level
-    if (!vertexBuffer.getVertexCount()) {
-        // no vertices to draw
-        return;
-    }
-
-    bool shadowInterp = displayFlags & kVertexBuffer_ShadowInterp;
-    const int transformFlags = TransformFlags::OffsetByFudgeFactor;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshVertexBuffer(vertexBuffer)
-            .setFillPaint(*paint, currentSnapshot()->alpha, shadowInterp)
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds())
-            .build();
-    renderGlop(glop);
-}
-
-/**
- * Renders a convex path via tessellation. For AA paths, this function uses a similar approach to
- * that of AA lines in the drawLines() function.  We expand the convex path by a half pixel in
- * screen space in all directions. However, instead of using a fragment shader to compute the
- * translucency of the color from its position, we simply use a varying parameter to define how far
- * a given pixel is from the edge. For non-AA paths, the expansion and alpha varying are not used.
- *
- * Doesn't yet support joins, caps, or path effects.
- */
-void OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) {
-    VertexBuffer vertexBuffer;
-    // TODO: try clipping large paths to viewport
-
-    PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer);
-    drawVertexBuffer(vertexBuffer, paint);
-}
-
-/**
- * We create tristrips for the lines much like shape stroke tessellation, using a per-vertex alpha
- * and additional geometry for defining an alpha slope perimeter.
- *
- * Using GL_LINES can be difficult because the rasterization rules for those lines produces some
- * unexpected results, and may vary between hardware devices. Previously we used a varying-base
- * in-shader alpha region, but found it to be taxing on some GPUs.
- *
- * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce
- * memory transfer by removing need for degenerate vertices.
- */
-void OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
-    if (mState.currentlyIgnored() || count < 4) return;
-
-    count &= ~0x3; // round down to nearest four
-
-    VertexBuffer buffer;
-    PathTessellator::tessellateLines(points, count, paint, *currentTransform(), buffer);
-    const Rect& bounds = buffer.getBounds();
-
-    if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) {
-        return;
-    }
-
-    int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
-    drawVertexBuffer(buffer, paint, displayFlags);
-}
-
-void OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
-    if (mState.currentlyIgnored() || count < 2) return;
-
-    count &= ~0x1; // round down to nearest two
-
-    VertexBuffer buffer;
-    PathTessellator::tessellatePoints(points, count, paint, *currentTransform(), buffer);
-
-    const Rect& bounds = buffer.getBounds();
-    if (quickRejectSetupScissor(bounds.left, bounds.top, bounds.right, bounds.bottom)) {
-        return;
-    }
-
-    int displayFlags = paint->isAntiAlias() ? 0 : kVertexBuffer_Offset;
-    drawVertexBuffer(buffer, paint, displayFlags);
-
-    mDirty = true;
-}
-
-void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
-    // No need to check against the clip, we fill the clip region
-    if (mState.currentlyIgnored()) return;
-
-    Rect clip(mState.currentRenderTargetClip());
-    clip.snapToPixelBoundaries();
-
-    SkPaint paint;
-    paint.setColor(color);
-    paint.setXfermodeMode(mode);
-
-    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true);
-
-    mDirty = true;
-}
-
-void OpenGLRenderer::drawShape(float left, float top, PathTexture* texture,
-        const SkPaint* paint) {
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    const float x = left + texture->left - texture->offset;
-    const float y = top + texture->top - texture->offset;
-
-    drawPathTexture(texture, x, y, paint);
-
-    mDirty = true;
-}
-
-void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, const SkPaint* p) {
-    if (mState.currentlyIgnored()
-            || quickRejectSetupScissor(left, top, right, bottom, p)
-            || PaintUtils::paintWillNotDraw(*p)) {
-        return;
-    }
-
-    if (p->getPathEffect() != nullptr) {
-        mCaches.textureState().activateTexture(0);
-        PathTexture* texture = mCaches.pathCache.getRoundRect(
-                right - left, bottom - top, rx, ry, p);
-        drawShape(left, top, texture, p);
-    } else {
-        const VertexBuffer* vertexBuffer = mCaches.tessellationCache.getRoundRect(
-                *currentTransform(), *p, right - left, bottom - top, rx, ry);
-        drawVertexBuffer(left, top, *vertexBuffer, p);
-    }
-}
-
-void OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
-    if (mState.currentlyIgnored()
-            || quickRejectSetupScissor(x - radius, y - radius, x + radius, y + radius, p)
-            || PaintUtils::paintWillNotDraw(*p)) {
-        return;
-    }
-
-    if (p->getPathEffect() != nullptr) {
-        mCaches.textureState().activateTexture(0);
-        PathTexture* texture = mCaches.pathCache.getCircle(radius, p);
-        drawShape(x - radius, y - radius, texture, p);
-        return;
-    }
-
-    SkPath path;
-    if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
-        path.addCircle(x, y, radius + p->getStrokeWidth() / 2);
-    } else {
-        path.addCircle(x, y, radius);
-    }
-
-#if !HWUI_NEW_OPS
-    if (CC_UNLIKELY(currentSnapshot()->projectionPathMask != nullptr)) {
-        // mask ripples with projection mask
-        SkPath maskPath = *(currentSnapshot()->projectionPathMask->projectionMask);
-
-        Matrix4 screenSpaceTransform;
-        currentSnapshot()->buildScreenSpaceTransform(&screenSpaceTransform);
-
-        Matrix4 totalTransform;
-        totalTransform.loadInverse(screenSpaceTransform);
-        totalTransform.multiply(currentSnapshot()->projectionPathMask->projectionMaskTransform);
-
-        SkMatrix skTotalTransform;
-        totalTransform.copyTo(skTotalTransform);
-        maskPath.transform(skTotalTransform);
-
-        // Mask the ripple path by the projection mask, now that it's
-        // in local space. Note that this can create CCW paths.
-        Op(path, maskPath, kIntersect_SkPathOp, &path);
-    }
-#endif
-    drawConvexPath(path, p);
-}
-
-void OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
-        const SkPaint* p) {
-    if (mState.currentlyIgnored()
-            || quickRejectSetupScissor(left, top, right, bottom, p)
-            || PaintUtils::paintWillNotDraw(*p)) {
-        return;
-    }
-
-    if (p->getPathEffect() != nullptr) {
-        mCaches.textureState().activateTexture(0);
-        PathTexture* texture = mCaches.pathCache.getOval(right - left, bottom - top, p);
-        drawShape(left, top, texture, p);
-    } else {
-        SkPath path;
-        SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
-        if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
-            rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
-        }
-        path.addOval(rect);
-        drawConvexPath(path, p);
-    }
-}
-
-void OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
-    if (mState.currentlyIgnored()
-            || quickRejectSetupScissor(left, top, right, bottom, p)
-            || PaintUtils::paintWillNotDraw(*p)) {
-        return;
-    }
-
-    // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
-    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != nullptr || useCenter) {
-        mCaches.textureState().activateTexture(0);
-        PathTexture* texture = mCaches.pathCache.getArc(right - left, bottom - top,
-                startAngle, sweepAngle, useCenter, p);
-        drawShape(left, top, texture, p);
-        return;
-    }
-    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
-    if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
-        rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
-    }
-
-    SkPath path;
-    if (useCenter) {
-        path.moveTo(rect.centerX(), rect.centerY());
-    }
-    path.arcTo(rect, startAngle, sweepAngle, !useCenter);
-    if (useCenter) {
-        path.close();
-    }
-    drawConvexPath(path, p);
-}
-
-void OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
-        const SkPaint* p) {
-    if (mState.currentlyIgnored()
-            || quickRejectSetupScissor(left, top, right, bottom, p)
-            || PaintUtils::paintWillNotDraw(*p)) {
-        return;
-    }
-
-    if (p->getStyle() != SkPaint::kFill_Style) {
-        // only fill style is supported by drawConvexPath, since others have to handle joins
-        static_assert(SkPaintDefaults_MiterLimit == 4.0f, "Miter limit has changed");
-        if (p->getPathEffect() != nullptr || p->getStrokeJoin() != SkPaint::kMiter_Join ||
-                p->getStrokeMiter() != SkPaintDefaults_MiterLimit) {
-            mCaches.textureState().activateTexture(0);
-            PathTexture* texture =
-                    mCaches.pathCache.getRect(right - left, bottom - top, p);
-            drawShape(left, top, texture, p);
-        } else {
-            SkPath path;
-            SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
-            if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
-                rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
-            }
-            path.addRect(rect);
-            drawConvexPath(path, p);
-        }
-    } else {
-        if (p->isAntiAlias() && !currentTransform()->isSimple()) {
-            SkPath path;
-            path.addRect(left, top, right, bottom);
-            drawConvexPath(path, p);
-        } else {
-            drawColorRect(left, top, right, bottom, p);
-
-            mDirty = true;
-        }
-    }
-}
-
-void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const glyph_t* glyphs,
-        int count, const float* positions,
-        FontRenderer& fontRenderer, int alpha, float x, float y) {
-    mCaches.textureState().activateTexture(0);
-
-    PaintUtils::TextShadow textShadow;
-    if (!PaintUtils::getTextShadow(paint, &textShadow)) {
-        LOG_ALWAYS_FATAL("failed to query shadow attributes");
-    }
-
-    // NOTE: The drop shadow will not perform gamma correction
-    //       if shader-based correction is enabled
-    mCaches.dropShadowCache.setFontRenderer(fontRenderer);
-    ShadowTexture* texture = mCaches.dropShadowCache.get(
-            paint, glyphs, count, textShadow.radius, positions);
-    // If the drop shadow exceeds the max texture size or couldn't be
-    // allocated, skip drawing
-    if (!texture) return;
-    const AutoTexture autoCleanup(texture);
-
-    const float sx = x - texture->left + textShadow.dx;
-    const float sy = y - texture->top + textShadow.dy;
-
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUnitQuad(nullptr)
-            .setFillShadowTexturePaint(*texture, textShadow.color, *paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width(), sy + texture->height()))
-            .build();
-    renderGlop(glop);
-}
-
-// TODO: remove this, once mState.currentlyIgnored captures snapshot alpha
-bool OpenGLRenderer::canSkipText(const SkPaint* paint) const {
-    float alpha = (PaintUtils::hasTextShadow(paint)
-            ? 1.0f : paint->getAlpha()) * currentSnapshot()->alpha;
-    return MathUtils::isZero(alpha)
-            && PaintUtils::getXfermode(paint->getXfermode()) == SkXfermode::kSrcOver_Mode;
-}
-
-bool OpenGLRenderer::findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const {
-    if (CC_LIKELY(transform.isPureTranslate())) {
-        outMatrix->setIdentity();
-        return false;
-    } else if (CC_UNLIKELY(transform.isPerspective())) {
-        outMatrix->setIdentity();
-        return true;
-    }
-
-    /**
-     * Input is a non-perspective, scaling transform. Generate a scale-only transform,
-     * with values rounded to the nearest int.
-     */
-    float sx, sy;
-    transform.decomposeScale(sx, sy);
-    outMatrix->setScale(
-            roundf(std::max(1.0f, sx)),
-            roundf(std::max(1.0f, sy)));
-    return true;
-}
-
-int OpenGLRenderer::getSaveCount() const {
-    return mState.getSaveCount();
-}
-
-int OpenGLRenderer::save(int flags) {
-    return mState.save(flags);
-}
-
-void OpenGLRenderer::restore() {
-    mState.restore();
-}
-
-void OpenGLRenderer::restoreToCount(int saveCount) {
-    mState.restoreToCount(saveCount);
-}
-
-
-void OpenGLRenderer::translate(float dx, float dy, float dz) {
-    mState.translate(dx, dy, dz);
-}
-
-void OpenGLRenderer::rotate(float degrees) {
-    mState.rotate(degrees);
-}
-
-void OpenGLRenderer::scale(float sx, float sy) {
-    mState.scale(sx, sy);
-}
-
-void OpenGLRenderer::skew(float sx, float sy) {
-    mState.skew(sx, sy);
-}
-
-void OpenGLRenderer::setLocalMatrix(const Matrix4& matrix) {
-    mState.setMatrix(mBaseTransform);
-    mState.concatMatrix(matrix);
-}
-
-void OpenGLRenderer::setLocalMatrix(const SkMatrix& matrix) {
-    mState.setMatrix(mBaseTransform);
-    mState.concatMatrix(matrix);
-}
-
-void OpenGLRenderer::concatMatrix(const Matrix4& matrix) {
-    mState.concatMatrix(matrix);
-}
-
-bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
-    return mState.clipRect(left, top, right, bottom, op);
-}
-
-bool OpenGLRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
-    return mState.clipPath(path, op);
-}
-
-bool OpenGLRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
-    return mState.clipRegion(region, op);
-}
-
-void OpenGLRenderer::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
-    mState.setClippingOutline(allocator, outline);
-}
-
-void OpenGLRenderer::setClippingRoundRect(LinearAllocator& allocator,
-        const Rect& rect, float radius, bool highPriority) {
-    mState.setClippingRoundRect(allocator, rect, radius, highPriority);
-}
-
-void OpenGLRenderer::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
-    mState.setProjectionPathMask(allocator, path);
-}
-
-void OpenGLRenderer::drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y,
-        const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
-        DrawOpMode drawOpMode) {
-
-    if (drawOpMode == DrawOpMode::kImmediate) {
-        // The checks for corner-case ignorable text and quick rejection is only done for immediate
-        // drawing as ops from DeferredDisplayList are already filtered for these
-        if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) ||
-                quickRejectSetupScissor(bounds)) {
-            return;
-        }
-    }
-
-    const float oldX = x;
-    const float oldY = y;
-
-    const mat4& transform = *currentTransform();
-    const bool pureTranslate = transform.isPureTranslate();
-
-    if (CC_LIKELY(pureTranslate)) {
-        x = floorf(x + transform.getTranslateX() + 0.5f);
-        y = floorf(y + transform.getTranslateY() + 0.5f);
-    }
-
-    int alpha = PaintUtils::getAlphaDirect(paint) * currentSnapshot()->alpha;
-    SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(paint);
-
-    FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer();
-
-    if (CC_UNLIKELY(PaintUtils::hasTextShadow(paint))) {
-        fontRenderer.setFont(paint, SkMatrix::I());
-        drawTextShadow(paint, glyphs, count, positions, fontRenderer,
-                alpha, oldX, oldY);
-    }
-
-    const bool hasActiveLayer = hasLayer();
-
-    // We only pass a partial transform to the font renderer. That partial
-    // matrix defines how glyphs are rasterized. Typically we want glyphs
-    // to be rasterized at their final size on screen, which means the partial
-    // matrix needs to take the scale factor into account.
-    // When a partial matrix is used to transform glyphs during rasterization,
-    // the mesh is generated with the inverse transform (in the case of scale,
-    // the mesh is generated at 1.0 / scale for instance.) This allows us to
-    // apply the full transform matrix at draw time in the vertex shader.
-    // Applying the full matrix in the shader is the easiest way to handle
-    // rotation and perspective and allows us to always generated quads in the
-    // font renderer which greatly simplifies the code, clipping in particular.
-    SkMatrix fontTransform;
-    bool linearFilter = findBestFontTransform(transform, &fontTransform)
-            || fabs(y - (int) y) > 0.0f
-            || fabs(x - (int) x) > 0.0f;
-    fontRenderer.setFont(paint, fontTransform);
-    fontRenderer.setTextureFiltering(linearFilter);
-
-    // TODO: Implement better clipping for scaled/rotated text
-    const Rect* clip = !pureTranslate ? nullptr : &mState.currentRenderTargetClip();
-    Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
-
-    bool status;
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("unsupported");
-    TextDrawFunctor functor(nullptr, nullptr, nullptr, x, y, pureTranslate, alpha, mode, paint);
-#else
-    TextDrawFunctor functor(this, x, y, pureTranslate, alpha, mode, paint);
-#endif
-
-    // don't call issuedrawcommand, do it at end of batch
-    bool forceFinish = (drawOpMode != DrawOpMode::kDefer);
-    if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
-        SkPaint paintCopy(*paint);
-        paintCopy.setTextAlign(SkPaint::kLeft_Align);
-        status = fontRenderer.renderPosText(&paintCopy, clip, glyphs, count, x, y,
-                positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish);
-    } else {
-        status = fontRenderer.renderPosText(paint, clip, glyphs, count, x, y,
-                positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish);
-    }
-
-    if ((status || drawOpMode != DrawOpMode::kImmediate) && hasActiveLayer) {
-        if (!pureTranslate) {
-            transform.mapRect(layerBounds);
-        }
-        dirtyLayerUnchecked(layerBounds, getRegion());
-    }
-
-    mDirty = true;
-}
-
-void OpenGLRenderer::drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count,
-        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
-    if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) {
-        return;
-    }
-
-    // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics
-    mRenderState.scissor().setEnabled(true);
-
-    FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer();
-    fontRenderer.setFont(paint, SkMatrix::I());
-    fontRenderer.setTextureFiltering(true);
-
-    int alpha = PaintUtils::getAlphaDirect(paint) * currentSnapshot()->alpha;
-    SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(paint);
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("unsupported");
-    TextDrawFunctor functor(nullptr, nullptr, nullptr, 0.0f, 0.0f, false, alpha, mode, paint);
-#else
-    TextDrawFunctor functor(this, 0.0f, 0.0f, false, alpha, mode, paint);
-#endif
-
-    const Rect* clip = &writableSnapshot()->getLocalClip();
-    Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
-
-    if (fontRenderer.renderTextOnPath(paint, clip, glyphs, count, path,
-            hOffset, vOffset, hasLayer() ? &bounds : nullptr, &functor)) {
-        dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, *currentTransform());
-        mDirty = true;
-    }
-}
-
-void OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
-    if (mState.currentlyIgnored()) return;
-
-    mCaches.textureState().activateTexture(0);
-
-    PathTexture* texture = mCaches.pathCache.get(path, paint);
-    if (!texture) return;
-
-    const float x = texture->left - texture->offset;
-    const float y = texture->top - texture->offset;
-
-    drawPathTexture(texture, x, y, paint);
-
-    if (texture->cleanup) {
-        mCaches.pathCache.remove(path, paint);
-    }
-    mDirty = true;
-}
-
-void OpenGLRenderer::drawLayer(Layer* layer) {
-    if (!layer) {
-        return;
-    }
-
-    mat4* transform = nullptr;
-    if (layer->isTextureLayer()) {
-        transform = &layer->getTransform();
-        if (!transform->isIdentity()) {
-            save(SaveFlags::Matrix);
-            concatMatrix(*transform);
-        }
-    }
-
-    bool clipRequired = false;
-    const bool rejected = mState.calculateQuickRejectForScissor(
-            0, 0, layer->layer.getWidth(), layer->layer.getHeight(),
-            &clipRequired, nullptr, false);
-
-    if (rejected) {
-        if (transform && !transform->isIdentity()) {
-            restore();
-        }
-        return;
-    }
-
-    EVENT_LOGD("drawLayer," RECT_STRING ", clipRequired %d", x, y,
-            x + layer->layer.getWidth(), y + layer->layer.getHeight(), clipRequired);
-
-    updateLayer(layer, true);
-
-    mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired);
-    mCaches.textureState().activateTexture(0);
-
-    if (CC_LIKELY(!layer->region.isEmpty())) {
-        if (layer->region.isRect()) {
-            DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
-                    composeLayerRect(layer, layer->regionRect));
-        } else if (layer->mesh) {
-            Glop glop;
-            GlopBuilder(mRenderState, mCaches, &glop)
-                    .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-                    .setMeshTexturedIndexedQuads(layer->mesh, layer->meshElementCount)
-                    .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap)
-                    .setTransform(*currentSnapshot(),  TransformFlags::None)
-                    .setModelViewOffsetRectSnap(0, 0, Rect(layer->layer.getWidth(), layer->layer.getHeight()))
-                    .build();
-            DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, renderGlop(glop));
-#if DEBUG_LAYERS_AS_REGIONS
-            drawRegionRectsDebug(layer->region);
-#endif
-        }
-
-        if (layer->debugDrawUpdate) {
-            layer->debugDrawUpdate = false;
-
-            SkPaint paint;
-            paint.setColor(0x7f00ff00);
-            drawColorRect(0, 0, layer->layer.getWidth(), layer->layer.getHeight(), &paint);
-        }
-    }
-    layer->hasDrawnSinceUpdate = true;
-
-    if (transform && !transform->isIdentity()) {
-        restore();
-    }
-
-    mDirty = true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Draw filters
-///////////////////////////////////////////////////////////////////////////////
-void OpenGLRenderer::setDrawFilter(SkDrawFilter* filter) {
-    // We should never get here since we apply the draw filter when stashing
-    // the paints in the DisplayList.
-    LOG_ALWAYS_FATAL("OpenGLRenderer does not directly support DrawFilters");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Drawing implementation
-///////////////////////////////////////////////////////////////////////////////
-
-Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
-    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef());
-    if (!texture) {
-        return mCaches.textureCache.get(bitmap);
-    }
-    return texture;
-}
-
-void OpenGLRenderer::drawPathTexture(PathTexture* texture, float x, float y,
-        const SkPaint* paint) {
-    if (quickRejectSetupScissor(x, y, x + texture->width(), y + texture->height())) {
-        return;
-    }
-
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshTexturedUnitQuad(nullptr)
-            .setFillPathTexturePaint(*texture, *paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(),  TransformFlags::None)
-            .setModelViewMapUnitToRect(Rect(x, y, x + texture->width(), y + texture->height()))
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
-    if (mState.currentlyIgnored()) {
-        return;
-    }
-
-    drawColorRects(rects, count, paint, false, true, true);
-}
-
-void OpenGLRenderer::drawShadow(float casterAlpha,
-        const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) {
-    if (mState.currentlyIgnored()) return;
-
-    // TODO: use quickRejectWithScissor. For now, always force enable scissor.
-    mRenderState.scissor().setEnabled(true);
-
-    SkPaint paint;
-    paint.setAntiAlias(true); // want to use AlphaVertex
-
-    // The caller has made sure casterAlpha > 0.
-    float ambientShadowAlpha = mAmbientShadowAlpha;
-    if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
-        ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
-    }
-    if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) {
-        paint.setARGB(casterAlpha * ambientShadowAlpha, 0, 0, 0);
-        drawVertexBuffer(*ambientShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp);
-    }
-
-    float spotShadowAlpha = mSpotShadowAlpha;
-    if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
-        spotShadowAlpha = Properties::overrideSpotShadowStrength;
-    }
-    if (spotShadowVertexBuffer && spotShadowAlpha > 0) {
-        paint.setARGB(casterAlpha * spotShadowAlpha, 0, 0, 0);
-        drawVertexBuffer(*spotShadowVertexBuffer, &paint, kVertexBuffer_ShadowInterp);
-    }
-
-    mDirty=true;
-}
-
-void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint,
-        bool ignoreTransform, bool dirty, bool clip) {
-    if (count == 0) {
-        return;
-    }
-
-    float left = FLT_MAX;
-    float top = FLT_MAX;
-    float right = FLT_MIN;
-    float bottom = FLT_MIN;
-
-    Vertex mesh[count];
-    Vertex* vertex = mesh;
-
-    for (int index = 0; index < count; index += 4) {
-        float l = rects[index + 0];
-        float t = rects[index + 1];
-        float r = rects[index + 2];
-        float b = rects[index + 3];
-
-        Vertex::set(vertex++, l, t);
-        Vertex::set(vertex++, r, t);
-        Vertex::set(vertex++, l, b);
-        Vertex::set(vertex++, r, b);
-
-        left = std::min(left, l);
-        top = std::min(top, t);
-        right = std::max(right, r);
-        bottom = std::max(bottom, b);
-    }
-
-    if (clip && quickRejectSetupScissor(left, top, right, bottom)) {
-        return;
-    }
-
-    const int transformFlags = ignoreTransform
-            ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshIndexedQuads(&mesh[0], count / 4)
-            .setFillPaint(*paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom))
-            .build();
-    renderGlop(glop);
-}
-
-void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
-        const SkPaint* paint, bool ignoreTransform) {
-    const int transformFlags = ignoreTransform
-            ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None;
-    Glop glop;
-    GlopBuilder(mRenderState, mCaches, &glop)
-            .setRoundRectClipState(currentSnapshot()->roundRectClipState)
-            .setMeshUnitQuad()
-            .setFillPaint(*paint, currentSnapshot()->alpha)
-            .setTransform(*currentSnapshot(), transformFlags)
-            .setModelViewMapUnitToRect(Rect(left, top, right, bottom))
-            .build();
-    renderGlop(glop);
-}
-
-float OpenGLRenderer::getLayerAlpha(const Layer* layer) const {
-    return (layer->getAlpha() / 255.0f) * currentSnapshot()->alpha;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
deleted file mode 100755
index dacd8cc..0000000
--- a/libs/hwui/OpenGLRenderer.h
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_OPENGL_RENDERER_H
-#define ANDROID_HWUI_OPENGL_RENDERER_H
-
-#include "CanvasState.h"
-#include "Debug.h"
-#include "Extensions.h"
-#include "Matrix.h"
-#include "Program.h"
-#include "Rect.h"
-#include "Snapshot.h"
-#include "UvMapper.h"
-#include "Vertex.h"
-#include "Caches.h"
-#include "utils/PaintUtils.h"
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkColorFilter.h>
-#include <SkDrawLooper.h>
-#include <SkMatrix.h>
-#include <SkPaint.h>
-#include <SkRegion.h>
-#include <SkXfermode.h>
-
-#include <utils/Blur.h>
-#include <utils/Functor.h>
-#include <utils/RefBase.h>
-#include <utils/SortedVector.h>
-
-#include <cutils/compiler.h>
-
-#include <androidfw/ResourceTypes.h>
-
-#include <vector>
-
-class SkShader;
-
-namespace android {
-namespace uirenderer {
-
-enum class DrawOpMode {
-    kImmediate,
-    kDefer,
-    kFlush
-};
-
-class DeferredDisplayState;
-struct Glop;
-class RenderState;
-class RenderNode;
-class TextDrawFunctor;
-class VertexBuffer;
-
-enum StateDeferFlags {
-    kStateDeferFlag_Draw = 0x1,
-    kStateDeferFlag_Clip = 0x2
-};
-
-enum ClipSideFlags {
-    kClipSide_None = 0x0,
-    kClipSide_Left = 0x1,
-    kClipSide_Top = 0x2,
-    kClipSide_Right = 0x4,
-    kClipSide_Bottom = 0x8,
-    kClipSide_Full = 0xF,
-    kClipSide_ConservativeFull = 0x1F
-};
-
-enum VertexBufferDisplayFlags {
-    kVertexBuffer_Offset = 0x1,
-    kVertexBuffer_ShadowInterp = 0x2,
-};
-
-/**
- * Defines additional transformation that should be applied by the model view matrix, beyond that of
- * the currentTransform()
- */
-enum ModelViewMode {
-    /**
-     * Used when the model view should simply translate geometry passed to the shader. The resulting
-     * matrix will be a simple translation.
-     */
-    kModelViewMode_Translate = 0,
-
-    /**
-     * Used when the model view should translate and scale geometry. The resulting matrix will be a
-     * translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
-     */
-    kModelViewMode_TranslateAndScale = 1,
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Renderer
-///////////////////////////////////////////////////////////////////////////////
-/**
- * OpenGL Renderer implementation.
- */
-class OpenGLRenderer : public CanvasStateClient {
-public:
-    OpenGLRenderer(RenderState& renderState);
-    virtual ~OpenGLRenderer();
-
-    void initProperties();
-    void initLight(float lightRadius, uint8_t ambientShadowAlpha,
-            uint8_t spotShadowAlpha);
-    void setLightCenter(const Vector3& lightCenter);
-
-    /*
-     * Prepares the renderer to draw a frame. This method must be invoked
-     * at the beginning of each frame. Only the specified rectangle of the
-     * frame is assumed to be dirty. A clip will automatically be set to
-     * the specified rectangle.
-     *
-     * @param opaque If true, the target surface is considered opaque
-     *               and will not be cleared. If false, the target surface
-     *               will be cleared
-     */
-    virtual void prepareDirty(int viewportWidth, int viewportHeight,
-            float left, float top, float right, float bottom, bool opaque);
-
-    /**
-     * Indicates the end of a frame. This method must be invoked whenever
-     * the caller is done rendering a frame.
-     * Returns true if any drawing was done during the frame (the output
-     * has changed / is "dirty" and should be displayed to the user).
-     */
-    virtual bool finish();
-
-    void callDrawGLFunction(Functor* functor, Rect& dirty);
-
-    void pushLayerUpdate(Layer* layer);
-    void cancelLayerUpdate(Layer* layer);
-    void flushLayerUpdates();
-    void markLayersAsBuildLayers();
-
-    virtual int saveLayer(float left, float top, float right, float bottom,
-            const SkPaint* paint, int flags) {
-        return saveLayer(left, top, right, bottom, paint, flags, nullptr);
-    }
-
-    // Specialized saveLayer implementation, which will pass the convexMask to an FBO layer, if
-    // created, which will in turn clip to that mask when drawn back/restored.
-    int saveLayer(float left, float top, float right, float bottom,
-            const SkPaint* paint, int flags, const SkPath* convexMask);
-
-    int saveLayerDeferred(float left, float top, float right, float bottom,
-            const SkPaint* paint, int flags);
-
-    void drawRenderNode(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
-    void drawLayer(Layer* layer);
-    void drawBitmap(const SkBitmap* bitmap, const SkPaint* paint);
-    void drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
-            TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
-    void drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst,
-            const SkPaint* paint);
-    void drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
-            const float* vertices, const int* colors, const SkPaint* paint);
-    void drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
-            TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
-    void drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
-            float left, float top, float right, float bottom, const SkPaint* paint);
-    void drawColor(int color, SkXfermode::Mode mode);
-    void drawRect(float left, float top, float right, float bottom,
-            const SkPaint* paint);
-    void drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, const SkPaint* paint);
-    void drawCircle(float x, float y, float radius, const SkPaint* paint);
-    void drawOval(float left, float top, float right, float bottom,
-            const SkPaint* paint);
-    void drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
-    void drawPath(const SkPath* path, const SkPaint* paint);
-    void drawLines(const float* points, int count, const SkPaint* paint);
-    void drawPoints(const float* points, int count, const SkPaint* paint);
-    void drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count, const SkPath* path,
-            float hOffset, float vOffset, const SkPaint* paint);
-    void drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y,
-            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
-            DrawOpMode drawOpMode = DrawOpMode::kImmediate);
-    void drawRects(const float* rects, int count, const SkPaint* paint);
-
-    void drawShadow(float casterAlpha,
-            const VertexBuffer* ambientShadowVertexBuffer,
-            const VertexBuffer* spotShadowVertexBuffer);
-
-    void setDrawFilter(SkDrawFilter* filter);
-
-    /**
-     * Store the current display state (most importantly, the current clip and transform), and
-     * additionally map the state's bounds from local to window coordinates.
-     *
-     * Returns true if quick-rejected
-     */
-    bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
-    void restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore = false);
-    void setupMergedMultiDraw(const Rect* clipRect);
-
-    bool isCurrentTransformSimple() {
-        return currentTransform()->isSimple();
-    }
-
-    Caches& getCaches() {
-        return mCaches;
-    }
-
-    RenderState& renderState() {
-        return mRenderState;
-    }
-
-    int getViewportWidth() { return mState.getViewportWidth(); }
-    int getViewportHeight() { return mState.getViewportHeight(); }
-
-    /**
-     * Scales the alpha on the current snapshot. This alpha value will be modulated
-     * with other alpha values when drawing primitives.
-     */
-    void scaleAlpha(float alpha) { mState.scaleAlpha(alpha); }
-
-    /**
-     * Inserts a named event marker in the stream of GL commands.
-     */
-    void eventMark(const char* name) const;
-
-    /**
-     * Inserts a formatted event marker in the stream of GL commands.
-     */
-    void eventMarkDEBUG(const char *fmt, ...) const;
-
-    /**
-     * Inserts a named group marker in the stream of GL commands. This marker
-     * can be used by tools to group commands into logical groups. A call to
-     * this method must always be followed later on by a call to endMark().
-     */
-    void startMark(const char* name) const;
-
-    /**
-     * Closes the last group marker opened by startMark().
-     */
-    void endMark() const;
-
-    /**
-     * Build the best transform to use to rasterize text given a full
-     * transform matrix, and whether filteration is needed.
-     *
-     * Returns whether filtration is needed
-     */
-    bool findBestFontTransform(const mat4& transform, SkMatrix* outMatrix) const;
-
-#if DEBUG_MERGE_BEHAVIOR
-    void drawScreenSpaceColorRect(float left, float top, float right, float bottom, int color) {
-        mCaches.setScissorEnabled(false);
-
-        // should only be called outside of other draw ops, so stencil can only be in test state
-        bool stencilWasEnabled = mCaches.stencil.isTestEnabled();
-        mCaches.stencil.disable();
-
-        drawColorRect(left, top, right, bottom, color, SkXfermode::kSrcOver_Mode, true);
-
-        if (stencilWasEnabled) mCaches.stencil.enableTest();
-        mDirty = true;
-    }
-#endif
-
-    const Vector3& getLightCenter() const { return mState.currentLightCenter(); }
-    float getLightRadius() const { return mLightRadius; }
-    uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
-    uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
-
-    ///////////////////////////////////////////////////////////////////
-    /// State manipulation
-
-    int getSaveCount() const;
-    int save(int flags);
-    void restore();
-    void restoreToCount(int saveCount);
-
-    void setGlobalMatrix(const Matrix4& matrix) {
-        mState.setMatrix(matrix);
-    }
-    void setLocalMatrix(const Matrix4& matrix);
-    void setLocalMatrix(const SkMatrix& matrix);
-    void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
-
-    void translate(float dx, float dy, float dz = 0.0f);
-    void rotate(float degrees);
-    void scale(float sx, float sy);
-    void skew(float sx, float sy);
-
-    void setMatrix(const Matrix4& matrix); // internal only convenience method
-    void concatMatrix(const Matrix4& matrix); // internal only convenience method
-
-    const Rect& getLocalClipBounds() const { return mState.getLocalClipBounds(); }
-    const Rect& getRenderTargetClipBounds() const { return mState.getRenderTargetClipBounds(); }
-    bool quickRejectConservative(float left, float top,
-            float right, float bottom) const {
-        return mState.quickRejectConservative(left, top, right, bottom);
-    }
-
-    bool clipRect(float left, float top,
-            float right, float bottom, SkRegion::Op op);
-    bool clipPath(const SkPath* path, SkRegion::Op op);
-    bool clipRegion(const SkRegion* region, SkRegion::Op op);
-
-    /**
-     * Does not support different clipping Ops (that is, every call to setClippingOutline is
-     * effectively using SkRegion::kReplaceOp)
-     *
-     * The clipping outline is independent from the regular clip.
-     */
-    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
-    void setClippingRoundRect(LinearAllocator& allocator,
-            const Rect& rect, float radius, bool highPriority = true);
-    void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);
-
-    inline bool hasRectToRectTransform() const { return mState.hasRectToRectTransform(); }
-    inline const mat4* currentTransform() const { return mState.currentTransform(); }
-
-    ///////////////////////////////////////////////////////////////////
-    /// CanvasStateClient interface
-
-    virtual void onViewportInitialized() override;
-    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
-    virtual GLuint getTargetFbo() const override { return 0; }
-
-    SkPath* allocPathForFrame() {
-        std::unique_ptr<SkPath> path(new SkPath());
-        SkPath* returnPath = path.get();
-        mTempPaths.push_back(std::move(path));
-        return returnPath;
-    }
-
-    void setBaseTransform(const Matrix4& matrix) { mBaseTransform = matrix; }
-
-protected:
-    /**
-     * Perform the setup specific to a frame. This method does not
-     * issue any OpenGL commands.
-     */
-    void setupFrameState(int viewportWidth, int viewportHeight,
-            float left, float top, float right, float bottom, bool opaque);
-
-    /**
-     * Indicates the start of rendering. This method will setup the
-     * initial OpenGL state (viewport, clearing the buffer, etc.)
-     */
-    void startFrame();
-
-    /**
-     * Clears the underlying surface if needed.
-     */
-    virtual void clear(float left, float top, float right, float bottom, bool opaque);
-
-    /**
-     * Call this method after updating a layer during a drawing pass.
-     */
-    void resumeAfterLayer();
-
-    /**
-     * This method is called whenever a stencil buffer is required. Subclasses
-     * should override this method and call attachStencilBufferToLayer() on the
-     * appropriate layer(s).
-     */
-    virtual void ensureStencilBuffer();
-
-    /**
-     * Obtains a stencil render buffer (allocating it if necessary) and
-     * attaches it to the specified layer.
-     */
-    void attachStencilBufferToLayer(Layer* layer);
-
-    /**
-     * Draw a rectangle list. Currently only used for the the stencil buffer so that the stencil
-     * will have a value of 'n' in every unclipped pixel, where 'n' is the number of rectangles
-     * in the list.
-     */
-    void drawRectangleList(const RectangleList& rectangleList);
-
-    bool quickRejectSetupScissor(float left, float top, float right, float bottom,
-            const SkPaint* paint = nullptr);
-    bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = nullptr) {
-        return quickRejectSetupScissor(bounds.left, bounds.top,
-                bounds.right, bounds.bottom, paint);
-    }
-
-    /**
-     * Compose the layer defined in the current snapshot with the layer
-     * defined by the previous snapshot.
-     *
-     * The current snapshot *must* be a layer (flag kFlagIsLayer set.)
-     *
-     * @param curent The current snapshot containing the layer to compose
-     * @param previous The previous snapshot to compose the current layer with
-     */
-    virtual void composeLayer(const Snapshot& current, const Snapshot& previous);
-
-    /**
-     * Marks the specified region as dirty at the specified bounds.
-     */
-    void dirtyLayerUnchecked(Rect& bounds, Region* region);
-
-    /**
-     * Returns the region of the current layer.
-     */
-    virtual Region* getRegion() const {
-        return mState.currentRegion();
-    }
-
-    /**
-     * Indicates whether rendering is currently targeted at a layer.
-     */
-    virtual bool hasLayer() const {
-        return (mState.currentFlags() & Snapshot::kFlagFboTarget) && mState.currentRegion();
-    }
-
-    /**
-     * Renders the specified layer as a textured quad.
-     *
-     * @param layer The layer to render
-     * @param rect The bounds of the layer
-     */
-    void drawTextureLayer(Layer* layer, const Rect& rect);
-
-    /**
-     * Gets the alpha from a layer, accounting for snapshot alpha
-     *
-     * @param layer The layer from which the alpha is extracted
-     */
-    inline float getLayerAlpha(const Layer* layer) const;
-
-    /**
-     * Set to true to suppress error checks at the end of a frame.
-     */
-    virtual bool suppressErrorChecks() const {
-        return false;
-    }
-
-    CanvasState mState;
-    Caches& mCaches;
-    RenderState& mRenderState;
-
-private:
-    enum class GlopRenderType {
-        Standard,
-        Multi,
-        LayerClear
-    };
-
-    void renderGlop(const Glop& glop, GlopRenderType type = GlopRenderType::Standard);
-
-    /**
-     * Discards the content of the framebuffer if supported by the driver.
-     * This method should be called at the beginning of a frame to optimize
-     * rendering on some tiler architectures.
-     */
-    void discardFramebuffer(float left, float top, float right, float bottom);
-
-    /**
-     * Sets the clipping rectangle using glScissor. The clip is defined by
-     * the current snapshot's clipRect member.
-     */
-    void setScissorFromClip();
-
-    /**
-     * Sets the clipping region using the stencil buffer. The clip region
-     * is defined by the current snapshot's clipRegion member.
-     */
-    void setStencilFromClip();
-
-    /**
-     * Given the local bounds of the layer, calculates ...
-     */
-    void calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer);
-
-    /**
-     * Given the local bounds + clip of the layer, updates current snapshot's empty/invisible
-     */
-    void updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect& clip,
-            bool fboLayer, int alpha);
-
-    /**
-     * Creates a new layer stored in the specified snapshot.
-     *
-     * @param snapshot The snapshot associated with the new layer
-     * @param left The left coordinate of the layer
-     * @param top The top coordinate of the layer
-     * @param right The right coordinate of the layer
-     * @param bottom The bottom coordinate of the layer
-     * @param alpha The translucency of the layer
-     * @param mode The blending mode of the layer
-     * @param flags The layer save flags
-     * @param mask A mask to use when drawing the layer back, may be empty
-     *
-     * @return True if the layer was successfully created, false otherwise
-     */
-    bool createLayer(float left, float top, float right, float bottom,
-            const SkPaint* paint, int flags, const SkPath* convexMask);
-
-    /**
-     * Creates a new layer stored in the specified snapshot as an FBO.
-     *
-     * @param layer The layer to store as an FBO
-     * @param snapshot The snapshot associated with the new layer
-     * @param bounds The bounds of the layer
-     */
-    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip);
-
-    /**
-     * Compose the specified layer as a region.
-     *
-     * @param layer The layer to compose
-     * @param rect The layer's bounds
-     */
-    void composeLayerRegion(Layer* layer, const Rect& rect);
-
-    /**
-     * Restores the content in layer to the screen, swapping the blend mode,
-     * specifically used in the restore() of a saveLayerAlpha().
-     *
-     * This allows e.g. a layer that would have been drawn on top of existing content (with SrcOver)
-     * to be drawn underneath.
-     *
-     * This will always ignore the canvas transform.
-     */
-    void composeLayerRectSwapped(Layer* layer, const Rect& rect);
-
-    /**
-     * Draws the content in layer to the screen.
-     */
-    void composeLayerRect(Layer* layer, const Rect& rect);
-
-    /**
-     * Clears all the regions corresponding to the current list of layers.
-     * This method MUST be invoked before any drawing operation.
-     */
-    void clearLayerRegions();
-
-    /**
-     * Mark the layer as dirty at the specified coordinates. The coordinates
-     * are transformed with the supplied matrix.
-     */
-    void dirtyLayer(const float left, const float top,
-            const float right, const float bottom, const Matrix4& transform);
-
-    /**
-     * Mark the layer as dirty at the specified coordinates.
-     */
-    void dirtyLayer(const float left, const float top,
-            const float right, const float bottom);
-
-    /**
-     * Draws a colored rectangle with the specified color. The specified coordinates
-     * are transformed by the current snapshot's transform matrix unless specified
-     * otherwise.
-     *
-     * @param left The left coordinate of the rectangle
-     * @param top The top coordinate of the rectangle
-     * @param right The right coordinate of the rectangle
-     * @param bottom The bottom coordinate of the rectangle
-     * @param paint The paint containing the color, blending mode, etc.
-     * @param ignoreTransform True if the current transform should be ignored
-     */
-    void drawColorRect(float left, float top, float right, float bottom,
-            const SkPaint* paint, bool ignoreTransform = false);
-
-    /**
-     * Draws a series of colored rectangles with the specified color. The specified
-     * coordinates are transformed by the current snapshot's transform matrix unless
-     * specified otherwise.
-     *
-     * @param rects A list of rectangles, 4 floats (left, top, right, bottom)
-     *              per rectangle
-     * @param paint The paint containing the color, blending mode, etc.
-     * @param ignoreTransform True if the current transform should be ignored
-     * @param dirty True if calling this method should dirty the current layer
-     * @param clip True if the rects should be clipped, false otherwise
-     */
-    void drawColorRects(const float* rects, int count, const SkPaint* paint,
-            bool ignoreTransform = false, bool dirty = true, bool clip = true);
-
-    /**
-     * Draws the shape represented by the specified path texture.
-     * This method invokes drawPathTexture() but takes into account
-     * the extra left/top offset and the texture offset to correctly
-     * position the final shape.
-     *
-     * @param left The left coordinate of the shape to render
-     * @param top The top coordinate of the shape to render
-     * @param texture The texture reprsenting the shape
-     * @param paint The paint to draw the shape with
-     */
-    void drawShape(float left, float top, PathTexture* texture, const SkPaint* paint);
-
-    /**
-     * Renders a strip of polygons with the specified paint, used for tessellated geometry.
-     *
-     * @param vertexBuffer The VertexBuffer to be drawn
-     * @param paint The paint to render with
-     * @param flags flags with which to draw
-     */
-    void drawVertexBuffer(float translateX, float translateY, const VertexBuffer& vertexBuffer,
-            const SkPaint* paint, int flags = 0);
-
-    /**
-     * Convenience for translating method
-     */
-    void drawVertexBuffer(const VertexBuffer& vertexBuffer,
-            const SkPaint* paint, int flags = 0) {
-        drawVertexBuffer(0.0f, 0.0f, vertexBuffer, paint, flags);
-    }
-
-    /**
-     * Renders the convex hull defined by the specified path as a strip of polygons.
-     *
-     * @param path The hull of the path to draw
-     * @param paint The paint to render with
-     */
-    void drawConvexPath(const SkPath& path, const SkPaint* paint);
-
-   /**
-     * Draws shadow layer on text (with optional positions).
-     *
-     * @param paint The paint to draw the shadow with
-     * @param text The text to draw
-     * @param count The number of glyphs in the text
-     * @param positions The x, y positions of individual glyphs (or NULL)
-     * @param fontRenderer The font renderer object
-     * @param alpha The alpha value for drawing the shadow
-     * @param x The x coordinate where the shadow will be drawn
-     * @param y The y coordinate where the shadow will be drawn
-     */
-    void drawTextShadow(const SkPaint* paint, const glyph_t* glyphs, int count,
-            const float* positions, FontRenderer& fontRenderer, int alpha,
-            float x, float y);
-
-    /**
-     * Draws a path texture. Path textures are alpha8 bitmaps that need special
-     * compositing to apply colors/filters/etc.
-     *
-     * @param texture The texture to render
-     * @param x The x coordinate where the texture will be drawn
-     * @param y The y coordinate where the texture will be drawn
-     * @param paint The paint to draw the texture with
-     */
-     void drawPathTexture(PathTexture* texture, float x, float y, const SkPaint* paint);
-
-    /**
-     * Resets the texture coordinates stored in mMeshVertices. Setting the values
-     * back to default is achieved by calling:
-     *
-     * resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
-     *
-     * @param u1 The left coordinate of the texture
-     * @param v1 The bottom coordinate of the texture
-     * @param u2 The right coordinate of the texture
-     * @param v2 The top coordinate of the texture
-     */
-    void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2);
-
-    /**
-     * Returns true if the specified paint will draw invisible text.
-     */
-    bool canSkipText(const SkPaint* paint) const;
-
-    bool updateLayer(Layer* layer, bool inFrame);
-    void updateLayers();
-    void flushLayers();
-
-#if DEBUG_LAYERS_AS_REGIONS
-    /**
-     * Renders the specified region as a series of rectangles. This method
-     * is used for debugging only.
-     */
-    void drawRegionRectsDebug(const Region& region);
-#endif
-
-    /**
-     * Renders the specified region as a series of rectangles. The region
-     * must be in screen-space coordinates.
-     */
-    void drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty = false);
-
-    /**
-     * Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
-     * is turned on.
-     */
-    void debugClip();
-
-    void debugOverdraw(bool enable, bool clear);
-    void renderOverdraw();
-    void countOverdraw();
-
-    /**
-     * Should be invoked every time the glScissor is modified.
-     */
-    inline void dirtyClip() { mState.setDirtyClip(true); }
-
-    inline const UvMapper& getMapper(const Texture* texture) {
-        return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
-    }
-
-    /**
-     * Returns a texture object for the specified bitmap. The texture can
-     * come from the texture cache or an atlas. If this method returns
-     * NULL, the texture could not be found and/or allocated.
-     */
-    Texture* getTexture(const SkBitmap* bitmap);
-
-    bool reportAndClearDirty() { bool ret = mDirty; mDirty = false; return ret; }
-    inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); }
-    inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); }
-
-    // State used to define the clipping region
-    Rect mTilingClip;
-    // Is the target render surface opaque
-    bool mOpaque;
-    // Is a frame currently being rendered
-    bool mFrameStarted;
-
-    // Default UV mapper
-    const UvMapper mUvMapper;
-
-    // List of rectangles to clear after saveLayer() is invoked
-    std::vector<Rect> mLayers;
-    // List of layers to update at the beginning of a frame
-    std::vector< sp<Layer> > mLayerUpdates;
-
-    // See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
-    // Properties.h
-    bool mScissorOptimizationDisabled;
-
-    bool mSkipOutlineClip;
-
-    // True if anything has been drawn since the last call to
-    // reportAndClearDirty()
-    bool mDirty;
-
-    // Lighting + shadows
-    Vector3 mLightCenter;
-    float mLightRadius;
-    uint8_t mAmbientShadowAlpha;
-    uint8_t mSpotShadowAlpha;
-
-    // Paths kept alive for the duration of the frame
-    std::vector<std::unique_ptr<SkPath>> mTempPaths;
-
-    /**
-     * Initial transform for a rendering pass; transform from global device
-     * coordinates to the current RenderNode's drawing content coordinates,
-     * with the RenderNode's RenderProperty transforms already applied.
-     * Calling setMatrix(mBaseTransform) will result in drawing at the origin
-     * of the DisplayList's recorded surface prior to any Canvas
-     * transformation.
-     */
-    Matrix4 mBaseTransform;
-
-    friend class Layer;
-    friend class TextDrawFunctor;
-    friend class DrawBitmapOp;
-    friend class DrawPatchOp;
-
-}; // class OpenGLRenderer
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_OPENGL_RENDERER_H
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index d1c5dbf..4e587fb 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_PATCH_CACHE_H
-#define ANDROID_HWUI_PATCH_CACHE_H
+#pragma once
 
 #include <GLES2/gl2.h>
 
@@ -48,6 +47,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class Caches;
+class RenderState;
 
 class PatchCache {
 public:
@@ -186,5 +186,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_PATCH_CACHE_H
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 880a90e..5d892fd 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -20,8 +20,7 @@
 #include <cutils/properties.h>
 
 /**
- * This file contains the list of system properties used to configure
- * the OpenGLRenderer.
+ * This file contains the list of system properties used to configure libhwui.
  */
 
 namespace android {
@@ -167,7 +166,7 @@
  * Used to enable/disable scissor optimization. The accepted values are
  * "true" and "false". The default value is "false".
  *
- * When scissor optimization is enabled, OpenGLRenderer will attempt to
+ * When scissor optimization is enabled, libhwui will attempt to
  * minimize the use of scissor by selectively enabling and disabling the
  * GL scissor test.
  * When the optimization is disabled, OpenGLRenderer will keep the GL
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index aee9d63..f3078ce 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_RECORDED_OP_H
-#define ANDROID_HWUI_RECORDED_OP_H
+#pragma once
 
-#include "RecordedOp.h"
 #include "font/FontUtil.h"
 #include "Matrix.h"
 #include "Rect.h"
 #include "RenderNode.h"
 #include "TessellationCache.h"
 #include "utils/LinearAllocator.h"
+#include "utils/PaintUtils.h"
 #include "Vector.h"
 
 #include <androidfw/ResourceTypes.h>
@@ -529,5 +528,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_RECORDED_OP_H
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index cbefccb..4528a38 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -43,7 +43,6 @@
     mState.initializeRecordingSaveStack(width, height);
 
     mDeferredBarrierType = DeferredBarrierType::InOrder;
-    mState.setDirtyClip(false);
 }
 
 DisplayList* RecordingCanvas::finishRecording() {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index f8797bf..5330e23 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -16,19 +16,17 @@
 
 #include "RenderNode.h"
 
+#include "BakedOpRenderer.h"
 #include "DamageAccumulator.h"
 #include "Debug.h"
-#if HWUI_NEW_OPS
-#include "BakedOpRenderer.h"
-#include "RecordedOp.h"
-#include "OpDumper.h"
-#endif
-#include "DisplayListOp.h"
 #include "LayerRenderer.h"
-#include "OpenGLRenderer.h"
+#include "OpDumper.h"
+#include "RecordedOp.h"
 #include "TreeInfo.h"
 #include "utils/MathUtils.h"
 #include "utils/TraceUtils.h"
+#include "VectorDrawable.h"
+#include "renderstate/RenderState.h"
 #include "renderthread/CanvasContext.h"
 
 #include "protos/hwui.pb.h"
@@ -41,23 +39,6 @@
 namespace android {
 namespace uirenderer {
 
-void RenderNode::debugDumpLayers(const char* prefix) {
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("TODO: dump layer");
-#else
-    if (mLayer) {
-        ALOGD("%sNode %p (%s) has layer %p (fbo = %u, wasBuildLayered = %s)",
-                prefix, this, getName(), mLayer, mLayer->getFbo(),
-                mLayer->wasBuildLayered ? "true" : "false");
-    }
-#endif
-    if (mDisplayList) {
-        for (auto&& child : mDisplayList->getChildren()) {
-            child->renderNode->debugDumpLayers(prefix);
-        }
-    }
-}
-
 RenderNode::RenderNode()
         : mDirtyPropertyFields(0)
         , mNeedsDisplayListSync(false)
@@ -70,15 +51,7 @@
 RenderNode::~RenderNode() {
     deleteDisplayList(nullptr);
     delete mStagingDisplayList;
-#if HWUI_NEW_OPS
     LOG_ALWAYS_FATAL_IF(mLayer, "layer missed detachment!");
-#else
-    if (mLayer) {
-        ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer);
-        mLayer->postDecStrong();
-        mLayer = nullptr;
-    }
-#endif
 }
 
 void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) {
@@ -96,7 +69,6 @@
  * This function is a simplified version of replay(), where we simply retrieve and log the
  * display list. This function should remain in sync with the replay() function.
  */
-#if HWUI_NEW_OPS
 void RenderNode::output(uint32_t level, const char* label) {
     ALOGD("%s (%s %p%s%s%s%s%s)",
             label,
@@ -123,26 +95,6 @@
     }
     ALOGD("%*s/RenderNode(%s %p)", level * 2, "", getName(), this);
 }
-#else
-void RenderNode::output(uint32_t level) {
-    ALOGD("%*sStart display list (%p, %s%s%s%s%s%s)", (level - 1) * 2, "", this,
-            getName(),
-            (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : ""),
-            (properties().hasShadow() ? ", casting shadow" : ""),
-            (isRenderable() ? "" : ", empty"),
-            (properties().getProjectBackwards() ? ", projected" : ""),
-            (mLayer != nullptr ? ", on HW Layer" : ""));
-    ALOGD("%*s%s %d", level * 2, "", "Save", SaveFlags::MatrixClip);
-    properties().debugOutputProperties(level);
-    if (mDisplayList) {
-        // TODO: consider printing the chunk boundaries here
-        for (auto&& op : mDisplayList->getOps()) {
-            op->output(level, DisplayListOp::kOpLogFlag_Recurse);
-        }
-    }
-    ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName());
-    }
-#endif
 
 void RenderNode::copyTo(proto::RenderNode *pnode) {
     pnode->set_id(static_cast<uint64_t>(
@@ -272,29 +224,17 @@
     }
 }
 
-static layer_t* createLayer(RenderState& renderState, uint32_t width, uint32_t height) {
-#if HWUI_NEW_OPS
+static OffscreenBuffer* createLayer(RenderState& renderState, uint32_t width, uint32_t height) {
     return renderState.layerPool().get(renderState, width, height);
-#else
-    return LayerRenderer::createRenderLayer(renderState, width, height);
-#endif
 }
 
-static void destroyLayer(layer_t* layer) {
-#if HWUI_NEW_OPS
+static void destroyLayer(OffscreenBuffer* layer) {
     RenderState& renderState = layer->renderState;
     renderState.layerPool().putOrDelete(layer);
-#else
-    LayerRenderer::destroyLayer(layer);
-#endif
 }
 
-static bool layerMatchesWidthAndHeight(layer_t* layer, int width, int height) {
-#if HWUI_NEW_OPS
+static bool layerMatchesWidthAndHeight(OffscreenBuffer* layer, int width, int height) {
     return layer->viewportWidth == (uint32_t) width && layer->viewportHeight == (uint32_t)height;
-#else
-    return layer->layer.getWidth() == width && layer->layer.getHeight() == height;
-#endif
 }
 
 void RenderNode::pushLayerUpdate(TreeInfo& info) {
@@ -312,22 +252,15 @@
     bool transformUpdateNeeded = false;
     if (!mLayer) {
         mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight());
-#if !HWUI_NEW_OPS
-        applyLayerPropertiesToLayer(info);
-#endif
         damageSelf(info);
         transformUpdateNeeded = true;
     } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) {
-#if HWUI_NEW_OPS
         // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering)
         // Or, ideally, maintain damage between frames on node/layer so ordering is always correct
         RenderState& renderState = mLayer->renderState;
         if (properties().fitsOnLayer()) {
             mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight());
         } else {
-#else
-        if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) {
-#endif
             destroyLayer(mLayer);
             mLayer = nullptr;
         }
@@ -362,19 +295,7 @@
         mLayer->setWindowTransform(windowTransform);
     }
 
-#if HWUI_NEW_OPS
     info.layerUpdateQueue->enqueueLayerWithDamage(this, dirty);
-#else
-    if (dirty.intersect(0, 0, getWidth(), getHeight())) {
-        dirty.roundOut(&dirty);
-        mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom);
-    }
-    // This is not inside the above if because we may have called
-    // updateDeferred on a previous prepare pass that didn't have a renderer
-    if (info.renderer && mLayer->deferredUpdateScheduled) {
-        info.renderer->pushLayerUpdate(mLayer);
-    }
-#endif
 
     // There might be prefetched layers that need to be accounted for.
     // That might be us, so tell CanvasContext that this layer is in the
@@ -450,9 +371,6 @@
         damageSelf(info);
         info.damageAccumulator->popTransform();
         syncProperties();
-#if !HWUI_NEW_OPS
-        applyLayerPropertiesToLayer(info);
-#endif
         // We could try to be clever and only re-damage if the matrix changed.
         // However, we don't need to worry about that. The cost of over-damaging
         // here is only going to be a single additional map rect of this node
@@ -463,17 +381,6 @@
     }
 }
 
-#if !HWUI_NEW_OPS
-void RenderNode::applyLayerPropertiesToLayer(TreeInfo& info) {
-    if (CC_LIKELY(!mLayer)) return;
-
-    const LayerProperties& props = properties().layerProperties();
-    mLayer->setAlpha(props.alpha(), props.xferMode());
-    mLayer->setColorFilter(props.colorFilter());
-    mLayer->setBlend(props.needsBlending());
-}
-#endif
-
 void RenderNode::syncDisplayList(TreeInfo* info) {
     // Make sure we inc first so that we don't fluctuate between 0 and 1,
     // which would thrash the layer cache
@@ -526,15 +433,8 @@
         }
         for (auto&& op : subtree->getChildren()) {
             RenderNode* childNode = op->renderNode;
-#if HWUI_NEW_OPS
             info.damageAccumulator->pushTransform(&op->localMatrix);
             bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip;
-#else
-            info.damageAccumulator->pushTransform(&op->localMatrix);
-            bool childFunctorsNeedLayer = functorsNeedLayer
-                    // Recorded with non-rect clip, or canvas-rotated by parent
-                    || op->mRecordedWithPotentialStencilClip;
-#endif
             childNode->prepareTreeImpl(info, childFunctorsNeedLayer);
             info.damageAccumulator->popTransform();
         }
@@ -576,84 +476,6 @@
     }
 }
 
-/*
- * For property operations, we pass a savecount of 0, since the operations aren't part of the
- * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
- * base saveCount (i.e., how RestoreToCount uses saveCount + properties().getCount())
- */
-#define PROPERTY_SAVECOUNT 0
-
-template <class T>
-void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) {
-#if DEBUG_DISPLAY_LIST
-    properties().debugOutputProperties(handler.level() + 1);
-#endif
-    if (properties().getLeft() != 0 || properties().getTop() != 0) {
-        renderer.translate(properties().getLeft(), properties().getTop());
-    }
-    if (properties().getStaticMatrix()) {
-        renderer.concatMatrix(*properties().getStaticMatrix());
-    } else if (properties().getAnimationMatrix()) {
-        renderer.concatMatrix(*properties().getAnimationMatrix());
-    }
-    if (properties().hasTransformMatrix()) {
-        if (properties().isTransformTranslateOnly()) {
-            renderer.translate(properties().getTranslationX(), properties().getTranslationY());
-        } else {
-            renderer.concatMatrix(*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())) {
-            // simply scale rendering content's alpha
-            renderer.scaleAlpha(properties().getAlpha());
-        } else {
-            // savelayer needed to create an offscreen buffer
-            Rect layerBounds(0, 0, getWidth(), getHeight());
-            if (clipFlags) {
-                properties().getClippingRectForFlags(clipFlags, &layerBounds);
-                clipFlags = 0; // all clipping done by savelayer
-            }
-            SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
-                    layerBounds.left, layerBounds.top,
-                    layerBounds.right, layerBounds.bottom,
-                    (int) (properties().getAlpha() * 255),
-                    SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer);
-            handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
-        }
-
-        if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) {
-            // pretend alpha always causes savelayer to warn about
-            // performance problem affecting old versions
-            ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(),
-                    static_cast<int>(getWidth()),
-                    static_cast<int>(getHeight()));
-        }
-    }
-    if (clipFlags) {
-        Rect clipRect;
-        properties().getClippingRectForFlags(clipFlags, &clipRect);
-        ClipRectOp* op = new (handler.allocator()) ClipRectOp(
-                clipRect.left, clipRect.top, clipRect.right, clipRect.bottom,
-                SkRegion::kIntersect_Op);
-        handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds());
-    }
-
-    // TODO: support nesting round rect clips
-    if (mProperties.getRevealClip().willClip()) {
-        Rect bounds;
-        mProperties.getRevealClip().getBounds(&bounds);
-        renderer.setClippingRoundRect(handler.allocator(), bounds, mProperties.getRevealClip().getRadius());
-    } else if (mProperties.getOutline().willClip()) {
-        renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline()));
-    }
-}
-
 /**
  * Apply property-based transformations to input matrix
  *
@@ -714,14 +536,14 @@
     // transform properties are applied correctly to top level children
     if (mDisplayList == nullptr) return;
     for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
-        renderNodeOp_t* childOp = mDisplayList->getChildren()[i];
+        RenderNodeOp* childOp = mDisplayList->getChildren()[i];
         childOp->renderNode->computeOrderingImpl(childOp, &mProjectedNodes, &mat4::identity());
     }
 }
 
 void RenderNode::computeOrderingImpl(
-        renderNodeOp_t* opState,
-        std::vector<renderNodeOp_t*>* compositedChildrenOfProjectionSurface,
+        RenderNodeOp* opState,
+        std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface,
         const mat4* transformFromProjectionSurface) {
     mProjectedNodes.clear();
     if (mDisplayList == nullptr || mDisplayList->isEmpty()) return;
@@ -745,10 +567,10 @@
         const bool isProjectionReceiver = mDisplayList->projectionReceiveIndex >= 0;
         bool haveAppliedPropertiesToProjection = false;
         for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) {
-            renderNodeOp_t* childOp = mDisplayList->getChildren()[i];
+            RenderNodeOp* childOp = mDisplayList->getChildren()[i];
             RenderNode* child = childOp->renderNode;
 
-            std::vector<renderNodeOp_t*>* projectionChildren = nullptr;
+            std::vector<RenderNodeOp*>* projectionChildren = nullptr;
             const mat4* projectionTransform = nullptr;
             if (isProjectionReceiver && !child->properties().getProjectBackwards()) {
                 // if receiving projections, collect projecting descendant
@@ -771,372 +593,5 @@
     }
 }
 
-class DeferOperationHandler {
-public:
-    DeferOperationHandler(DeferStateStruct& deferStruct, int level)
-        : mDeferStruct(deferStruct), mLevel(level) {}
-    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
-        operation->defer(mDeferStruct, saveCount, mLevel, clipToBounds);
-    }
-    inline LinearAllocator& allocator() { return *(mDeferStruct.mAllocator); }
-    inline void startMark(const char* name) {} // do nothing
-    inline void endMark() {}
-    inline int level() { return mLevel; }
-    inline int replayFlags() { return mDeferStruct.mReplayFlags; }
-    inline SkPath* allocPathForFrame() { return mDeferStruct.allocPathForFrame(); }
-
-private:
-    DeferStateStruct& mDeferStruct;
-    const int mLevel;
-};
-
-void RenderNode::defer(DeferStateStruct& deferStruct, const int level) {
-    DeferOperationHandler handler(deferStruct, level);
-    issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler);
-}
-
-class ReplayOperationHandler {
-public:
-    ReplayOperationHandler(ReplayStateStruct& replayStruct, int level)
-        : mReplayStruct(replayStruct), mLevel(level) {}
-    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
-#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        mReplayStruct.mRenderer.eventMark(operation->name());
-#endif
-        operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
-    }
-    inline LinearAllocator& allocator() { return *(mReplayStruct.mAllocator); }
-    inline void startMark(const char* name) {
-        mReplayStruct.mRenderer.startMark(name);
-    }
-    inline void endMark() {
-        mReplayStruct.mRenderer.endMark();
-    }
-    inline int level() { return mLevel; }
-    inline int replayFlags() { return mReplayStruct.mReplayFlags; }
-    inline SkPath* allocPathForFrame() { return mReplayStruct.allocPathForFrame(); }
-
-private:
-    ReplayStateStruct& mReplayStruct;
-    const int mLevel;
-};
-
-void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
-    ReplayOperationHandler handler(replayStruct, level);
-    issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler);
-}
-
-void RenderNode::buildZSortedChildList(const DisplayList::Chunk& chunk,
-        std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) {
-#if !HWUI_NEW_OPS
-    if (chunk.beginChildIndex == chunk.endChildIndex) return;
-
-    for (unsigned int i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) {
-        DrawRenderNodeOp* childOp = mDisplayList->getChildren()[i];
-        RenderNode* child = childOp->renderNode;
-        float childZ = child->properties().getZ();
-
-        if (!MathUtils::isZero(childZ) && chunk.reorderChildren) {
-            zTranslatedNodes.push_back(ZDrawRenderNodeOpPair(childZ, childOp));
-            childOp->skipInOrderDraw = true;
-        } else if (!child->properties().getProjectBackwards()) {
-            // regular, in order drawing DisplayList
-            childOp->skipInOrderDraw = false;
-        }
-    }
-
-    // Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order)
-    std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end());
-#endif
-}
-
-template <class T>
-void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler) {
-    if (properties().getAlpha() <= 0.0f
-            || properties().getOutline().getAlpha() <= 0.0f
-            || !properties().getOutline().getPath()
-            || properties().getScaleX() == 0
-            || properties().getScaleY() == 0) {
-        // no shadow to draw
-        return;
-    }
-
-    mat4 shadowMatrixXY(transformFromParent);
-    applyViewPropertyTransforms(shadowMatrixXY);
-
-    // Z matrix needs actual 3d transformation, so mapped z values will be correct
-    mat4 shadowMatrixZ(transformFromParent);
-    applyViewPropertyTransforms(shadowMatrixZ, true);
-
-    const SkPath* casterOutlinePath = properties().getOutline().getPath();
-    const SkPath* revealClipPath = properties().getRevealClip().getPath();
-    if (revealClipPath && revealClipPath->isEmpty()) return;
-
-    float casterAlpha = properties().getAlpha() * properties().getOutline().getAlpha();
-
-
-    // holds temporary SkPath to store the result of intersections
-    SkPath* frameAllocatedPath = nullptr;
-    const SkPath* outlinePath = casterOutlinePath;
-
-    // intersect the outline with the reveal clip, if present
-    if (revealClipPath) {
-        frameAllocatedPath = handler.allocPathForFrame();
-
-        Op(*outlinePath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath);
-        outlinePath = frameAllocatedPath;
-    }
-
-    // intersect the outline with the clipBounds, if present
-    if (properties().getClippingFlags() & CLIP_TO_CLIP_BOUNDS) {
-        if (!frameAllocatedPath) {
-            frameAllocatedPath = handler.allocPathForFrame();
-        }
-
-        Rect clipBounds;
-        properties().getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds);
-        SkPath clipBoundsPath;
-        clipBoundsPath.addRect(clipBounds.left, clipBounds.top,
-                clipBounds.right, clipBounds.bottom);
-
-        Op(*outlinePath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath);
-        outlinePath = frameAllocatedPath;
-    }
-
-    DisplayListOp* shadowOp  = new (handler.allocator()) DrawShadowOp(
-            shadowMatrixXY, shadowMatrixZ, casterAlpha, outlinePath);
-    handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds());
-}
-
-#define SHADOW_DELTA 0.1f
-
-template <class T>
-void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode,
-        const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
-        OpenGLRenderer& renderer, T& handler) {
-    const int size = zTranslatedNodes.size();
-    if (size == 0
-            || (mode == ChildrenSelectMode::NegativeZChildren && zTranslatedNodes[0].key > 0.0f)
-            || (mode == ChildrenSelectMode::PositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
-        // no 3d children to draw
-        return;
-    }
-
-    // Apply the base transform of the parent of the 3d children. This isolates
-    // 3d children of the current chunk from transformations made in previous chunks.
-    int rootRestoreTo = renderer.save(SaveFlags::Matrix);
-    renderer.setGlobalMatrix(initialTransform);
-
-    /**
-     * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
-     * with very similar Z heights to draw together.
-     *
-     * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
-     * underneath both, and neither's shadow is drawn on top of the other.
-     */
-    const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
-    size_t drawIndex, shadowIndex, endIndex;
-    if (mode == ChildrenSelectMode::NegativeZChildren) {
-        drawIndex = 0;
-        endIndex = nonNegativeIndex;
-        shadowIndex = endIndex; // draw no shadows
-    } else {
-        drawIndex = nonNegativeIndex;
-        endIndex = size;
-        shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
-    }
-
-    DISPLAY_LIST_LOGD("%*s%d %s 3d children:", (handler.level() + 1) * 2, "",
-            endIndex - drawIndex, mode == kNegativeZChildren ? "negative" : "positive");
-
-    float lastCasterZ = 0.0f;
-    while (shadowIndex < endIndex || drawIndex < endIndex) {
-        if (shadowIndex < endIndex) {
-            DrawRenderNodeOp* casterOp = zTranslatedNodes[shadowIndex].value;
-            RenderNode* caster = casterOp->renderNode;
-            const float casterZ = zTranslatedNodes[shadowIndex].key;
-            // attempt to render the shadow if the caster about to be drawn is its caster,
-            // OR if its caster's Z value is similar to the previous potential caster
-            if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
-                caster->issueDrawShadowOperation(casterOp->localMatrix, handler);
-
-                lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
-                shadowIndex++;
-                continue;
-            }
-        }
-
-        // only the actual child DL draw needs to be in save/restore,
-        // since it modifies the renderer's matrix
-        int restoreTo = renderer.save(SaveFlags::Matrix);
-
-        DrawRenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
-
-        renderer.concatMatrix(childOp->localMatrix);
-        childOp->skipInOrderDraw = false; // this is horrible, I'm so sorry everyone
-        handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds());
-        childOp->skipInOrderDraw = true;
-
-        renderer.restoreToCount(restoreTo);
-        drawIndex++;
-    }
-    renderer.restoreToCount(rootRestoreTo);
-}
-
-template <class T>
-void RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler) {
-    DISPLAY_LIST_LOGD("%*s%d projected children:", (handler.level() + 1) * 2, "", mProjectedNodes.size());
-    const SkPath* projectionReceiverOutline = properties().getOutline().getPath();
-    int restoreTo = renderer.getSaveCount();
-
-    LinearAllocator& alloc = handler.allocator();
-    handler(new (alloc) SaveOp(SaveFlags::MatrixClip),
-            PROPERTY_SAVECOUNT, properties().getClipToBounds());
-
-    // Transform renderer to match background we're projecting onto
-    // (by offsetting canvas by translationX/Y of background rendernode, since only those are set)
-    const DisplayListOp* op =
-#if HWUI_NEW_OPS
-            nullptr;
-    LOG_ALWAYS_FATAL("unsupported");
-#else
-            (mDisplayList->getOps()[mDisplayList->projectionReceiveIndex]);
-#endif
-    const DrawRenderNodeOp* backgroundOp = reinterpret_cast<const DrawRenderNodeOp*>(op);
-    const RenderProperties& backgroundProps = backgroundOp->renderNode->properties();
-    renderer.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY());
-
-    // If the projection receiver has an outline, we mask projected content to it
-    // (which we know, apriori, are all tessellated paths)
-    renderer.setProjectionPathMask(alloc, projectionReceiverOutline);
-
-    // draw projected nodes
-    for (size_t i = 0; i < mProjectedNodes.size(); i++) {
-        renderNodeOp_t* childOp = mProjectedNodes[i];
-
-        // matrix save, concat, and restore can be done safely without allocating operations
-        int restoreTo = renderer.save(SaveFlags::Matrix);
-        renderer.concatMatrix(childOp->transformFromCompositingAncestor);
-        childOp->skipInOrderDraw = false; // this is horrible, I'm so sorry everyone
-        handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds());
-        childOp->skipInOrderDraw = true;
-        renderer.restoreToCount(restoreTo);
-    }
-
-    handler(new (alloc) RestoreToCountOp(restoreTo),
-            PROPERTY_SAVECOUNT, properties().getClipToBounds());
-}
-
-/**
- * This function serves both defer and replay modes, and will organize the displayList's component
- * operations for a single frame:
- *
- * Every 'simple' state operation that affects just the matrix and alpha (or other factors of
- * DeferredDisplayState) may be issued directly to the renderer, but complex operations (with custom
- * defer logic) and operations in displayListOps are issued through the 'handler' which handles the
- * defer vs replay logic, per operation
- */
-template <class T>
-void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) {
-    if (mDisplayList->isEmpty()) {
-        DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", handler.level() * 2, "",
-                this, getName());
-        return;
-    }
-
-#if HWUI_NEW_OPS
-    const bool drawLayer = false;
-#else
-    const bool drawLayer = (mLayer && (&renderer != mLayer->renderer.get()));
-#endif
-    // If we are updating the contents of mLayer, we don't want to apply any of
-    // the RenderNode's properties to this issueOperations pass. Those will all
-    // be applied when the layer is drawn, aka when this is true.
-    const bool useViewProperties = (!mLayer || drawLayer);
-    if (useViewProperties) {
-        const Outline& outline = properties().getOutline();
-        if (properties().getAlpha() <= 0
-                || (outline.getShouldClip() && outline.isEmpty())
-                || properties().getScaleX() == 0
-                || properties().getScaleY() == 0) {
-            DISPLAY_LIST_LOGD("%*sRejected display list (%p, %s)", handler.level() * 2, "",
-                    this, getName());
-            return;
-        }
-    }
-
-    handler.startMark(getName());
-
-#if DEBUG_DISPLAY_LIST
-    const Rect& clipRect = renderer.getLocalClipBounds();
-    DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), localClipBounds: %.0f, %.0f, %.0f, %.0f",
-            handler.level() * 2, "", this, getName(),
-            clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
-#endif
-
-    LinearAllocator& alloc = handler.allocator();
-    int restoreTo = renderer.getSaveCount();
-    handler(new (alloc) SaveOp(SaveFlags::MatrixClip),
-            PROPERTY_SAVECOUNT, properties().getClipToBounds());
-
-    DISPLAY_LIST_LOGD("%*sSave %d %d", (handler.level() + 1) * 2, "",
-            SaveFlags::MatrixClip, restoreTo);
-
-    if (useViewProperties) {
-        setViewProperties<T>(renderer, handler);
-    }
-
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("legacy op traversal not supported");
-#else
-    bool quickRejected = properties().getClipToBounds()
-            && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight());
-    if (!quickRejected) {
-        Matrix4 initialTransform(*(renderer.currentTransform()));
-        renderer.setBaseTransform(initialTransform);
-
-        if (drawLayer) {
-            handler(new (alloc) DrawLayerOp(mLayer),
-                    renderer.getSaveCount() - 1, properties().getClipToBounds());
-        } else {
-            const int saveCountOffset = renderer.getSaveCount() - 1;
-            const int projectionReceiveIndex = mDisplayList->projectionReceiveIndex;
-            for (size_t chunkIndex = 0; chunkIndex < mDisplayList->getChunks().size(); chunkIndex++) {
-                const DisplayList::Chunk& chunk = mDisplayList->getChunks()[chunkIndex];
-
-                std::vector<ZDrawRenderNodeOpPair> zTranslatedNodes;
-                buildZSortedChildList(chunk, zTranslatedNodes);
-
-                issueOperationsOf3dChildren(ChildrenSelectMode::NegativeZChildren,
-                        initialTransform, zTranslatedNodes, renderer, handler);
-
-                for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) {
-                    DisplayListOp *op = mDisplayList->getOps()[opIndex];
-#if DEBUG_DISPLAY_LIST
-                    op->output(handler.level() + 1);
-#endif
-                    handler(op, saveCountOffset, properties().getClipToBounds());
-
-                    if (CC_UNLIKELY(!mProjectedNodes.empty() && projectionReceiveIndex >= 0 &&
-                        opIndex == static_cast<size_t>(projectionReceiveIndex))) {
-                        issueOperationsOfProjectedChildren(renderer, handler);
-                    }
-                }
-
-                issueOperationsOf3dChildren(ChildrenSelectMode::PositiveZChildren,
-                        initialTransform, zTranslatedNodes, renderer, handler);
-            }
-        }
-    }
-#endif
-
-    DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (handler.level() + 1) * 2, "", restoreTo);
-    handler(new (alloc) RestoreToCountOp(restoreTo),
-            PROPERTY_SAVECOUNT, properties().getClipToBounds());
-
-    DISPLAY_LIST_LOGD("%*sDone (%p, %s)", handler.level() * 2, "", this, getName());
-    handler.endMark();
-}
-
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index f9735a2..ee045aa 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef RENDERNODE_H
-#define RENDERNODE_H
+
+#pragma once
 
 #include <SkCamera.h>
 #include <SkMatrix.h>
@@ -44,29 +44,13 @@
 namespace uirenderer {
 
 class CanvasState;
-class DisplayListCanvas;
 class DisplayListOp;
-class OpenGLRenderer;
-class Rect;
-class SkiaShader;
-
-#if HWUI_NEW_OPS
 class FrameBuilder;
 class OffscreenBuffer;
+class Rect;
+class SkiaShader;
 struct RenderNodeOp;
-typedef OffscreenBuffer layer_t;
-typedef RenderNodeOp renderNodeOp_t;
-#else
-class Layer;
-typedef Layer layer_t;
-typedef DrawRenderNodeOp renderNodeOp_t;
-#endif
 
-class ClipRectOp;
-class DrawRenderNodeOp;
-class SaveLayerOp;
-class SaveOp;
-class RestoreToCountOp;
 class TreeInfo;
 class TreeObserver;
 
@@ -78,9 +62,8 @@
  * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
  *
  * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording
- * functionality is split between DisplayListCanvas (which manages the recording), DisplayList
- * (which holds the actual data), and DisplayList (which holds properties and performs playback onto
- * a renderer).
+ * functionality is split between RecordingCanvas (which manages the recording), DisplayList
+ * (which holds the actual data), and RenderNode (which holds properties used for render playback).
  *
  * Note that DisplayList is swapped out from beneath an individual RenderNode when a view's
  * recorded stream of canvas operations is refreshed. The RenderNode (and its properties) stay
@@ -115,20 +98,11 @@
         kReplayFlag_ClipChildren = 0x1
     };
 
-    void debugDumpLayers(const char* prefix);
-
     ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
 
     void computeOrdering();
 
-    void defer(DeferStateStruct& deferStruct, const int level);
-    void replay(ReplayStateStruct& replayStruct, const int level);
-
-#if HWUI_NEW_OPS
     ANDROID_API void output(uint32_t level = 0, const char* label = "Root");
-#else
-    ANDROID_API void output(uint32_t level = 1);
-#endif
     ANDROID_API int getDebugSize();
     void copyTo(proto::RenderNode* node);
 
@@ -223,10 +197,8 @@
     const DisplayList* getDisplayList() const {
         return mDisplayList;
     }
-#if HWUI_NEW_OPS
     OffscreenBuffer* getLayer() const { return mLayer; }
     OffscreenBuffer** getLayerHandle() { return &mLayer; } // ugh...
-#endif
 
     // Note: The position callbacks are relying on the listener using
     // the frameNumber to appropriately batch/synchronize these transactions.
@@ -257,63 +229,10 @@
     }
 
 private:
-    typedef key_value_pair_t<float, DrawRenderNodeOp*> ZDrawRenderNodeOpPair;
-
-    static size_t findNonNegativeIndex(const std::vector<ZDrawRenderNodeOpPair>& nodes) {
-        for (size_t i = 0; i < nodes.size(); i++) {
-            if (nodes[i].key >= 0.0f) return i;
-        }
-        return nodes.size();
-    }
-
-    enum class ChildrenSelectMode {
-        NegativeZChildren,
-        PositiveZChildren
-    };
-
-    void computeOrderingImpl(renderNodeOp_t* opState,
-            std::vector<renderNodeOp_t*>* compositedChildrenOfProjectionSurface,
+    void computeOrderingImpl(RenderNodeOp* opState,
+            std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface,
             const mat4* transformFromProjectionSurface);
 
-    template <class T>
-    inline void setViewProperties(OpenGLRenderer& renderer, T& handler);
-
-    void buildZSortedChildList(const DisplayList::Chunk& chunk,
-            std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes);
-
-    template<class T>
-    inline void issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler);
-
-    template <class T>
-    inline void issueOperationsOf3dChildren(ChildrenSelectMode mode,
-            const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes,
-            OpenGLRenderer& renderer, T& handler);
-
-    template <class T>
-    inline void issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler);
-
-    /**
-     * Issue the RenderNode's operations into a handler, recursing for subtrees through
-     * DrawRenderNodeOp's defer() or replay() methods
-     */
-    template <class T>
-    inline void issueOperations(OpenGLRenderer& renderer, T& handler);
-
-    class TextContainer {
-    public:
-        size_t length() const {
-            return mByteLength;
-        }
-
-        const char* text() const {
-            return (const char*) mText;
-        }
-
-        size_t mByteLength;
-        const char* mText;
-    };
-
-
     void syncProperties();
     void syncDisplayList(TreeInfo* info);
 
@@ -321,9 +240,6 @@
     void pushStagingPropertiesChanges(TreeInfo& info);
     void pushStagingDisplayListChanges(TreeInfo& info);
     void prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree);
-#if !HWUI_NEW_OPS
-    void applyLayerPropertiesToLayer(TreeInfo& info);
-#endif
     void prepareLayer(TreeInfo& info, uint32_t dirtyMask);
     void pushLayerUpdate(TreeInfo& info);
     void deleteDisplayList(TreeObserver* observer, TreeInfo* info = nullptr);
@@ -349,14 +265,14 @@
 
     // Owned by RT. Lifecycle is managed by prepareTree(), with the exception
     // being in ~RenderNode() which may happen on any thread.
-    layer_t* mLayer = nullptr;
+    OffscreenBuffer* mLayer = nullptr;
 
     /**
      * Draw time state - these properties are only set and used during rendering
      */
 
     // for projection surfaces, contains a list of all children items
-    std::vector<renderNodeOp_t*> mProjectedNodes;
+    std::vector<RenderNodeOp*> mProjectedNodes;
 
     // How many references our parent(s) have to us. Typically this should alternate
     // between 2 and 1 (when a staging push happens we inc first then dec)
@@ -371,5 +287,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* RENDERNODE_H */
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
index 5ebf545..7e3cad4 100644
--- a/libs/hwui/RenderProperties.cpp
+++ b/libs/hwui/RenderProperties.cpp
@@ -24,7 +24,6 @@
 #include <SkPathOps.h>
 
 #include "Matrix.h"
-#include "OpenGLRenderer.h"
 #include "hwui/Canvas.h"
 #include "utils/MathUtils.h"
 
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index c1221f7..2a2e4c7 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef RENDERNODEPROPERTIES_H
-#define RENDERNODEPROPERTIES_H
+
+#pragma once
 
 #include "Caches.h"
 #include "DeviceInfo.h"
@@ -22,6 +22,7 @@
 #include "RevealClip.h"
 #include "Outline.h"
 #include "utils/MathUtils.h"
+#include "utils/PaintUtils.h"
 
 #include <SkCamera.h>
 #include <SkMatrix.h>
@@ -680,5 +681,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* RENDERNODEPROPERTIES_H */
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index 2c9c9d9..21c26f7 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -30,14 +30,11 @@
         , previous(nullptr)
         , layer(nullptr)
         , fbo(0)
-        , invisible(false)
-        , empty(false)
         , alpha(1.0f)
         , roundRectClipState(nullptr)
         , projectionPathMask(nullptr)
         , mClipArea(&mClipAreaRoot) {
     transform = &mTransformRoot;
-    region = nullptr;
 }
 
 /**
@@ -49,8 +46,6 @@
         , previous(s)
         , layer(s->layer)
         , fbo(s->fbo)
-        , invisible(s->invisible)
-        , empty(false)
         , alpha(s->alpha)
         , roundRectClipState(s->roundRectClipState)
         , projectionPathMask(s->projectionPathMask)
@@ -70,13 +65,6 @@
     } else {
         mClipArea = s->mClipArea;
     }
-
-    if (s->flags & Snapshot::kFlagFboTarget) {
-        flags |= Snapshot::kFlagFboTarget;
-        region = s->region;
-    } else {
-        region = nullptr;
-    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -126,58 +114,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Transforms
-///////////////////////////////////////////////////////////////////////////////
-
-void Snapshot::resetTransform(float x, float y, float z) {
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("not supported - light center managed differently");
-#else
-    // before resetting, map current light pos with inverse of current transform
-    Vector3 center = mRelativeLightCenter;
-    mat4 inverse;
-    inverse.loadInverse(*transform);
-    inverse.mapPoint3d(center);
-    mRelativeLightCenter = center;
-
-    transform = &mTransformRoot;
-    transform->loadTranslate(x, y, z);
-#endif
-}
-
-void Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const {
-#if HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL("not supported - not needed by new ops");
-#else
-    // build (reverse ordered) list of the stack of snapshots, terminated with a NULL
-    Vector<const Snapshot*> snapshotList;
-    snapshotList.push(nullptr);
-    const Snapshot* current = this;
-    do {
-        snapshotList.push(current);
-        current = current->previous;
-    } while (current);
-
-    // traverse the list, adding in each transform that contributes to the total transform
-    outTransform->loadIdentity();
-    for (size_t i = snapshotList.size() - 1; i > 0; i--) {
-        // iterate down the stack
-        const Snapshot* current = snapshotList[i];
-        const Snapshot* next = snapshotList[i - 1];
-        if (current->flags & kFlagIsFboLayer) {
-            // if we've hit a layer, translate by the layer's draw offset
-            outTransform->translate(current->layer->layer.left, current->layer->layer.top);
-        }
-        if (!next || (next->flags & kFlagIsFboLayer)) {
-            // if this snapshot is last, or if this snapshot is last before an
-            // FBO layer (which reset the transform), apply it
-            outTransform->multiply(*(current->transform));
-        }
-    }
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // Clipping round rect
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -226,20 +162,8 @@
     roundRectClipState = state;
 }
 
-void Snapshot::setProjectionPathMask(LinearAllocator& allocator, const SkPath* path) {
-#if HWUI_NEW_OPS
-    // TODO: remove allocator param for HWUI_NEW_OPS
+void Snapshot::setProjectionPathMask(const SkPath* path) {
     projectionPathMask = path;
-#else
-    if (path) {
-        ProjectionPathMask* mask = new (allocator) ProjectionPathMask;
-        mask->projectionMask = path;
-        buildScreenSpaceTransform(&(mask->projectionMaskTransform));
-        projectionPathMask = mask;
-    } else {
-        projectionPathMask = nullptr;
-    }
-#endif
 }
 
 static Snapshot* getClipRoot(Snapshot* target) {
@@ -273,13 +197,9 @@
 // Queries
 ///////////////////////////////////////////////////////////////////////////////
 
-bool Snapshot::isIgnored() const {
-    return invisible || empty;
-}
-
 void Snapshot::dump() const {
-    ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d",
-            this, flags, previous, getViewportHeight(), isIgnored(), !mClipArea->isSimple());
+    ALOGD("Snapshot %p, flags %x, prev %p, height %d, hasComplexClip %d",
+            this, flags, previous, getViewportHeight(), !mClipArea->isSimple());
     const Rect& clipRect(mClipArea->getClipRect());
     ALOGD("  ClipRect %.1f %.1f %.1f %.1f, clip simple %d",
             clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, mClipArea->isSimple());
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index d8f926e..4ab5830 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_SNAPSHOT_H
-#define ANDROID_HWUI_SNAPSHOT_H
+#pragma once
 
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
@@ -63,18 +62,6 @@
     float radius;
 };
 
-// TODO: remove for HWUI_NEW_OPS
-class ProjectionPathMask {
-public:
-    static void* operator new(size_t size) = delete;
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc<ProjectionPathMask>(size);
-    }
-
-    const SkPath* projectionMask;
-    Matrix4 projectionMaskTransform;
-};
-
 /**
  * A snapshot holds information about the current state of the rendering
  * surface. A snapshot is usually created whenever the user calls save()
@@ -113,11 +100,6 @@
          * restored when this snapshot is restored.
          */
         kFlagIsFboLayer = 0x4,
-        /**
-         * Indicates that this snapshot or an ancestor snapshot is
-         * an FBO layer.
-         */
-        kFlagFboTarget = 0x8, // TODO: remove for HWUI_NEW_OPS
     };
 
     /**
@@ -179,11 +161,6 @@
      */
     void resetClip(float left, float top, float right, float bottom);
 
-    /**
-     * Resets the current transform to a pure 3D translation.
-     */
-    void resetTransform(float x, float y, float z);
-
     void initializeViewport(int width, int height) {
         mViewportData.initialize(width, height);
         mClipAreaRoot.setViewportDimensions(width, height);
@@ -207,13 +184,7 @@
     /**
      * Sets (and replaces) the current projection mask
      */
-    void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);
-
-    /**
-     * Indicates whether this snapshot should be ignored. A snapshot
-     * is typically ignored if its layer is invisible or empty.
-     */
-    bool isIgnored() const;
+    void setProjectionPathMask(const SkPath* path);
 
     /**
      * Indicates whether the current transform has perspective components.
@@ -221,13 +192,6 @@
     bool hasPerspectiveTransform() const;
 
     /**
-     * Fills outTransform with the current, total transform to screen space,
-     * across layer boundaries.
-     */
-    // TODO: remove for HWUI_NEW_OPS
-    void buildScreenSpaceTransform(Matrix4* outTransform) const;
-
-    /**
      * Dirty flags.
      */
     int flags;
@@ -251,19 +215,6 @@
     GLuint fbo;
 
     /**
-     * Indicates that this snapshot is invisible and nothing should be drawn
-     * inside it. This flag is set only when the layer clips drawing to its
-     * bounds and is passed to subsequent snapshots.
-     */
-    bool invisible;
-
-    /**
-     * If set to true, the layer will not be composited. This is similar to
-     * invisible but this flag is not passed to subsequent snapshots.
-     */
-    bool empty;
-
-    /**
      * Local transformation. Holds the current translation, scale and
      * rotation values.
      *
@@ -273,14 +224,6 @@
     mat4* transform;
 
     /**
-     * The ancestor layer's dirty region.
-     *
-     * This is a reference to a region owned by a layer. This pointer must
-     * not be freed.
-     */
-    Region* region;
-
-    /**
      * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
      * has translucent rendering in a non-overlapping View. This value will be used by
      * the renderer to set the alpha in the current color being used for ensuing drawing
@@ -302,11 +245,7 @@
     /**
      * Current projection masking path - used exclusively to mask projected, tessellated circles.
      */
-#if HWUI_NEW_OPS
     const SkPath* projectionPathMask;
-#else
-    const ProjectionPathMask* projectionPathMask;
-#endif
 
     void dump() const;
 
@@ -345,5 +284,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_SNAPSHOT_H
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index d9e8116..91e7ac3 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -18,7 +18,6 @@
 #include <utils/Trace.h>
 
 #include "Caches.h"
-#include "OpenGLRenderer.h"
 #include "PathTessellator.h"
 #include "ShadowTessellator.h"
 #include "TessellationCache.h"
@@ -369,21 +368,6 @@
     mShadowCache.put(key, task.get());
 }
 
-void TessellationCache::getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
-        bool opaque, const SkPath* casterPerimeter,
-        const Matrix4* transformXY, const Matrix4* transformZ,
-        const Vector3& lightCenter, float lightRadius, vertexBuffer_pair_t& outBuffers) {
-    ShadowDescription key(casterPerimeter, drawTransform);
-    ShadowTask* task = static_cast<ShadowTask*>(mShadowCache.get(key));
-    if (!task) {
-        precacheShadows(drawTransform, localClip, opaque, casterPerimeter,
-                transformXY, transformZ, lightCenter, lightRadius);
-        task = static_cast<ShadowTask*>(mShadowCache.get(key));
-    }
-    LOG_ALWAYS_FATAL_IF(task == nullptr, "shadow not precached");
-    outBuffers = task->getResult();
-}
-
 sp<TessellationCache::ShadowTask> TessellationCache::getShadowTask(
         const Matrix4* drawTransform, const Rect& localClip,
         bool opaque, const SkPath* casterPerimeter,
diff --git a/libs/hwui/TessellationCache.h b/libs/hwui/TessellationCache.h
index 6141b4e..ccad1b7 100644
--- a/libs/hwui/TessellationCache.h
+++ b/libs/hwui/TessellationCache.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HWUI_TESSELLATION_CACHE_H
-#define ANDROID_HWUI_TESSELLATION_CACHE_H
+#pragma once
 
 #include "Debug.h"
 #include "Matrix.h"
@@ -161,17 +160,6 @@
     const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint,
             float width, float height, float rx, float ry);
 
-    // TODO: delete these when switching to HWUI_NEW_OPS
-    void precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
-            bool opaque, const SkPath* casterPerimeter,
-            const Matrix4* transformXY, const Matrix4* transformZ,
-            const Vector3& lightCenter, float lightRadius);
-    void getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
-            bool opaque, const SkPath* casterPerimeter,
-            const Matrix4* transformXY, const Matrix4* transformZ,
-            const Vector3& lightCenter, float lightRadius,
-            vertexBuffer_pair_t& outBuffers);
-
     sp<ShadowTask> getShadowTask(const Matrix4* drawTransform, const Rect& localClip,
             bool opaque, const SkPath* casterPerimeter,
             const Matrix4* transformXY, const Matrix4* transformZ,
@@ -184,6 +172,11 @@
 
     typedef VertexBuffer* (*Tessellator)(const Description&);
 
+    void precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
+                bool opaque, const SkPath* casterPerimeter,
+                const Matrix4* transformXY, const Matrix4* transformZ,
+                const Vector3& lightCenter, float lightRadius);
+
     Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint,
             float width, float height);
     Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint,
@@ -232,5 +225,3 @@
 
 }; // namespace uirenderer
 }; // namespace android
-
-#endif // ANDROID_HWUI_PATH_CACHE_H
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index ac2bdcc..2087fca 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef TREEINFO_H
-#define TREEINFO_H
+
+#pragma once
 
 #include "utils/Macros.h"
 
@@ -31,7 +31,6 @@
 
 class DamageAccumulator;
 class LayerUpdateQueue;
-class OpenGLRenderer;
 class RenderNode;
 class RenderState;
 
@@ -89,13 +88,7 @@
     // Must not be null during actual usage
     DamageAccumulator* damageAccumulator = nullptr;
 
-#if HWUI_NEW_OPS
     LayerUpdateQueue* layerUpdateQueue = nullptr;
-#else
-    // The renderer that will be drawing the next frame. Use this to push any
-    // layer updates or similar. May be NULL.
-    OpenGLRenderer* renderer = nullptr;
-#endif
     ErrorHandler* errorHandler = nullptr;
 
     // Optional, may be nullptr. Used to allow things to observe interesting
@@ -128,5 +121,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* TREEINFO_H */
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index dd0d72b..461363f 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -16,7 +16,6 @@
 
 #include "Canvas.h"
 
-#include "DisplayListCanvas.h"
 #include "RecordingCanvas.h"
 #include "MinikinUtils.h"
 #include "Paint.h"
@@ -27,11 +26,7 @@
 namespace android {
 
 Canvas* Canvas::create_recording_canvas(int width, int height) {
-#if HWUI_NEW_OPS
     return new uirenderer::RecordingCanvas(width, height);
-#else
-    return new uirenderer::DisplayListCanvas(width, height);
-#endif
 }
 
 void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) {
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 7b3199c..0b42099 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_GRAPHICS_CANVAS_H
-#define ANDROID_GRAPHICS_CANVAS_H
+#pragma once
 
 #include <cutils/compiler.h>
 #include <utils/Functor.h>
@@ -253,4 +252,3 @@
 };
 
 }; // namespace android
-#endif // ANDROID_GRAPHICS_CANVAS_H
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 5e60064..ee4619d 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -60,38 +60,6 @@
 }
 
 void RenderState::onGLContextDestroyed() {
-/*
-    size_t size = mActiveLayers.size();
-    if (CC_UNLIKELY(size != 0)) {
-        ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
-                mRegisteredContexts.size(), size, mActiveLayers.empty());
-        mCaches->dumpMemoryUsage();
-        for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin();
-                cit != mRegisteredContexts.end(); cit++) {
-            renderthread::CanvasContext* context = *cit;
-            ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get());
-            ALOGE("  Prefeteched layers: %zu", context->mPrefetechedLayers.size());
-            for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin();
-                    pit != context->mPrefetechedLayers.end(); pit++) {
-                (*pit)->debugDumpLayers("    ");
-            }
-            context->mRootRenderNode->debugDumpLayers("  ");
-        }
-
-
-        if (mActiveLayers.begin() == mActiveLayers.end()) {
-            ALOGE("set has become empty. wat.");
-        }
-        for (std::set<const Layer*>::iterator lit = mActiveLayers.begin();
-             lit != mActiveLayers.end(); lit++) {
-            const Layer* layer = *(lit);
-            ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d",
-                    layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered);
-        }
-        LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
-    }
-*/
-
     mLayerPool.clear();
 
     // TODO: reset all cached state in state objects
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 9aa0dea..d36ebc7 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -21,9 +21,8 @@
 #include "Caches.h"
 #include "DeferredLayerUpdater.h"
 #include "EglManager.h"
-#include "LayerUpdateQueue.h"
 #include "LayerRenderer.h"
-#include "OpenGLRenderer.h"
+#include "LayerUpdateQueue.h"
 #include "Properties.h"
 #include "Readback.h"
 #include "RenderThread.h"
@@ -109,12 +108,6 @@
     freePrefetchedLayers(observer);
     destroyHardwareResources(observer);
     mAnimationContext->destroy();
-#if !HWUI_NEW_OPS
-    if (mCanvas) {
-        delete mCanvas;
-        mCanvas = nullptr;
-    }
-#endif
 }
 
 void CanvasContext::setSurface(Surface* surface) {
@@ -149,11 +142,6 @@
 
 void CanvasContext::initialize(Surface* surface) {
     setSurface(surface);
-#if !HWUI_NEW_OPS
-    if (mCanvas) return;
-    mCanvas = new OpenGLRenderer(mRenderThread.renderState());
-    mCanvas->initProperties();
-#endif
 }
 
 void CanvasContext::updateSurface(Surface* surface) {
@@ -180,23 +168,13 @@
 
 void CanvasContext::setup(float lightRadius,
         uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
-#if HWUI_NEW_OPS
     mLightGeometry.radius = lightRadius;
     mLightInfo.ambientShadowAlpha = ambientShadowAlpha;
     mLightInfo.spotShadowAlpha = spotShadowAlpha;
-#else
-    if (!mCanvas) return;
-    mCanvas->initLight(lightRadius, ambientShadowAlpha, spotShadowAlpha);
-#endif
 }
 
 void CanvasContext::setLightCenter(const Vector3& lightCenter) {
-#if HWUI_NEW_OPS
     mLightGeometry.center = lightCenter;
-#else
-    if (!mCanvas) return;
-    mCanvas->setLightCenter(lightCenter);
-#endif
 }
 
 void CanvasContext::setOpaque(bool opaque) {
@@ -273,11 +251,7 @@
     mCurrentFrameInfo->markSyncStart();
 
     info.damageAccumulator = &mDamageAccumulator;
-#if HWUI_NEW_OPS
     info.layerUpdateQueue = &mLayerUpdateQueue;
-#else
-    info.renderer = mCanvas;
-#endif
 
     mAnimationContext->startFrame(info.mode);
     for (const sp<RenderNode>& node : mRenderNodes) {
@@ -354,10 +328,8 @@
 }
 
 void CanvasContext::draw() {
-#if !HWUI_NEW_OPS
-    LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
-            "drawRenderNode called on a context with no canvas or surface!");
-#endif
+    LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
+            "drawRenderNode called on a context with no surface!");
 
     SkRect dirty;
     mDamageAccumulator.finish(&dirty);
@@ -420,7 +392,6 @@
 
     mEglManager.damageFrame(frame, dirty);
 
-#if HWUI_NEW_OPS
     auto& caches = Caches::getInstance();
     FrameBuilder frameBuilder(dirty, frame.width(), frame.height(), mLightGeometry, caches);
 
@@ -448,122 +419,6 @@
     }
 #endif
 
-#else
-    mCanvas->prepareDirty(frame.width(), frame.height(),
-            dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom, mOpaque);
-
-    Rect outBounds;
-    // It there are multiple render nodes, they are laid out as follows:
-    // #0 - backdrop (content + caption)
-    // #1 - content (positioned at (0,0) and clipped to - its bounds mContentDrawBounds)
-    // #2 - additional overlay nodes
-    // Usually the backdrop cannot be seen since it will be entirely covered by the content. While
-    // resizing however it might become partially visible. The following render loop will crop the
-    // backdrop against the content and draw the remaining part of it. It will then draw the content
-    // cropped to the backdrop (since that indicates a shrinking of the window).
-    //
-    // Additional nodes will be drawn on top with no particular clipping semantics.
-
-    // The bounds of the backdrop against which the content should be clipped.
-    Rect backdropBounds = mContentDrawBounds;
-    // Usually the contents bounds should be mContentDrawBounds - however - we will
-    // move it towards the fixed edge to give it a more stable appearance (for the moment).
-    Rect contentBounds;
-    // If there is no content bounds we ignore the layering as stated above and start with 2.
-    int layer = (mContentDrawBounds.isEmpty() || mRenderNodes.size() == 1) ? 2 : 0;
-    // Draw all render nodes. Note that
-    for (const sp<RenderNode>& node : mRenderNodes) {
-        if (layer == 0) { // Backdrop.
-            // Draw the backdrop clipped to the inverse content bounds, but assume that the content
-            // was moved to the upper left corner.
-            const RenderProperties& properties = node->properties();
-            Rect targetBounds(properties.getLeft(), properties.getTop(),
-                              properties.getRight(), properties.getBottom());
-            // Move the content bounds towards the fixed corner of the backdrop.
-            const int x = targetBounds.left;
-            const int y = targetBounds.top;
-            contentBounds.set(x, y, x + mContentDrawBounds.getWidth(),
-                                    y + mContentDrawBounds.getHeight());
-            // Remember the intersection of the target bounds and the intersection bounds against
-            // which we have to crop the content.
-            backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight());
-            backdropBounds.doIntersect(targetBounds);
-            // Check if we have to draw something on the left side ...
-            if (targetBounds.left < contentBounds.left) {
-                mCanvas->save(SaveFlags::Clip);
-                if (mCanvas->clipRect(targetBounds.left, targetBounds.top,
-                                      contentBounds.left, targetBounds.bottom,
-                                      SkRegion::kIntersect_Op)) {
-                    mCanvas->drawRenderNode(node.get(), outBounds);
-                }
-                // Reduce the target area by the area we have just painted.
-                targetBounds.left = std::min(contentBounds.left, targetBounds.right);
-                mCanvas->restore();
-            }
-            // ... or on the right side ...
-            if (targetBounds.right > contentBounds.right &&
-                !targetBounds.isEmpty()) {
-                mCanvas->save(SaveFlags::Clip);
-                if (mCanvas->clipRect(contentBounds.right, targetBounds.top,
-                                      targetBounds.right, targetBounds.bottom,
-                                      SkRegion::kIntersect_Op)) {
-                    mCanvas->drawRenderNode(node.get(), outBounds);
-                }
-                // Reduce the target area by the area we have just painted.
-                targetBounds.right = std::max(targetBounds.left, contentBounds.right);
-                mCanvas->restore();
-            }
-            // ... or at the top ...
-            if (targetBounds.top < contentBounds.top &&
-                !targetBounds.isEmpty()) {
-                mCanvas->save(SaveFlags::Clip);
-                if (mCanvas->clipRect(targetBounds.left, targetBounds.top, targetBounds.right,
-                                      contentBounds.top,
-                                      SkRegion::kIntersect_Op)) {
-                    mCanvas->drawRenderNode(node.get(), outBounds);
-                }
-                // Reduce the target area by the area we have just painted.
-                targetBounds.top = std::min(contentBounds.top, targetBounds.bottom);
-                mCanvas->restore();
-            }
-            // ... or at the bottom.
-            if (targetBounds.bottom > contentBounds.bottom &&
-                !targetBounds.isEmpty()) {
-                mCanvas->save(SaveFlags::Clip);
-                if (mCanvas->clipRect(targetBounds.left, contentBounds.bottom, targetBounds.right,
-                                      targetBounds.bottom, SkRegion::kIntersect_Op)) {
-                    mCanvas->drawRenderNode(node.get(), outBounds);
-                }
-                mCanvas->restore();
-            }
-        } else if (layer == 1) { // Content
-            // It gets cropped against the bounds of the backdrop to stay inside.
-            mCanvas->save(SaveFlags::MatrixClip);
-
-            // We shift and clip the content to match its final location in the window.
-            const float left = mContentDrawBounds.left;
-            const float top = mContentDrawBounds.top;
-            const float dx = backdropBounds.left - left;
-            const float dy = backdropBounds.top - top;
-            const float width = backdropBounds.getWidth();
-            const float height = backdropBounds.getHeight();
-
-            mCanvas->translate(dx, dy);
-            if (mCanvas->clipRect(left, top, left + width, top + height, SkRegion::kIntersect_Op)) {
-                mCanvas->drawRenderNode(node.get(), outBounds);
-            }
-            mCanvas->restore();
-        } else { // draw the rest on top at will!
-            mCanvas->drawRenderNode(node.get(), outBounds);
-        }
-        layer++;
-    }
-
-    profiler().draw(mCanvas);
-
-    bool drew = mCanvas->finish();
-#endif
-
     waitOnFences();
 
     GL_CHECKPOINT(LOW);
@@ -614,11 +469,7 @@
 
 // Called by choreographer to do an RT-driven animation
 void CanvasContext::doFrame() {
-#if HWUI_NEW_OPS
     if (CC_UNLIKELY(mEglSurface == EGL_NO_SURFACE)) return;
-#else
-    if (CC_UNLIKELY(!mCanvas || mEglSurface == EGL_NO_SURFACE)) return;
-#endif
     prepareAndDraw(nullptr);
 }
 
@@ -669,9 +520,6 @@
 void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
     ATRACE_CALL();
     if (!mEglManager.hasEglContext()) return;
-#if !HWUI_NEW_OPS
-    if (!mCanvas) return;
-#endif
 
     // buildLayer() will leave the tree in an unknown state, so we must stop drawing
     stopDrawing();
@@ -679,11 +527,7 @@
     TreeInfo info(TreeInfo::MODE_FULL, *this);
     info.damageAccumulator = &mDamageAccumulator;
     info.observer = observer;
-#if HWUI_NEW_OPS
     info.layerUpdateQueue = &mLayerUpdateQueue;
-#else
-    info.renderer = mCanvas;
-#endif
     info.runAnimations = false;
     node->prepareTree(info);
     SkRect ignore;
@@ -692,7 +536,6 @@
     // purposes when the frame is actually drawn
     node->setPropertyFieldsDirty(RenderNode::GENERIC);
 
-#if HWUI_NEW_OPS
     static const std::vector< sp<RenderNode> > emptyNodeList;
     auto& caches = Caches::getInstance();
     FrameBuilder frameBuilder(mLayerUpdateQueue, mLightGeometry, caches);
@@ -701,10 +544,6 @@
             mOpaque, mLightInfo);
     LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
     frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
-#else
-    mCanvas->markLayersAsBuildLayers();
-    mCanvas->flushLayerUpdates();
-#endif
 
     node->incStrong(nullptr);
     mPrefetchedLayers.insert(node);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index a5f8562..72f1268 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-#ifndef CANVASCONTEXT_H_
-#define CANVASCONTEXT_H_
+#pragma once
 
+#include "BakedOpDispatcher.h"
+#include "BakedOpRenderer.h"
 #include "DamageAccumulator.h"
+#include "FrameBuilder.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
 #include "FrameMetricsReporter.h"
@@ -30,12 +32,6 @@
 #include "renderthread/RenderTask.h"
 #include "renderthread/RenderThread.h"
 
-#if HWUI_NEW_OPS
-#include "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "FrameBuilder.h"
-#endif
-
 #include <cutils/compiler.h>
 #include <EGL/egl.h>
 #include <SkBitmap.h>
@@ -53,9 +49,8 @@
 
 class AnimationContext;
 class DeferredLayerUpdater;
-class OpenGLRenderer;
-class Rect;
 class Layer;
+class Rect;
 class RenderState;
 
 namespace renderthread {
@@ -211,12 +206,8 @@
     int64_t mFrameNumber = -1;
 
     bool mOpaque;
-#if HWUI_NEW_OPS
     BakedOpRenderer::LightInfo mLightInfo;
     FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
-#else
-    OpenGLRenderer* mCanvas = nullptr;
-#endif
 
     bool mHaveNewSurface = false;
     DamageAccumulator mDamageAccumulator;
@@ -252,4 +243,3 @@
 } /* namespace renderthread */
 } /* namespace uirenderer */
 } /* namespace android */
-#endif /* CANVASCONTEXT_H_ */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index aea7edb..d860acd 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -466,11 +466,7 @@
     } else {
         fprintf(file, "\nNo caches instance.\n");
     }
-#if HWUI_NEW_OPS
     fprintf(file, "\nPipeline=FrameBuilder\n");
-#else
-    fprintf(file, "\nPipeline=OpenGLRenderer\n");
-#endif
     fflush(file);
     return nullptr;
 }
diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h
index d4a6646..4813ff0 100644
--- a/libs/hwui/tests/common/TestScene.h
+++ b/libs/hwui/tests/common/TestScene.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef TESTS_TESTSCENE_H
-#define TESTS_TESTSCENE_H
+
+#pragma once
 
 #include <string>
 #include <unordered_map>
@@ -22,14 +22,9 @@
 namespace android {
 namespace uirenderer {
 class RenderNode;
-
-#if HWUI_NEW_OPS
 class RecordingCanvas;
+
 typedef RecordingCanvas TestCanvas;
-#else
-class DisplayListCanvas;
-typedef DisplayListCanvas TestCanvas;
-#endif
 
 namespace test {
 
@@ -76,5 +71,3 @@
 } // namespace test
 } // namespace uirenderer
 } // namespace android
-
-#endif /* TESTS_TESTSCENE_H */
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 4536bef..9f7fee2 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef TEST_UTILS_H
-#define TEST_UTILS_H
+
+#pragma once
 
 #include <DeviceInfo.h>
 #include <DisplayList.h>
@@ -25,24 +25,15 @@
 #include <renderthread/RenderThread.h>
 #include <Snapshot.h>
 
-#if HWUI_NEW_OPS
 #include <RecordedOp.h>
 #include <RecordingCanvas.h>
-#else
-#include <DisplayListOp.h>
-#include <DisplayListCanvas.h>
-#endif
 
 #include <memory>
 
 namespace android {
 namespace uirenderer {
 
-#if HWUI_NEW_OPS
 typedef RecordingCanvas TestCanvas;
-#else
-typedef DisplayListCanvas TestCanvas;
-#endif
 
 #define EXPECT_MATRIX_APPROX_EQ(a, b) \
     EXPECT_TRUE(TestUtils::matricesAreApproxEqual(a, b))
@@ -251,5 +242,3 @@
 
 } /* namespace uirenderer */
 } /* namespace android */
-
-#endif /* TEST_UTILS_H */
diff --git a/libs/hwui/tests/common/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h
index 935ddcf..792312a 100644
--- a/libs/hwui/tests/common/scenes/TestSceneBase.h
+++ b/libs/hwui/tests/common/scenes/TestSceneBase.h
@@ -13,10 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef TESTS_SCENES_TESTSCENEBASE_H
-#define TESTS_SCENES_TESTSCENEBASE_H
 
-#include "DisplayListCanvas.h"
+#pragma once
+
 #include "RecordingCanvas.h"
 #include "RenderNode.h"
 #include "tests/common/TestContext.h"
@@ -30,5 +29,3 @@
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
 using namespace android::uirenderer::test;
-
-#endif /* TESTS_SCENES_TESTSCENEBASE_H_ */
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index cd4a3c9..ed3b847 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -17,21 +17,13 @@
 #include <benchmark/benchmark.h>
 
 #include "DisplayList.h"
-#if HWUI_NEW_OPS
 #include "RecordingCanvas.h"
-#else
-#include "DisplayListCanvas.h"
-#endif
 #include "tests/common/TestUtils.h"
 
 using namespace android;
 using namespace android::uirenderer;
 
-#if HWUI_NEW_OPS
 typedef RecordingCanvas TestCanvas;
-#else
-typedef DisplayListCanvas TestCanvas;
-#endif
 
 void BM_DisplayList_alloc(benchmark::State& benchState) {
     while (benchState.KeepRunning()) {
diff --git a/libs/hwui/tests/unit/GlopBuilderTests.cpp b/libs/hwui/tests/unit/GlopBuilderTests.cpp
index 95543d3..67e58e2 100644
--- a/libs/hwui/tests/unit/GlopBuilderTests.cpp
+++ b/libs/hwui/tests/unit/GlopBuilderTests.cpp
@@ -85,9 +85,6 @@
 }
 
 static void expectGlopEq(Glop& expectedGlop, Glop& builtGlop) {
-#if !HWUI_NEW_OPS
-    EXPECT_EQ(expectedGlop.bounds, builtGlop.bounds);
-#endif
     expectBlendEq(expectedGlop.blend, builtGlop.blend);
     expectFillEq(expectedGlop.fill, builtGlop.fill);
     expectMeshEq(expectedGlop.mesh, builtGlop.mesh);
@@ -138,9 +135,6 @@
     // unit quad also should be translate by additional (0.3, 0.3) to snap to exact pixels.
     goldenGlop->transform.modelView.loadTranslate(1.3, 1.3, 0);
     goldenGlop->transform.modelView.scale(99, 99, 1);
-#if !HWUI_NEW_OPS
-    goldenGlop->bounds = android::uirenderer::Rect(1.70, 1.70, 100.70, 100.70);
-#endif
     goldenGlop->transform.canvas = simpleTranslate;
     goldenGlop->fill.texture.filter = GL_NEAREST;
     expectGlopEq(*goldenGlop, glop);
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index e0b2593..b879f78 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -16,7 +16,6 @@
 #include "TestWindowContext.h"
 
 #include "AnimationContext.h"
-#include "DisplayListCanvas.h"
 #include "IContextFactory.h"
 #include "RecordingCanvas.h"
 #include "RenderNode.h"
@@ -89,11 +88,7 @@
         android::uirenderer::Vector3 lightVector { lightX, -200.0f, 800.0f };
         mProxy->setup(800.0f, 255 * 0.075f, 255 * 0.15f);
         mProxy->setLightCenter(lightVector);
-#if HWUI_NEW_OPS
         mCanvas.reset(new android::uirenderer::RecordingCanvas(mSize.width(), mSize.height()));
-#else
-        mCanvas.reset(new android::uirenderer::DisplayListCanvas(mSize.width(), mSize.height()));
-#endif
     }
 
     SkCanvas* prepareToDraw() {
@@ -171,11 +166,7 @@
 
     std::unique_ptr<android::uirenderer::RenderNode> mRootNode;
     std::unique_ptr<android::uirenderer::renderthread::RenderProxy> mProxy;
-#if HWUI_NEW_OPS
     std::unique_ptr<android::uirenderer::RecordingCanvas> mCanvas;
-#else
-    std::unique_ptr<android::uirenderer::DisplayListCanvas> mCanvas;
-#endif
     android::sp<android::IGraphicBufferProducer> mProducer;
     android::sp<android::IGraphicBufferConsumer> mConsumer;
     android::sp<android::CpuConsumer> mCpuConsumer;