diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 2b4260d..5e6125f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1868,7 +1868,7 @@
                 mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
                 switch (graphType) {
                     case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRects(mProfileShapes[i], count, mProfilePaint);
+                        mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
                         break;
                     case GraphDataProvider.GRAPH_TYPE_LINES:
                         mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index de14826..f4fcc81 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -479,7 +479,7 @@
             rects.push(r.fTop);
             rects.push(r.fRight);
             rects.push(r.fBottom);
-            count++;
+            count += 4;
             it.next();
         }
         renderer->drawRects(rects.array(), count, paint);
diff --git a/libs/hwui/DisplayListLogBuffer.cpp b/libs/hwui/DisplayListLogBuffer.cpp
index f204644..f039fcd 100644
--- a/libs/hwui/DisplayListLogBuffer.cpp
+++ b/libs/hwui/DisplayListLogBuffer.cpp
@@ -18,9 +18,8 @@
 
 // BUFFER_SIZE size must be one more than a multiple of COMMAND_SIZE to ensure
 // that mStart always points at the next command, not just the next item
-#define COMMAND_SIZE 2
 #define NUM_COMMANDS 50
-#define BUFFER_SIZE ((NUM_COMMANDS * COMMAND_SIZE) + 1)
+#define BUFFER_SIZE ((NUM_COMMANDS) + 1)
 
 /**
  * DisplayListLogBuffer is a utility class which logs the most recent display
@@ -57,7 +56,7 @@
 
 
 DisplayListLogBuffer::DisplayListLogBuffer() {
-    mBufferFirst = (int*) malloc(BUFFER_SIZE * sizeof(int));
+    mBufferFirst = (OpLog*) malloc(BUFFER_SIZE * sizeof(OpLog));
     mStart = mBufferFirst;
     mBufferLast = mBufferFirst + BUFFER_SIZE - 1;
     mEnd = mStart;
@@ -71,42 +70,30 @@
  * Called from DisplayListRenderer to output the current buffer into the
  * specified FILE. This only happens in a dumpsys/bugreport operation.
  */
-void DisplayListLogBuffer::outputCommands(FILE *file, const char* opNames[])
+void DisplayListLogBuffer::outputCommands(FILE *file)
 {
-    int *tmpBufferPtr = mStart;
+    OpLog* tmpBufferPtr = mStart;
     while (true) {
         if (tmpBufferPtr == mEnd) {
             break;
         }
-        int level = *tmpBufferPtr++;
+        OpLog* nextOp = tmpBufferPtr++;
         if (tmpBufferPtr > mBufferLast) {
             tmpBufferPtr = mBufferFirst;
         }
-        int op = *tmpBufferPtr++;
-        if (tmpBufferPtr > mBufferLast) {
-            tmpBufferPtr = mBufferFirst;
-        }
-        uint32_t count = (level + 1) * 2;
-        char indent[count + 1];
-        for (uint32_t i = 0; i < count; i++) {
-            indent[i] = ' ';
-        }
-        indent[count] = '\0';
-        fprintf(file, "%s%s\n", indent, opNames[op]);
+
+        fprintf(file, "%*s%s\n", tmpBufferPtr->level*2, "", tmpBufferPtr->label);
     }
 }
 
-void DisplayListLogBuffer::writeCommand(int level, int op) {
-    writeInt(level);
-    writeInt(op);
-}
-
 /**
- * Store the given value in the buffer and increment/wrap the mEnd
- * and mStart values as appropriate.
+ * Store the given level and label in the buffer and increment/wrap the mEnd
+ * and mStart values as appropriate. Label should point to static memory.
  */
-void DisplayListLogBuffer::writeInt(int value) {
-    *((int*)mEnd) = value;
+void DisplayListLogBuffer::writeCommand(int level, const char* label) {
+    mEnd->level = level;
+    mEnd->label = label;
+
     if (mEnd == mBufferLast) {
         mEnd = mBufferFirst;
     } else {
diff --git a/libs/hwui/DisplayListLogBuffer.h b/libs/hwui/DisplayListLogBuffer.h
index 5d689bb..c884789 100644
--- a/libs/hwui/DisplayListLogBuffer.h
+++ b/libs/hwui/DisplayListLogBuffer.h
@@ -31,19 +31,23 @@
     friend class Singleton<DisplayListLogBuffer>;
 
 public:
-    void writeCommand(int level, int op);
-    void writeInt(int value);
-    void outputCommands(FILE *file, const char* opNames[]);
+    void writeCommand(int level, const char* label);
+    void outputCommands(FILE *file);
 
     bool isEmpty() {
         return (mStart == mEnd);
     }
 
+    struct OpLog {
+        int level;
+        const char* label;
+    };
+
 private:
-    int *mBufferFirst; // where the memory starts
-    int* mStart;       // where the current command stream starts
-    int* mEnd;         // where the current commands end
-    int* mBufferLast;  // where the buffer memory ends
+    OpLog* mBufferFirst; // where the memory starts
+    OpLog* mStart;       // where the current command stream starts
+    OpLog* mEnd;         // where the current commands end
+    OpLog* mBufferLast;  // where the buffer memory ends
 
 };
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
new file mode 100644
index 0000000..a4de56d
--- /dev/null
+++ b/libs/hwui/DisplayListOp.h
@@ -0,0 +1,1138 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_DISPLAY_OPERATION_H
+#define ANDROID_HWUI_DISPLAY_OPERATION_H
+
+#include <SkXfermode.h>
+
+#include "OpenGLRenderer.h"
+#include "DisplayListRenderer.h"
+#include "utils/LinearAllocator.h"
+
+#define CRASH() do { \
+    *(int *)(uintptr_t)0xbbadbeef = 0; \
+    ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \
+} while(false)
+
+#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
+#define MATRIX_ARGS(m) \
+    m->get(0), m->get(1), m->get(2), \
+    m->get(3), m->get(4), m->get(5), \
+    m->get(6), m->get(7), m->get(8)
+#define RECT_STRING "%.2f %.2f %.2f %.2f"
+#define RECT_ARGS(r) \
+    r.left, r.top, r.right, r.bottom
+
+// 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--%p " s, level * 2, "", this, __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() { CRASH(); }
+    static void operator delete(void* ptr) { CRASH(); }
+    /** static void* operator new(size_t size); PURPOSELY OMITTED **/
+    static void* operator new(size_t size, LinearAllocator& allocator) {
+        return allocator.alloc(size);
+    }
+
+    enum OpLogFlag {
+        kOpLogFlag_Recurse = 0x1,
+        kOpLogFlag_JSON = 0x2 // TODO: add?
+    };
+
+    //TODO: for draw batching, DrawOps should override a virtual sub-method, with
+    // DrawOps::apply deferring operations to a different list if possible
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) = 0;
+
+    virtual void output(int level, uint32_t flags = 0) = 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:
+    StateOp() {};
+
+    virtual ~StateOp() {}
+
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) {
+        applyState(renderer, saveCount);
+        return DrawGlInfo::kStatusDone;
+    }
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) = 0;
+};
+
+class DrawOp : public DisplayListOp {
+public:
+    DrawOp(SkPaint* paint)
+            : mPaint(paint), mQuickRejected(false) {}
+
+    virtual status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, int saveCount,
+            uint32_t level, bool caching, int multipliedAlpha) {
+        if (mQuickRejected && CC_LIKELY(flags & DisplayList::kReplayFlag_ClipChildren)) {
+            return DrawGlInfo::kStatusDone;
+        }
+
+        return applyDraw(renderer, dirty, level, caching, multipliedAlpha);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) = 0;
+
+    // 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; }
+
+protected:
+    SkPaint* getPaint(OpenGLRenderer& renderer) {
+        return renderer.filterPaint(mPaint);
+    }
+
+    SkPaint* mPaint; // should be accessed via getPaint() when applying
+    bool mQuickRejected;
+};
+
+class DrawBoundedOp : public DrawOp {
+public:
+    DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
+
+    // default constructor for area, to be overridden in child constructor body
+    DrawBoundedOp(SkPaint* paint)
+            : DrawOp(paint) {}
+
+    bool getLocalBounds(Rect& localBounds) {
+        localBounds.set(mLocalBounds);
+        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 applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.save(mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Save flags %x", mFlags);
+    }
+
+    virtual const char* name() { return "Save"; }
+
+private:
+    int mFlags;
+};
+
+class RestoreToCountOp : public StateOp {
+public:
+    RestoreToCountOp(int count)
+            : mCount(count) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.restoreToCount(saveCount + mCount);
+
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Restore to count %d", mCount);
+    }
+
+    virtual const char* name() { return "RestoreToCount"; }
+
+private:
+    int mCount;
+};
+
+class SaveLayerOp : public StateOp {
+public:
+    SaveLayerOp(float left, float top, float right, float bottom, SkPaint* paint, int flags)
+            : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        SkPaint* paint = renderer.filterPaint(mPaint);
+        renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, paint, mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SaveLayer of area " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "SaveLayer"; }
+
+private:
+    Rect mArea;
+    SkPaint* mPaint;
+    int mFlags;
+};
+
+class SaveLayerAlphaOp : public StateOp {
+public:
+    SaveLayerAlphaOp(float left, float top, float right, float bottom, int alpha, int flags)
+            : mArea(left, top, right, bottom), mAlpha(alpha), mFlags(flags) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.saveLayerAlpha(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mFlags);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SaveLayerAlpha of area " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "SaveLayerAlpha"; }
+private:
+    Rect mArea;
+    int mAlpha;
+    int mFlags;
+};
+
+class TranslateOp : public StateOp {
+public:
+    TranslateOp(float dx, float dy)
+            : mDx(dx), mDy(dy) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.translate(mDx, mDy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Translate by %f %f", mDx, mDy);
+    }
+
+    virtual const char* name() { return "Translate"; }
+
+private:
+    float mDx;
+    float mDy;
+};
+
+class RotateOp : public StateOp {
+public:
+    RotateOp(float degrees)
+            : mDegrees(degrees) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.rotate(mDegrees);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Rotate by %f degrees", mDegrees);
+    }
+
+    virtual const char* name() { 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) {
+        renderer.scale(mSx, mSy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Scale by %f %f", mSx, mSy);
+    }
+
+    virtual const char* name() { 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) {
+        renderer.skew(mSx, mSy);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("Skew by %f %f", mSx, mSy);
+    }
+
+    virtual const char* name() { return "Skew"; }
+
+private:
+    float mSx;
+    float mSy;
+};
+
+class SetMatrixOp : public StateOp {
+public:
+    SetMatrixOp(SkMatrix* matrix)
+            : mMatrix(matrix) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setMatrix(mMatrix);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "SetMatrix"; }
+
+private:
+    SkMatrix* mMatrix;
+};
+
+class ConcatMatrixOp : public StateOp {
+public:
+    ConcatMatrixOp(SkMatrix* matrix)
+            : mMatrix(matrix) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.concatMatrix(mMatrix);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "ConcatMatrix"; }
+
+private:
+    SkMatrix* mMatrix;
+};
+
+class ClipRectOp : public StateOp {
+public:
+    ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
+            : mArea(left, top, right, bottom), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipRect(mArea.left, mArea.top, mArea.right, mArea.bottom, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("ClipRect " RECT_STRING, RECT_ARGS(mArea));
+    }
+
+    virtual const char* name() { return "ClipRect"; }
+
+private:
+    Rect mArea;
+    SkRegion::Op mOp;
+};
+
+class ClipPathOp : public StateOp {
+public:
+    ClipPathOp(SkPath* path, SkRegion::Op op)
+            : mPath(path), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipPath(mPath, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        SkRect bounds = mPath->getBounds();
+        OP_LOG("ClipPath bounds " RECT_STRING,
+                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+    }
+
+    virtual const char* name() { return "ClipPath"; }
+
+private:
+    SkPath* mPath;
+    SkRegion::Op mOp;
+};
+
+class ClipRegionOp : public StateOp {
+public:
+    ClipRegionOp(SkRegion* region, SkRegion::Op op)
+            : mRegion(region), mOp(op) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.clipRegion(mRegion, mOp);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        SkIRect bounds = mRegion->getBounds();
+        OP_LOG("ClipRegion bounds %d %d %d %d",
+                bounds.left(), bounds.top(), bounds.right(), bounds.bottom());
+    }
+
+    virtual const char* name() { return "ClipRegion"; }
+
+private:
+    SkRegion* mRegion;
+    SkRegion::Op mOp;
+};
+
+class ResetShaderOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetShader();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetShader");
+    }
+
+    virtual const char* name() { return "ResetShader"; }
+};
+
+class SetupShaderOp : public StateOp {
+public:
+    SetupShaderOp(SkiaShader* shader)
+            : mShader(shader) {}
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupShader(mShader);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupShader, shader %p", mShader);
+    }
+
+    virtual const char* name() { return "SetupShader"; }
+
+private:
+    SkiaShader* mShader;
+};
+
+class ResetColorFilterOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetColorFilter();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetColorFilter");
+    }
+
+    virtual const char* name() { return "ResetColorFilter"; }
+};
+
+class SetupColorFilterOp : public StateOp {
+public:
+    SetupColorFilterOp(SkiaColorFilter* colorFilter)
+            : mColorFilter(colorFilter) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupColorFilter(mColorFilter);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupColorFilter, filter %p", mColorFilter);
+    }
+
+    virtual const char* name() { return "SetupColorFilter"; }
+
+private:
+    SkiaColorFilter* mColorFilter;
+};
+
+class ResetShadowOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetShadow();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetShadow");
+    }
+
+    virtual const char* name() { return "ResetShadow"; }
+};
+
+class SetupShadowOp : public StateOp {
+public:
+    SetupShadowOp(float radius, float dx, float dy, int color)
+            : mRadius(radius), mDx(dx), mDy(dy), mColor(color) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupShadow(mRadius, mDx, mDy, mColor);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupShadow, radius %f, %f, %f, color %#x", mRadius, mDx, mDy, mColor);
+    }
+
+    virtual const char* name() { return "SetupShadow"; }
+
+private:
+    float mRadius;
+    float mDx;
+    float mDy;
+    int mColor;
+};
+
+class ResetPaintFilterOp : public StateOp {
+public:
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.resetPaintFilter();
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOGS("ResetPaintFilter");
+    }
+
+    virtual const char* name() { return "ResetPaintFilter"; }
+};
+
+class SetupPaintFilterOp : public StateOp {
+public:
+    SetupPaintFilterOp(int clearBits, int setBits)
+            : mClearBits(clearBits), mSetBits(setBits) {}
+
+    virtual void applyState(OpenGLRenderer& renderer, int saveCount) {
+        renderer.setupPaintFilter(mClearBits, mSetBits);
+    }
+
+    virtual void output(int level, uint32_t flags = 0) {
+        OP_LOG("SetupPaintFilter, clear %#x, set %#x", mClearBits, mSetBits);
+    }
+
+    virtual const char* name() { return "SetupPaintFilter"; }
+
+private:
+    int mClearBits;
+    int mSetBits;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// DRAW OPERATIONS - these are operations that can draw to the canvas's device
+///////////////////////////////////////////////////////////////////////////////
+
+class DrawBitmapOp : public DrawBoundedOp {
+public:
+    DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(),
+                    paint),
+            mBitmap(bitmap) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        SkPaint* paint = getPaint(renderer);
+        int oldAlpha = -1;
+        if (caching && multipliedAlpha < 255) {
+            oldAlpha = paint->getAlpha();
+            paint->setAlpha(multipliedAlpha);
+        }
+        status_t ret = renderer.drawBitmap(mBitmap, mLocalBounds.left, mLocalBounds.top, paint);
+        if (oldAlpha >= 0) {
+            paint->setAlpha(oldAlpha);
+        }
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top);
+    }
+
+    virtual const char* name() { return "DrawBitmap"; }
+
+protected:
+    SkBitmap* mBitmap;
+};
+
+class DrawBitmapMatrixOp : public DrawBoundedOp {
+public:
+    DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
+            : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
+        mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
+        const mat4 transform(*matrix);
+        transform.mapRect(mLocalBounds);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmap(mBitmap, mMatrix, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
+    }
+
+    virtual const char* name() { return "DrawBitmap"; }
+
+private:
+    SkBitmap* mBitmap;
+    SkMatrix* mMatrix;
+};
+
+class DrawBitmapRectOp : public DrawBoundedOp {
+public:
+    DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
+            float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
+            : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
+            mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmap(mBitmap, mSrc.left, mSrc.top, mSrc.right, mSrc.bottom,
+                mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
+                getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p src="RECT_STRING", dst="RECT_STRING,
+                mBitmap, RECT_ARGS(mSrc), RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawBitmapRect"; }
+
+private:
+    SkBitmap* mBitmap;
+    Rect mSrc;
+};
+
+class DrawBitmapDataOp : public DrawBitmapOp {
+public:
+    DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+            : DrawBitmapOp(bitmap, left, top, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmapData(mBitmap, mLocalBounds.left,
+                mLocalBounds.top, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p", mBitmap);
+    }
+
+    virtual const char* name() { return "DrawBitmapData"; }
+};
+
+class DrawBitmapMeshOp : public DrawOp {
+public:
+    DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
+            float* vertices, int* colors, SkPaint* paint)
+            : DrawOp(paint), mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
+            mVertices(vertices), mColors(colors) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawBitmapMesh(mBitmap, mMeshWidth, mMeshHeight,
+                mVertices, mColors, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw bitmap %p mesh %d x %d", mBitmap, mMeshWidth, mMeshHeight);
+    }
+
+    virtual const char* name() { return "DrawBitmapMesh"; }
+
+private:
+    SkBitmap* mBitmap;
+    int mMeshWidth;
+    int mMeshHeight;
+    float* mVertices;
+    int* mColors;
+};
+
+class DrawPatchOp : public DrawBoundedOp {
+public:
+    DrawPatchOp(SkBitmap* bitmap, const int32_t* xDivs,
+            const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height,
+            int8_t numColors, float left, float top, float right, float bottom,
+            int alpha, SkXfermode::Mode mode)
+            : DrawBoundedOp(left, top, right, bottom, 0),
+            mBitmap(bitmap), mxDivs(xDivs), myDivs(yDivs),
+            mColors(colors), mxDivsCount(width), myDivsCount(height),
+            mNumColors(numColors), mAlpha(alpha), mMode(mode) {};
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        // NOTE: not calling the virtual method, which takes a paint
+        return renderer.drawPatch(mBitmap, mxDivs, myDivs, mColors,
+                mxDivsCount, myDivsCount, mNumColors,
+                mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, mAlpha, mMode);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw patch "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawPatch"; }
+
+private:
+    SkBitmap* mBitmap;
+    const int32_t* mxDivs;
+    const int32_t* myDivs;
+    const uint32_t* mColors;
+    uint32_t mxDivsCount;
+    uint32_t myDivsCount;
+    int8_t mNumColors;
+    int mAlpha;
+    SkXfermode::Mode mMode;
+};
+
+class DrawColorOp : public DrawOp {
+public:
+    DrawColorOp(int color, SkXfermode::Mode mode)
+            : DrawOp(0), mColor(color), mMode(mode) {};
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawColor(mColor, mMode);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw color %#x, mode %d", mColor, mMode);
+    }
+
+    virtual const char* name() { return "DrawColor"; }
+
+private:
+    int mColor;
+    SkXfermode::Mode mMode;
+};
+
+class DrawStrokableOp : public DrawBoundedOp {
+public:
+    DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawBoundedOp(left, top, right, bottom, paint) {};
+
+    bool getLocalBounds(Rect& localBounds) {
+        if (mPaint && mPaint->getStyle() != SkPaint::kFill_Style) {
+            float outset = mPaint->getStrokeWidth() * 0.5f;
+            localBounds.set(mLocalBounds.left - outset, mLocalBounds.top - outset,
+                    mLocalBounds.right + outset, mLocalBounds.bottom + outset);
+        } else {
+            localBounds.set(mLocalBounds);
+        }
+        return true;
+    }
+};
+
+class DrawRectOp : public DrawStrokableOp {
+public:
+    DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRect(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Rect "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawRect"; }
+};
+
+class DrawRectsOp : public DrawOp {
+public:
+    DrawRectsOp(const float* rects, int count, SkPaint* paint)
+            : DrawOp(paint), mRects(rects), mCount(count) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRects(mRects, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Rects count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawRects"; }
+
+private:
+    const float* mRects;
+    int mCount;
+};
+
+class DrawRoundRectOp : public DrawStrokableOp {
+public:
+    DrawRoundRectOp(float left, float top, float right, float bottom,
+            float rx, float ry, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawRoundRect(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, mRx, mRy, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw RoundRect "RECT_STRING", rx %f, ry %f", RECT_ARGS(mLocalBounds), mRx, mRy);
+    }
+
+    virtual const char* name() { return "DrawRoundRect"; }
+
+private:
+    float mRx;
+    float mRy;
+};
+
+class DrawCircleOp : public DrawStrokableOp {
+public:
+    DrawCircleOp(float x, float y, float radius, SkPaint* paint)
+            : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
+            mX(x), mY(y), mRadius(radius) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawCircle(mX, mY, mRadius, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Circle x %f, y %f, r %f", mX, mY, mRadius);
+    }
+
+    virtual const char* name() { return "DrawCircle"; }
+
+private:
+    float mX;
+    float mY;
+    float mRadius;
+};
+
+class DrawOvalOp : public DrawStrokableOp {
+public:
+    DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawOval(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Oval "RECT_STRING, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawOval"; }
+};
+
+class DrawArcOp : public DrawStrokableOp {
+public:
+    DrawArcOp(float left, float top, float right, float bottom,
+            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
+            : DrawStrokableOp(left, top, right, bottom, paint),
+            mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawArc(mLocalBounds.left, mLocalBounds.top,
+                mLocalBounds.right, mLocalBounds.bottom,
+                mStartAngle, mSweepAngle, mUseCenter, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Arc "RECT_STRING", start %f, sweep %f, useCenter %d",
+                RECT_ARGS(mLocalBounds), mStartAngle, mSweepAngle, mUseCenter);
+    }
+
+    virtual const char* name() { return "DrawArc"; }
+
+private:
+    float mStartAngle;
+    float mSweepAngle;
+    bool mUseCenter;
+};
+
+class DrawPathOp : public DrawBoundedOp {
+public:
+    DrawPathOp(SkPath* path, SkPaint* paint)
+            : DrawBoundedOp(paint), mPath(path) {
+        float left, top, offset;
+        uint32_t width, height;
+        computePathBounds(path, paint, left, top, offset, width, height);
+        left -= offset;
+        top -= offset;
+        mLocalBounds.set(left, top, left + width, top + height);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPath(mPath, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Path %p in "RECT_STRING, mPath, RECT_ARGS(mLocalBounds));
+    }
+
+    virtual const char* name() { return "DrawPath"; }
+
+private:
+    SkPath* mPath;
+};
+
+class DrawLinesOp : public DrawOp {
+public:
+    DrawLinesOp(float* points, int count, SkPaint* paint)
+            : DrawOp(paint), mPoints(points), mCount(count) {
+        /* TODO: inherit from DrawBoundedOp and calculate localbounds something like:
+        for (int i = 0; i < count; i += 2) {
+            mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
+            mLocalBounds.right = fmaxf(mLocalBounds.right, points[i]);
+            mLocalBounds.top = fminf(mLocalBounds.top, points[i+1]);
+            mLocalBounds.bottom = fmaxf(mLocalBounds.bottom, points[i+1]);
+        }
+        */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawLines(mPoints, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Lines count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawLines"; }
+
+protected:
+    float* mPoints;
+    int mCount;
+};
+
+class DrawPointsOp : public DrawLinesOp {
+public:
+    DrawPointsOp(float* points, int count, SkPaint* paint)
+            : DrawLinesOp(points, count, paint) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPoints(mPoints, mCount, getPaint(renderer));
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Points count %d", mCount);
+    }
+
+    virtual const char* name() { return "DrawPoints"; }
+};
+
+class DrawSomeTextOp : public DrawOp {
+public:
+    DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
+            : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw some text, %d bytes", mBytesCount);
+    }
+protected:
+    const char* mText;
+    int mBytesCount;
+    int mCount;
+};
+
+class DrawTextOnPathOp : public DrawSomeTextOp {
+public:
+    DrawTextOnPathOp(const char* text, int bytesCount, int count,
+            SkPath* path, float hOffset, float vOffset, SkPaint* paint)
+            : DrawSomeTextOp(text, bytesCount, count, paint),
+            mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
+        /* TODO: inherit from DrawBounded and init mLocalBounds */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawTextOnPath(mText, mBytesCount, mCount, mPath,
+                mHOffset, mVOffset, getPaint(renderer));
+    }
+
+    virtual const char* name() { return "DrawTextOnPath"; }
+
+private:
+    SkPath* mPath;
+    float mHOffset;
+    float mVOffset;
+};
+
+class DrawPosTextOp : public DrawSomeTextOp {
+public:
+    DrawPosTextOp(const char* text, int bytesCount, int count,
+            const float* positions, SkPaint* paint)
+            : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
+        /* TODO: inherit from DrawBounded and init mLocalBounds */
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawPosText(mText, mBytesCount, mCount, mPositions, getPaint(renderer));
+    }
+
+    virtual const char* name() { return "DrawPosText"; }
+
+private:
+    const float* mPositions;
+};
+
+class DrawTextOp : public DrawBoundedOp {
+public:
+    DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
+            const float* positions, SkPaint* paint, float length)
+            : DrawBoundedOp(paint), mText(text), mBytesCount(bytesCount), mCount(count),
+            mX(x), mY(y), mPositions(positions), mLength(length) {
+        SkPaint::FontMetrics metrics;
+        paint->getFontMetrics(&metrics, 0.0f);
+        mLocalBounds.set(mX, mY + metrics.fTop, mX + length, mY + metrics.fBottom);
+    }
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawText(mText, mBytesCount, mCount, mX, mY,
+                mPositions, getPaint(renderer), mLength);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Text of count %d, bytes %d", mCount, mBytesCount);
+    }
+
+    virtual const char* name() { return "DrawText"; }
+
+private:
+    const char* mText;
+    int mBytesCount;
+    int mCount;
+    float mX;
+    float mY;
+    const float* mPositions;
+    float mLength;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// SPECIAL DRAW OPERATIONS
+///////////////////////////////////////////////////////////////////////////////
+
+class DrawFunctorOp : public DrawOp {
+public:
+    DrawFunctorOp(Functor* functor)
+            : DrawOp(0), mFunctor(functor) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        renderer.startMark("GL functor");
+        status_t ret = renderer.callDrawGLFunction(mFunctor, dirty);
+        renderer.endMark();
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Functor %p", mFunctor);
+    }
+
+    virtual const char* name() { return "DrawFunctor"; }
+
+private:
+    Functor* mFunctor;
+};
+
+class DrawDisplayListOp : public DrawOp {
+public:
+    DrawDisplayListOp(DisplayList* displayList, int flags)
+            : DrawOp(0), mDisplayList(displayList), mFlags(flags) {}
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        return renderer.drawDisplayList(mDisplayList, dirty, mFlags, level + 1);
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Display List %p, flags %#x", mDisplayList, mFlags);
+        if (mDisplayList && (flags & kOpLogFlag_Recurse)) {
+            mDisplayList->output(level + 1);
+        }
+    }
+
+    virtual const char* name() { return "DrawDisplayList"; }
+
+private:
+    DisplayList* mDisplayList;
+    int mFlags;
+};
+
+class DrawLayerOp : public DrawOp {
+public:
+    DrawLayerOp(Layer* layer, float x, float y, SkPaint* paint)
+            : DrawOp(paint), mLayer(layer), mX(x), mY(y) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
+            bool caching, int multipliedAlpha) {
+        int oldAlpha = -1;
+
+        if (caching && multipliedAlpha < 255) {
+            oldAlpha = mLayer->getAlpha();
+            mLayer->setAlpha(multipliedAlpha);
+        }
+        status_t ret = renderer.drawLayer(mLayer, mX, mY, getPaint(renderer));
+        if (oldAlpha >= 0) {
+            mLayer->setAlpha(oldAlpha);
+        }
+        return ret;
+    }
+
+    virtual void output(int level, uint32_t flags) {
+        OP_LOG("Draw Layer %p at %f %f", mLayer, mX, mY);
+    }
+
+    virtual const char* name() { return "DrawLayer"; }
+
+private:
+    Layer* mLayer;
+    float mX;
+    float mY;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_DISPLAY_OPERATION_H
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index f0c9ce4..5cb629e 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -21,6 +21,7 @@
 #include <private/hwui/DrawGlInfo.h>
 
 #include "DisplayListLogBuffer.h"
+#include "DisplayListOp.h"
 #include "DisplayListRenderer.h"
 #include "Caches.h"
 
@@ -31,53 +32,6 @@
 // Display list
 ///////////////////////////////////////////////////////////////////////////////
 
-const char* DisplayList::OP_NAMES[] = {
-    "Save",
-    "Restore",
-    "RestoreToCount",
-    "SaveLayer",
-    "SaveLayerAlpha",
-    "Translate",
-    "Rotate",
-    "Scale",
-    "Skew",
-    "SetMatrix",
-    "ConcatMatrix",
-    "ClipRect",
-    "ClipPath",
-    "ClipRegion",
-    "DrawDisplayList",
-    "DrawLayer",
-    "DrawBitmap",
-    "DrawBitmapMatrix",
-    "DrawBitmapRect",
-    "DrawBitmapData",
-    "DrawBitmapMesh",
-    "DrawPatch",
-    "DrawColor",
-    "DrawRect",
-    "DrawRoundRect",
-    "DrawCircle",
-    "DrawOval",
-    "DrawArc",
-    "DrawPath",
-    "DrawLines",
-    "DrawPoints",
-    "DrawTextOnPath",
-    "DrawPosText",
-    "DrawText",
-    "DrawRects",
-    "ResetShader",
-    "SetupShader",
-    "ResetColorFilter",
-    "SetupColorFilter",
-    "ResetShadow",
-    "SetupShadow",
-    "ResetPaintFilter",
-    "SetupPaintFilter",
-    "DrawGLFunction"
-};
-
 void DisplayList::outputLogBuffer(int fd) {
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     if (logBuffer.isEmpty()) {
@@ -87,7 +41,7 @@
     FILE *file = fdopen(fd, "a");
 
     fprintf(file, "\nRecent DisplayList operations\n");
-    logBuffer.outputCommands(file, OP_NAMES);
+    logBuffer.outputCommands(file);
 
     String8 cachesLog;
     Caches::getInstance().dumpMemoryUsage(cachesLog);
@@ -116,9 +70,7 @@
 }
 
 void DisplayList::clearResources() {
-    sk_free((void*) mReader.base());
-    mReader.setMemory(NULL, 0);
-
+    mDisplayListData = NULL;
     delete mTransformMatrix;
     delete mTransformCamera;
     delete mTransformMatrix3D;
@@ -200,7 +152,6 @@
 }
 
 void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
-
     if (reusing) {
         // re-using display list - clear out previous allocations
         clearResources();
@@ -208,16 +159,13 @@
 
     init();
 
-    const SkWriter32& writer = recorder.writeStream();
-    if (writer.size() == 0) {
+    mDisplayListData = recorder.getDisplayListData();
+    mSize = mDisplayListData->allocator.usedSize();
+
+    if (mSize == 0) {
         return;
     }
 
-    mSize = writer.size();
-    void* buffer = sk_malloc_throw(mSize);
-    writer.flatten(buffer);
-    mReader.setMemory(buffer, mSize);
-
     mFunctorCount = recorder.getFunctorCount();
 
     Caches& caches = Caches::getInstance();
@@ -312,392 +260,17 @@
  * 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.
  */
-void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) {
-    TextContainer text;
-
-    uint32_t count = (level + 1) * 2;
-    char indent[count + 1];
-    for (uint32_t i = 0; i < count; i++) {
-        indent[i] = ' ';
-    }
-    indent[count] = '\0';
-    ALOGD("%sStart display list (%p, %s, render=%d)", (char*) indent + 2, this,
+void DisplayList::output(uint32_t level) {
+    ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this,
             mName.string(), isRenderable());
 
-    ALOGD("%s%s %d", indent, "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    int saveCount = renderer.getSaveCount() - 1;
-
-    outputViewProperties(renderer, (char*) indent);
-    mReader.rewind();
-
-    while (!mReader.eof()) {
-        int op = mReader.readInt();
-        if (op & OP_MAY_BE_SKIPPED_MASK) {
-            int skip = mReader.readInt();
-            ALOGD("%sSkip %d", (char*) indent, skip);
-            op &= ~OP_MAY_BE_SKIPPED_MASK;
-        }
-
-        switch (op) {
-            case DrawGLFunction: {
-                Functor *functor = (Functor *) getInt();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
-            }
-            break;
-            case Save: {
-                int rendererNum = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
-            }
-            break;
-            case Restore: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case RestoreToCount: {
-                int restoreCount = saveCount + getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
-            }
-            break;
-            case SaveLayer: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                int flags = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
-            }
-            break;
-            case SaveLayerAlpha: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int alpha = getInt();
-                int flags = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
-            }
-            break;
-            case Translate: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
-            }
-            break;
-            case Rotate: {
-                float rotation = getFloat();
-                ALOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
-            }
-            break;
-            case Scale: {
-                float sx = getFloat();
-                float sy = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-            }
-            break;
-            case Skew: {
-                float sx = getFloat();
-                float sy = getFloat();
-                ALOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-            }
-            break;
-            case SetMatrix: {
-                SkMatrix* matrix = getMatrix();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
-            }
-            break;
-            case ConcatMatrix: {
-                SkMatrix* matrix = getMatrix();
-                ALOGD("%s%s new concat %p: [%f, %f, %f]   [%f, %f, %f]   [%f, %f, %f]",
-                        (char*) indent, OP_NAMES[op], matrix, matrix->get(0), matrix->get(1),
-                        matrix->get(2), matrix->get(3), matrix->get(4), matrix->get(5),
-                        matrix->get(6), matrix->get(7), matrix->get(8));
-            }
-            break;
-            case ClipRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int regionOp = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, regionOp);
-            }
-            break;
-            case ClipPath: {
-                SkPath* path = getPath();
-                int regionOp = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-            }
-            break;
-            case ClipRegion: {
-                SkRegion* region = getRegion();
-                int regionOp = getInt();
-                ALOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-            }
-            break;
-            case DrawDisplayList: {
-                DisplayList* displayList = getDisplayList();
-                int32_t flags = getInt();
-                ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
-                        displayList, mWidth, mHeight, flags, level + 1);
-                renderer.outputDisplayList(displayList, level + 1);
-            }
-            break;
-            case DrawLayer: {
-                Layer* layer = (Layer*) getInt();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        layer, x, y, paint);
-            }
-            break;
-            case DrawBitmap: {
-                SkBitmap* bitmap = getBitmap();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-            }
-            break;
-            case DrawBitmapMatrix: {
-                SkBitmap* bitmap = getBitmap();
-                SkMatrix* matrix = getMatrix();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, matrix, paint);
-            }
-            break;
-            case DrawBitmapRect: {
-                SkBitmap* bitmap = getBitmap();
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                float f7 = getFloat();
-                float f8 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
-            }
-            break;
-            case DrawBitmapData: {
-                SkBitmap* bitmap = getBitmapData();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %p", (char*) indent, OP_NAMES[op], x, y, paint);
-            }
-            break;
-            case DrawBitmapMesh: {
-                int verticesCount = 0;
-                uint32_t colorsCount = 0;
-                SkBitmap* bitmap = getBitmap();
-                uint32_t meshWidth = getInt();
-                uint32_t meshHeight = getInt();
-                float* vertices = getFloats(verticesCount);
-                bool hasColors = getInt();
-                int* colors = hasColors ? getInts(colorsCount) : NULL;
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case DrawPatch: {
-                int32_t* xDivs = NULL;
-                int32_t* yDivs = NULL;
-                uint32_t* colors = NULL;
-                uint32_t xDivsCount = 0;
-                uint32_t yDivsCount = 0;
-                int8_t numColors = 0;
-                SkBitmap* bitmap = getBitmap();
-                xDivs = getInts(xDivsCount);
-                yDivs = getInts(yDivsCount);
-                colors = getUInts(numColors);
-                float left = getFloat();
-                float top = getFloat();
-                float right = getFloat();
-                float bottom = getFloat();
-                int alpha = getInt();
-                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", (char*) indent, OP_NAMES[op],
-                        left, top, right, bottom);
-            }
-            break;
-            case DrawColor: {
-                int color = getInt();
-                int xferMode = getInt();
-                ALOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
-            }
-            break;
-            case DrawRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawRoundRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
-            }
-            break;
-            case DrawCircle: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
-            }
-            break;
-            case DrawOval: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawArc: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                int i1 = getInt();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
-            }
-            break;
-            case DrawPath: {
-                SkPath* path = getPath();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
-            }
-            break;
-            case DrawLines: {
-                int count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case DrawPoints: {
-                int count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case DrawTextOnPath: {
-                getText(&text);
-                int32_t count = getInt();
-                SkPath* path = getPath();
-                float hOffset = getFloat();
-                float vOffset = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                    text.text(), text.length(), count, paint);
-            }
-            break;
-            case DrawPosText: {
-                getText(&text);
-                int count = getInt();
-                int positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                        text.text(), text.length(), count, paint);
-            }
-            break;
-            case DrawText: {
-                getText(&text);
-                int32_t count = getInt();
-                float x = getFloat();
-                float y = getFloat();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                float length = getFloat();
-                ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                        text.text(), text.length(), count, paint);
-            }
-            break;
-            case DrawRects: {
-                int32_t count = 0;
-                float* rects = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                ALOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count / 4, paint);
-            }
-            break;
-            case ResetShader: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupShader: {
-                SkiaShader* shader = getShader();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
-            }
-            break;
-            case ResetColorFilter: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupColorFilter: {
-                SkiaColorFilter *colorFilter = getColorFilter();
-                ALOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
-            }
-            break;
-            case ResetShadow: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupShadow: {
-                float radius = getFloat();
-                float dx = getFloat();
-                float dy = getFloat();
-                int color = getInt();
-                ALOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
-                        radius, dx, dy, color);
-            }
-            break;
-            case ResetPaintFilter: {
-                ALOGD("%s%s", (char*) indent, OP_NAMES[op]);
-            }
-            break;
-            case SetupPaintFilter: {
-                int clearBits = getInt();
-                int setBits = getInt();
-                ALOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits);
-            }
-            break;
-            default:
-                ALOGD("Display List error: op not handled: %s%s",
-                        (char*) indent, OP_NAMES[op]);
-                break;
-        }
+    ALOGD("%*s%s %d", level * 4, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    outputViewProperties(level);
+    int flags = DisplayListOp::kOpLogFlag_Recurse;
+    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+        mDisplayListData->displayListOps[i]->output(level, flags);
     }
-    ALOGD("%sDone (%p, %s)", (char*) indent + 2, this, mName.string());
+    ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string());
 }
 
 void DisplayList::updateMatrix() {
@@ -743,115 +316,68 @@
     }
 }
 
-void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
+void DisplayList::outputViewProperties(uint32_t level) {
     updateMatrix();
     if (mLeft != 0 || mTop != 0) {
-        ALOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
+        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
     }
     if (mStaticMatrix) {
-        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (static)", mStaticMatrix,
-                mStaticMatrix->get(0), mStaticMatrix->get(1),
-                mStaticMatrix->get(2), mStaticMatrix->get(3),
-                mStaticMatrix->get(4), mStaticMatrix->get(5),
-                mStaticMatrix->get(6), mStaticMatrix->get(7),
-                mStaticMatrix->get(8));
+        ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
+                level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
     }
     if (mAnimationMatrix) {
-        ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (animation)", mAnimationMatrix,
-                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
-                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
-                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
-                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
-                mAnimationMatrix->get(8));
+        ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
+                level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
     }
     if (mMatrixFlags != 0) {
         if (mMatrixFlags == TRANSLATION) {
-            ALOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
+            ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
         } else {
-            ALOGD("%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                    indent, "ConcatMatrix", mTransformMatrix,
-                    mTransformMatrix->get(0), mTransformMatrix->get(1),
-                    mTransformMatrix->get(2), mTransformMatrix->get(3),
-                    mTransformMatrix->get(4), mTransformMatrix->get(5),
-                    mTransformMatrix->get(6), mTransformMatrix->get(7),
-                    mTransformMatrix->get(8));
+            ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
+                    level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
         }
     }
     if (mAlpha < 1 && !mCaching) {
         if (!mHasOverlappingRendering) {
-            ALOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
+            ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha);
         } else {
             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
             if (mClipChildren) {
                 flags |= SkCanvas::kClipToLayer_SaveFlag;
             }
-            ALOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
+            ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
                     (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
                     mMultipliedAlpha, flags);
         }
     }
     if (mClipChildren) {
-        ALOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
+        ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
                 (float) mRight - mLeft, (float) mBottom - mTop);
     }
 }
 
 void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
-#if DEBUG_DISPLAY_LIST
-        uint32_t count = (level + 1) * 2;
-        char indent[count + 1];
-        for (uint32_t i = 0; i < count; i++) {
-            indent[i] = ' ';
-        }
-        indent[count] = '\0';
+#if DEBUG_DISPLAYLIST
+    outputViewProperties(level);
 #endif
     updateMatrix();
     if (mLeft != 0 || mTop != 0) {
-        DISPLAY_LIST_LOGD("%s%s %d, %d", indent, "Translate (left, top)", mLeft, mTop);
         renderer.translate(mLeft, mTop);
     }
     if (mStaticMatrix) {
-        DISPLAY_LIST_LOGD(
-                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (static)", mStaticMatrix,
-                mStaticMatrix->get(0), mStaticMatrix->get(1),
-                mStaticMatrix->get(2), mStaticMatrix->get(3),
-                mStaticMatrix->get(4), mStaticMatrix->get(5),
-                mStaticMatrix->get(6), mStaticMatrix->get(7),
-                mStaticMatrix->get(8));
         renderer.concatMatrix(mStaticMatrix);
     } else if (mAnimationMatrix) {
-        DISPLAY_LIST_LOGD(
-                "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                indent, "ConcatMatrix (animation)", mAnimationMatrix,
-                mAnimationMatrix->get(0), mAnimationMatrix->get(1),
-                mAnimationMatrix->get(2), mAnimationMatrix->get(3),
-                mAnimationMatrix->get(4), mAnimationMatrix->get(5),
-                mAnimationMatrix->get(6), mAnimationMatrix->get(7),
-                mAnimationMatrix->get(8));
         renderer.concatMatrix(mAnimationMatrix);
     }
     if (mMatrixFlags != 0) {
         if (mMatrixFlags == TRANSLATION) {
-            DISPLAY_LIST_LOGD("%s%s %f, %f", indent, "Translate", mTranslationX, mTranslationY);
             renderer.translate(mTranslationX, mTranslationY);
         } else {
-            DISPLAY_LIST_LOGD(
-                    "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                    indent, "ConcatMatrix", mTransformMatrix,
-                    mTransformMatrix->get(0), mTransformMatrix->get(1),
-                    mTransformMatrix->get(2), mTransformMatrix->get(3),
-                    mTransformMatrix->get(4), mTransformMatrix->get(5),
-                    mTransformMatrix->get(6), mTransformMatrix->get(7),
-                    mTransformMatrix->get(8));
             renderer.concatMatrix(mTransformMatrix);
         }
     }
     if (mAlpha < 1 && !mCaching) {
         if (!mHasOverlappingRendering) {
-            DISPLAY_LIST_LOGD("%s%s %.2f", indent, "SetAlpha", mAlpha);
             renderer.setAlpha(mAlpha);
         } else {
             // TODO: should be able to store the size of a DL at record time and not
@@ -861,53 +387,35 @@
             if (mClipChildren) {
                 flags |= SkCanvas::kClipToLayer_SaveFlag;
             }
-            DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", indent, "SaveLayerAlpha",
-                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
-                    mMultipliedAlpha, flags);
             renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
                     mMultipliedAlpha, flags);
         }
     }
     if (mClipChildren) {
-        DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f", indent, "ClipRect", 0.0f, 0.0f,
-                (float) mRight - mLeft, (float) mBottom - mTop);
         renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
                 SkRegion::kIntersect_Op);
     }
 }
 
-/**
- * Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
- * in the output() function, since that function processes the same list of opcodes for the
- * purposes of logging display list info for a given view.
- */
 status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
     status_t drawGlStatus = DrawGlInfo::kStatusDone;
-    TextContainer text;
-    mReader.rewind();
 
 #if DEBUG_DISPLAY_LIST
-    uint32_t count = (level + 1) * 2;
-    char indent[count + 1];
-    for (uint32_t i = 0; i < count; i++) {
-        indent[i] = ' ';
-    }
-    indent[count] = '\0';
     Rect* clipRect = renderer.getClipRect();
-    DISPLAY_LIST_LOGD("%sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
-            (char*) indent + 2, this, mName.string(), clipRect->left, clipRect->top,
+    DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
+            (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top,
             clipRect->right, clipRect->bottom);
 #endif
 
     renderer.startMark(mName.string());
 
     int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    DISPLAY_LIST_LOGD("%s%s %d %d", indent, "Save",
+    DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
     setViewProperties(renderer, level);
 
     if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
-        DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+        DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
         renderer.restoreToCount(restoreTo);
         renderer.endMark();
         return drawGlStatus;
@@ -915,469 +423,22 @@
 
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     int saveCount = renderer.getSaveCount() - 1;
-
-    while (!mReader.eof()) {
-        int op = mReader.readInt();
-        if (op & OP_MAY_BE_SKIPPED_MASK) {
-            int32_t skip = mReader.readInt();
-            if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
-                mReader.skip(skip);
-                DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
-                        OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
-                continue;
-            } else {
-                op &= ~OP_MAY_BE_SKIPPED_MASK;
-            }
-        }
-        logBuffer.writeCommand(level, op);
-
+    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+        DisplayListOp *op = mDisplayListData->displayListOps[i];
 #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        Caches::getInstance().eventMark(strlen(OP_NAMES[op]), OP_NAMES[op]);
+        Caches::getInstance().eventMark(strlen(op->name()), op->name());
 #endif
 
-        switch (op) {
-            case DrawGLFunction: {
-                Functor *functor = (Functor *) getInt();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
-                renderer.startMark("GL functor");
-                drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
-                renderer.endMark();
-            }
-            break;
-            case Save: {
-                int32_t rendererNum = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
-                renderer.save(rendererNum);
-            }
-            break;
-            case Restore: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.restore();
-            }
-            break;
-            case RestoreToCount: {
-                int32_t restoreCount = saveCount + getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
-                renderer.restoreToCount(restoreCount);
-            }
-            break;
-            case SaveLayer: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, paint, flags);
-                renderer.saveLayer(f1, f2, f3, f4, paint, flags);
-            }
-            break;
-            case SaveLayerAlpha: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int32_t alpha = getInt();
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
-                        OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
-                renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
-            }
-            break;
-            case Translate: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], f1, f2);
-                renderer.translate(f1, f2);
-            }
-            break;
-            case Rotate: {
-                float rotation = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f", (char*) indent, OP_NAMES[op], rotation);
-                renderer.rotate(rotation);
-            }
-            break;
-            case Scale: {
-                float sx = getFloat();
-                float sy = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-                renderer.scale(sx, sy);
-            }
-            break;
-            case Skew: {
-                float sx = getFloat();
-                float sy = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f", (char*) indent, OP_NAMES[op], sx, sy);
-                renderer.skew(sx, sy);
-            }
-            break;
-            case SetMatrix: {
-                SkMatrix* matrix = getMatrix();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], matrix);
-                renderer.setMatrix(matrix);
-            }
-            break;
-            case ConcatMatrix: {
-                SkMatrix* matrix = getMatrix();
-                DISPLAY_LIST_LOGD(
-                        "%s%s %p: [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f] [%.2f, %.2f, %.2f]",
-                        (char*) indent, OP_NAMES[op], matrix,
-                        matrix->get(0), matrix->get(1), matrix->get(2),
-                        matrix->get(3), matrix->get(4), matrix->get(5),
-                        matrix->get(6), matrix->get(7), matrix->get(8));
-                renderer.concatMatrix(matrix);
-            }
-            break;
-            case ClipRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, regionOp);
-                renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
-            }
-            break;
-            case ClipPath: {
-                SkPath* path = getPath();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-                renderer.clipPath(path, (SkRegion::Op) regionOp);
-            }
-            break;
-            case ClipRegion: {
-                SkRegion* region = getRegion();
-                int32_t regionOp = getInt();
-                DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], regionOp);
-                renderer.clipRegion(region, (SkRegion::Op) regionOp);
-            }
-            break;
-            case DrawDisplayList: {
-                DisplayList* displayList = getDisplayList();
-                int32_t flags = getInt();
-                DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
-                        displayList, mWidth, mHeight, flags, level + 1);
-                drawGlStatus |= renderer.drawDisplayList(displayList, dirty, flags, level + 1);
-            }
-            break;
-            case DrawLayer: {
-                int oldAlpha = -1;
-                Layer* layer = (Layer*) getInt();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                if (mCaching && mMultipliedAlpha < 255) {
-                    oldAlpha = layer->getAlpha();
-                    layer->setAlpha(mMultipliedAlpha);
-                }
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        layer, x, y, paint);
-                drawGlStatus |= renderer.drawLayer(layer, x, y, paint);
-                if (oldAlpha >= 0) {
-                    layer->setAlpha(oldAlpha);
-                }
-            }
-            break;
-            case DrawBitmap: {
-                int oldAlpha = -1;
-                SkBitmap* bitmap = getBitmap();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                if (mCaching && mMultipliedAlpha < 255) {
-                    oldAlpha = paint->getAlpha();
-                    paint->setAlpha(mMultipliedAlpha);
-                }
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
-                if (oldAlpha >= 0) {
-                    paint->setAlpha(oldAlpha);
-                }
-            }
-            break;
-            case DrawBitmapMatrix: {
-                SkBitmap* bitmap = getBitmap();
-                SkMatrix* matrix = getMatrix();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %p, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, matrix, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, matrix, paint);
-            }
-            break;
-            case DrawBitmapRect: {
-                SkBitmap* bitmap = getBitmap();
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                float f7 = getFloat();
-                float f8 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], bitmap,
-                        f1, f2, f3, f4, f5, f6, f7, f8,paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, f1, f2, f3, f4, f5, f6, f7, f8, paint);
-            }
-            break;
-            case DrawBitmapData: {
-                SkBitmap* bitmap = getBitmapData();
-                float x = getFloat();
-                float y = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        bitmap, x, y, paint);
-                drawGlStatus |= renderer.drawBitmap(bitmap, x, y, paint);
-            }
-            break;
-            case DrawBitmapMesh: {
-                int32_t verticesCount = 0;
-                uint32_t colorsCount = 0;
-
-                SkBitmap* bitmap = getBitmap();
-                uint32_t meshWidth = getInt();
-                uint32_t meshHeight = getInt();
-                float* vertices = getFloats(verticesCount);
-                bool hasColors = getInt();
-                int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
-                SkPaint* paint = getPaint(renderer);
-
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices,
-                        colors, paint);
-            }
-            break;
-            case DrawPatch: {
-                int32_t* xDivs = NULL;
-                int32_t* yDivs = NULL;
-                uint32_t* colors = NULL;
-                uint32_t xDivsCount = 0;
-                uint32_t yDivsCount = 0;
-                int8_t numColors = 0;
-
-                SkBitmap* bitmap = getBitmap();
-
-                xDivs = getInts(xDivsCount);
-                yDivs = getInts(yDivsCount);
-                colors = getUInts(numColors);
-
-                float left = getFloat();
-                float top = getFloat();
-                float right = getFloat();
-                float bottom = getFloat();
-
-                int alpha = getInt();
-                SkXfermode::Mode mode = (SkXfermode::Mode) getInt();
-
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawPatch(bitmap, xDivs, yDivs, colors,
-                        xDivsCount, yDivsCount, numColors, left, top, right, bottom,
-                        alpha, mode);
-            }
-            break;
-            case DrawColor: {
-                int32_t color = getInt();
-                int32_t xferMode = getInt();
-                DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
-                drawGlStatus |= renderer.drawColor(color, (SkXfermode::Mode) xferMode);
-            }
-            break;
-            case DrawRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
-                        f1, f2, f3, f4, paint);
-                drawGlStatus |= renderer.drawRect(f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawRoundRect: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, paint);
-                drawGlStatus |= renderer.drawRoundRect(f1, f2, f3, f4, f5, f6, paint);
-            }
-            break;
-            case DrawCircle: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, paint);
-                drawGlStatus |= renderer.drawCircle(f1, f2, f3, paint);
-            }
-            break;
-            case DrawOval: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint);
-                drawGlStatus |= renderer.drawOval(f1, f2, f3, f4, paint);
-            }
-            break;
-            case DrawArc: {
-                float f1 = getFloat();
-                float f2 = getFloat();
-                float f3 = getFloat();
-                float f4 = getFloat();
-                float f5 = getFloat();
-                float f6 = getFloat();
-                int32_t i1 = getInt();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
-                        (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
-                drawGlStatus |= renderer.drawArc(f1, f2, f3, f4, f5, f6, i1 == 1, paint);
-            }
-            break;
-            case DrawPath: {
-                SkPath* path = getPath();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %p, %p", (char*) indent, OP_NAMES[op], path, paint);
-                drawGlStatus |= renderer.drawPath(path, paint);
-            }
-            break;
-            case DrawLines: {
-                int32_t count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawLines(points, count, paint);
-            }
-            break;
-            case DrawPoints: {
-                int32_t count = 0;
-                float* points = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                drawGlStatus |= renderer.drawPoints(points, count, paint);
-            }
-            break;
-            case DrawTextOnPath: {
-                getText(&text);
-                int32_t count = getInt();
-                SkPath* path = getPath();
-                float hOffset = getFloat();
-                float vOffset = getFloat();
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op],
-                    text.text(), text.length(), count, paint);
-                drawGlStatus |= renderer.drawTextOnPath(text.text(), text.length(), count, path,
-                        hOffset, vOffset, paint);
-            }
-            break;
-            case DrawPosText: {
-                getText(&text);
-                int32_t count = getInt();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
-                        OP_NAMES[op], text.text(), text.length(), count, paint);
-                drawGlStatus |= renderer.drawPosText(text.text(), text.length(), count,
-                        positions, paint);
-            }
-            break;
-            case DrawText: {
-                getText(&text);
-                int32_t count = getInt();
-                float x = getFloat();
-                float y = getFloat();
-                int32_t positionsCount = 0;
-                float* positions = getFloats(positionsCount);
-                SkPaint* paint = getPaint(renderer);
-                float length = getFloat();
-                DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %.2f, %.2f, %p, %.2f", (char*) indent,
-                        OP_NAMES[op], text.text(), text.length(), count, x, y, paint, length);
-                drawGlStatus |= renderer.drawText(text.text(), text.length(), count,
-                        x, y, positions, paint, length);
-            }
-            break;
-            case DrawRects: {
-                int32_t count = 0;
-                float* rects = getFloats(count);
-                SkPaint* paint = getPaint(renderer);
-                DISPLAY_LIST_LOGD("%s%s %d, %p", (char*) indent, OP_NAMES[op], count, paint);
-                drawGlStatus |= renderer.drawRects(rects, count / 4, paint);
-            }
-            break;
-            case ResetShader: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetShader();
-            }
-            break;
-            case SetupShader: {
-                SkiaShader* shader = getShader();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], shader);
-                renderer.setupShader(shader);
-            }
-            break;
-            case ResetColorFilter: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetColorFilter();
-            }
-            break;
-            case SetupColorFilter: {
-                SkiaColorFilter *colorFilter = getColorFilter();
-                DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], colorFilter);
-                renderer.setupColorFilter(colorFilter);
-            }
-            break;
-            case ResetShadow: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetShadow();
-            }
-            break;
-            case SetupShadow: {
-                float radius = getFloat();
-                float dx = getFloat();
-                float dy = getFloat();
-                int32_t color = getInt();
-                DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
-                        radius, dx, dy, color);
-                renderer.setupShadow(radius, dx, dy, color);
-            }
-            break;
-            case ResetPaintFilter: {
-                DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
-                renderer.resetPaintFilter();
-            }
-            break;
-            case SetupPaintFilter: {
-                int32_t clearBits = getInt();
-                int32_t setBits = getInt();
-                DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
-                        clearBits, setBits);
-                renderer.setupPaintFilter(clearBits, setBits);
-            }
-            break;
-            default:
-                DISPLAY_LIST_LOGD("Display List error: op not handled: %s%s",
-                        (char*) indent, OP_NAMES[op]);
-                break;
-        }
+        drawGlStatus |= op->replay(renderer, dirty, flags,
+                saveCount, level, mCaching, mMultipliedAlpha);
+        logBuffer.writeCommand(level, op->name());
     }
 
-    DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+    DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
     renderer.restoreToCount(restoreTo);
     renderer.endMark();
 
-    DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
+    DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(),
             drawGlStatus);
     return drawGlStatus;
 }
@@ -1387,7 +448,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 DisplayListRenderer::DisplayListRenderer():
-        mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
+        mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
         mHasDrawOps(false), mFunctorCount(0) {
 }
@@ -1397,8 +458,7 @@
 }
 
 void DisplayListRenderer::reset() {
-    mWriter.reset();
-
+    mDisplayListData = new DisplayListData();
     mCaches.resourceCache.lock();
 
     for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -1493,7 +553,7 @@
 
 void DisplayListRenderer::finish() {
     insertRestoreToCount();
-    insertTranlate();
+    insertTranslate();
 }
 
 void DisplayListRenderer::interrupt() {
@@ -1504,15 +564,13 @@
 
 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
     // Ignore dirty during recording, it matters only when we replay
-    addOp(DisplayList::DrawGLFunction);
-    addInt((int) functor);
+    addDrawOp(new (alloc()) DrawFunctorOp(functor));
     mFunctorCount++;
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
 }
 
 int DisplayListRenderer::save(int flags) {
-    addOp(DisplayList::Save);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveOp(flags));
     return OpenGLRenderer::save(flags);
 }
 
@@ -1523,31 +581,25 @@
     }
 
     mRestoreSaveCount--;
-    insertTranlate();
+    insertTranslate();
     OpenGLRenderer::restore();
 }
 
 void DisplayListRenderer::restoreToCount(int saveCount) {
     mRestoreSaveCount = saveCount;
-    insertTranlate();
+    insertTranslate();
     OpenGLRenderer::restoreToCount(saveCount);
 }
 
 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
         SkPaint* p, int flags) {
-    addOp(DisplayList::SaveLayer);
-    addBounds(left, top, right, bottom);
-    addPaint(p);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, p, flags));
     return OpenGLRenderer::save(flags);
 }
 
 int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
         int alpha, int flags) {
-    addOp(DisplayList::SaveLayerAlpha);
-    addBounds(left, top, right, bottom);
-    addInt(alpha);
-    addInt(flags);
+    addStateOp(new (alloc()) SaveLayerAlphaOp(left, top, right, bottom, alpha, flags));
     return OpenGLRenderer::save(flags);
 }
 
@@ -1560,54 +612,47 @@
 }
 
 void DisplayListRenderer::rotate(float degrees) {
-    addOp(DisplayList::Rotate);
-    addFloat(degrees);
+    addStateOp(new (alloc()) RotateOp(degrees));
     OpenGLRenderer::rotate(degrees);
 }
 
 void DisplayListRenderer::scale(float sx, float sy) {
-    addOp(DisplayList::Scale);
-    addPoint(sx, sy);
+    addStateOp(new (alloc()) ScaleOp(sx, sy));
     OpenGLRenderer::scale(sx, sy);
 }
 
 void DisplayListRenderer::skew(float sx, float sy) {
-    addOp(DisplayList::Skew);
-    addPoint(sx, sy);
+    addStateOp(new (alloc()) SkewOp(sx, sy));
     OpenGLRenderer::skew(sx, sy);
 }
 
 void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
-    addOp(DisplayList::SetMatrix);
-    addMatrix(matrix);
+    matrix = refMatrix(matrix);
+    addStateOp(new (alloc()) SetMatrixOp(matrix));
     OpenGLRenderer::setMatrix(matrix);
 }
 
 void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
-    addOp(DisplayList::ConcatMatrix);
-    addMatrix(matrix);
+    matrix = refMatrix(matrix);
+    addStateOp(new (alloc()) ConcatMatrixOp(matrix));
     OpenGLRenderer::concatMatrix(matrix);
 }
 
 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
         SkRegion::Op op) {
-    addOp(DisplayList::ClipRect);
-    addBounds(left, top, right, bottom);
-    addInt(op);
+    addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
 }
 
 bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
-    addOp(DisplayList::ClipPath);
-    addPath(path);
-    addInt(op);
+    path = refPath(path);
+    addStateOp(new (alloc()) ClipPathOp(path, op));
     return OpenGLRenderer::clipPath(path, op);
 }
 
 bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
-    addOp(DisplayList::ClipRegion);
-    addRegion(region);
-    addInt(op);
+    region = refRegion(region);
+    addStateOp(new (alloc()) ClipRegionOp(region, op));
     return OpenGLRenderer::clipRegion(region, op);
 }
 
@@ -1616,84 +661,71 @@
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
 
-    addOp(DisplayList::DrawDisplayList);
-    addDisplayList(displayList);
-    addInt(flags);
+    // TODO: To be safe, the display list should be ref-counted in the
+    //       resources cache, but we rely on the caller (UI toolkit) to
+    //       do the right thing for now
+
+    addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
-    addOp(DisplayList::DrawLayer);
-    addLayer(layer);
-    addPoint(x, y);
-    addPaint(paint);
+    mLayers.add(layer);
+    mCaches.resourceCache.incrementRefcount(layer);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawLayerOp(layer, x, y, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(left, top,
-            left + bitmap->width(), top + bitmap->height());
-    uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
-    addBitmap(bitmap);
-    addPoint(left, top);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
-    Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
-    const mat4 transform(*matrix);
-    transform.mapRect(r);
+    bitmap = refBitmap(bitmap);
+    matrix = refMatrix(matrix);
+    paint = refPaint(paint);
 
-    const bool reject = quickRejectNoScissor(r.left, r.top, r.right, r.bottom);
-    uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
-    addBitmap(bitmap);
-    addMatrix(matrix);
-    addPaint(paint);
-    addSkip(location);
+    addDrawOp(new (alloc()) DrawBitmapMatrixOp(bitmap, matrix, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
         float dstRight, float dstBottom, SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(dstLeft, dstTop, dstRight, dstBottom);
-    uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
-    addBitmap(bitmap);
-    addBounds(srcLeft, srcTop, srcRight, srcBottom);
-    addBounds(dstLeft, dstTop, dstRight, dstBottom);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapRectOp(bitmap,
+                    srcLeft, srcTop, srcRight, srcBottom,
+                    dstLeft, dstTop, dstRight, dstBottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
-    const bool reject = quickRejectNoScissor(left, top,
-            left + bitmap->width(), top + bitmap->height());
-    uint32_t* location = addOp(DisplayList::DrawBitmapData, reject);
-    addBitmapData(bitmap);
-    addPoint(left, top);
-    addPaint(paint);
-    addSkip(location);
+    bitmap = refBitmapData(bitmap);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawBitmapDataOp(bitmap, left, top, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
         float* vertices, int* colors, SkPaint* paint) {
-    addOp(DisplayList::DrawBitmapMesh);
-    addBitmap(bitmap);
-    addInt(meshWidth);
-    addInt(meshHeight);
-    addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
-    if (colors) {
-        addInt(1);
-        addInts(colors, (meshWidth + 1) * (meshHeight + 1));
-    } else {
-        addInt(0);
-    }
-    addPaint(paint);
+    int count = (meshWidth + 1) * (meshHeight + 1) * 2;
+    bitmap = refBitmap(bitmap);
+    vertices = refBuffer<float>(vertices, count);
+    paint = refPaint(paint);
+    colors = refBuffer<int>(colors, count);
+
+    addDrawOp(new (alloc()) DrawBitmapMeshOp(bitmap, meshWidth, meshHeight,
+                    vertices, colors, paint));
     return DrawGlInfo::kStatusDone;
 }
 
@@ -1704,132 +736,114 @@
     SkXfermode::Mode mode;
     OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
 
-    const bool reject = quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawPatch, reject);
-    addBitmap(bitmap);
-    addInts(xDivs, width);
-    addInts(yDivs, height);
-    addUInts(colors, numColors);
-    addBounds(left, top, right, bottom);
-    addInt(alpha);
-    addInt(mode);
-    addSkip(location);
+    bitmap = refBitmap(bitmap);
+    xDivs = refBuffer<int>(xDivs, width);
+    yDivs = refBuffer<int>(yDivs, height);
+    colors = refBuffer<uint32_t>(colors, numColors);
+
+    addDrawOp(new (alloc()) DrawPatchOp(bitmap, xDivs, yDivs, colors, width, height, numColors,
+                    left, top, right, bottom, alpha, mode));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
-    addOp(DisplayList::DrawColor);
-    addInt(color);
-    addInt(mode);
+    addDrawOp(new (alloc()) DrawColorOp(color, mode));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
         SkPaint* paint) {
-    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawRect, reject);
-    addBounds(left, top, right, bottom);
-    addPaint(paint);
-    addSkip(location);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
         float rx, float ry, SkPaint* paint) {
-    const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
-            quickRejectNoScissor(left, top, right, bottom);
-    uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
-    addBounds(left, top, right, bottom);
-    addPoint(rx, ry);
-    addPaint(paint);
-    addSkip(location);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
-    addOp(DisplayList::DrawCircle);
-    addPoint(x, y);
-    addFloat(radius);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
         SkPaint* paint) {
-    addOp(DisplayList::DrawOval);
-    addBounds(left, top, right, bottom);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
-    addOp(DisplayList::DrawArc);
-    addBounds(left, top, right, bottom);
-    addPoint(startAngle, sweepAngle);
-    addInt(useCenter ? 1 : 0);
-    addPaint(paint);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
+                    startAngle, sweepAngle, useCenter, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    float left, top, offset;
-    uint32_t width, height;
-    computePathBounds(path, paint, left, top, offset, width, height);
+    path = refPath(path);
+    paint = refPaint(paint);
 
-    left -= offset;
-    top -= offset;
-
-    const bool reject = quickRejectNoScissor(left, top, left + width, top + height);
-    uint32_t* location = addOp(DisplayList::DrawPath, reject);
-    addPath(path);
-    addPaint(paint);
-    addSkip(location);
+    addDrawOp(new (alloc()) DrawPathOp(path, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    addOp(DisplayList::DrawLines);
-    addFloats(points, count);
-    addPaint(paint);
+    points = refBuffer<float>(points, count);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawLinesOp(points, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    addOp(DisplayList::DrawPoints);
-    addFloats(points, count);
-    addPaint(paint);
+    points = refBuffer<float>(points, count);
+    paint = refPaint(paint);
+
+    addDrawOp(new (alloc()) DrawPointsOp(points, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
         SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
-    addOp(DisplayList::DrawTextOnPath);
-    addText(text, bytesCount);
-    addInt(count);
-    addPath(path);
-    addFloat(hOffset);
-    addFloat(vOffset);
+
     paint->setAntiAlias(true);
-    SkPaint* addedPaint = addPaint(paint);
-    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-    fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    text = refText(text, bytesCount);
+    path = refPath(path);
+    paint = refPaint(paint);
+
+    DrawOp* op = new (alloc()) DrawTextOnPathOp(text, bytesCount, count, path,
+            hOffset, vOffset, paint);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
+    }
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
         const float* positions, SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
-    addOp(DisplayList::DrawPosText);
-    addText(text, bytesCount);
-    addInt(count);
-    addFloats(positions, count * 2);
+
     paint->setAntiAlias(true);
-    SkPaint* addedPaint = addPaint(paint);
-    FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-    fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    text = refText(text, bytesCount);
+    positions = refBuffer<float>(positions, count * 2);
+    paint = refPaint(paint);
+
+    DrawOp* op = new (alloc()) DrawPosTextOp(text, bytesCount, count, positions, paint);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
+    }
     return DrawGlInfo::kStatusDone;
 }
 
@@ -1847,75 +861,96 @@
     paint->setAntiAlias(true);
     if (length < 0.0f) length = paint->measureText(text, bytesCount);
 
-    bool reject = false;
-    if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
-        SkPaint::FontMetrics metrics;
-        paint->getFontMetrics(&metrics, 0.0f);
-        reject = quickRejectNoScissor(x, y + metrics.fTop, x + length, y + metrics.fBottom);
-    }
+    text = refText(text, bytesCount);
+    positions = refBuffer<float>(positions, count * 2);
+    paint = refPaint(paint);
 
-    uint32_t* location = addOp(DisplayList::DrawText, reject);
-    addText(text, bytesCount);
-    addInt(count);
-    addFloat(x);
-    addFloat(y);
-    addFloats(positions, count * 2);
-    SkPaint* addedPaint = addPaint(paint);
-    if (!reject) {
-        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(addedPaint);
-        fontRenderer.precache(addedPaint, text, count, *mSnapshot->transform);
+    DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count, x, y, positions, paint, length);
+    if (addDrawOp(op)) {
+        // precache if draw operation is visible
+        FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
+        fontRenderer.precache(paint, text, count, *mSnapshot->transform);
     }
-    addFloat(length);
-    addSkip(location);
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
     if (count <= 0) return DrawGlInfo::kStatusDone;
 
-    addOp(DisplayList::DrawRects);
-    addFloats(rects, count * 4);
-    addPaint(paint);
+    rects = refBuffer<float>(rects, count);
+    paint = refPaint(paint);
+    addDrawOp(new (alloc()) DrawRectsOp(rects, count, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 void DisplayListRenderer::resetShader() {
-    addOp(DisplayList::ResetShader);
+    addStateOp(new (alloc()) ResetShaderOp());
 }
 
 void DisplayListRenderer::setupShader(SkiaShader* shader) {
-    addOp(DisplayList::SetupShader);
-    addShader(shader);
+    shader = refShader(shader);
+    addStateOp(new (alloc()) SetupShaderOp(shader));
 }
 
 void DisplayListRenderer::resetColorFilter() {
-    addOp(DisplayList::ResetColorFilter);
+    addStateOp(new (alloc()) ResetColorFilterOp());
 }
 
 void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
-    addOp(DisplayList::SetupColorFilter);
-    addColorFilter(filter);
+    filter = refColorFilter(filter);
+    addStateOp(new (alloc()) SetupColorFilterOp(filter));
 }
 
 void DisplayListRenderer::resetShadow() {
-    addOp(DisplayList::ResetShadow);
+    addStateOp(new (alloc()) ResetShadowOp());
 }
 
 void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
-    addOp(DisplayList::SetupShadow);
-    addFloat(radius);
-    addPoint(dx, dy);
-    addInt(color);
+    addStateOp(new (alloc()) SetupShadowOp(radius, dx, dy, color));
 }
 
 void DisplayListRenderer::resetPaintFilter() {
-    addOp(DisplayList::ResetPaintFilter);
+    addStateOp(new (alloc()) ResetPaintFilterOp());
 }
 
 void DisplayListRenderer::setupPaintFilter(int clearBits, int setBits) {
-    addOp(DisplayList::SetupPaintFilter);
-    addInt(clearBits);
-    addInt(setBits);
+    addStateOp(new (alloc()) SetupPaintFilterOp(clearBits, setBits));
+}
+
+void DisplayListRenderer::insertRestoreToCount() {
+    if (mRestoreSaveCount >= 0) {
+        DisplayListOp* op = new (alloc()) RestoreToCountOp(mRestoreSaveCount);
+        mDisplayListData->displayListOps.add(op);
+        mRestoreSaveCount = -1;
+    }
+}
+
+void DisplayListRenderer::insertTranslate() {
+    if (mHasTranslate) {
+        if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
+            DisplayListOp* op = new (alloc()) TranslateOp(mTranslateX, mTranslateY);
+            mDisplayListData->displayListOps.add(op);
+            mTranslateX = mTranslateY = 0.0f;
+        }
+        mHasTranslate = false;
+    }
+}
+
+void DisplayListRenderer::addStateOp(StateOp* op) {
+    addOpInternal(op);
+}
+
+bool DisplayListRenderer::addDrawOp(DrawOp* op) {
+    bool rejected = false;
+    Rect localBounds;
+    if (op->getLocalBounds(localBounds)) {
+        rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
+                localBounds.right, localBounds.bottom);
+        op->setQuickRejected(rejected);
+    }
+    mHasDrawOps = true;
+    addOpInternal(op);
+    return !rejected;
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index f55f1f2..b25288b 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -31,6 +31,7 @@
 
 #include "DisplayListLogBuffer.h"
 #include "OpenGLRenderer.h"
+#include "utils/LinearAllocator.h"
 
 namespace android {
 namespace uirenderer {
@@ -60,6 +61,18 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class DisplayListRenderer;
+class DisplayListOp;
+class DrawOp;
+class StateOp;
+
+/**
+ * Refcounted structure that holds data used in display list stream
+ */
+class DisplayListData: public LightRefBase<DisplayListData> {
+public:
+    LinearAllocator allocator;
+    Vector<DisplayListOp*> displayListOps;
+};
 
 /**
  * Replays recorded drawing commands.
@@ -69,66 +82,13 @@
     DisplayList(const DisplayListRenderer& recorder);
     ANDROID_API ~DisplayList();
 
-    // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
-    //            when modifying this file
-    enum Op {
-        // Non-drawing operations
-        Save = 0,
-        Restore,
-        RestoreToCount,
-        SaveLayer,
-        SaveLayerAlpha,
-        Translate,
-        Rotate,
-        Scale,
-        Skew,
-        SetMatrix,
-        ConcatMatrix,
-        ClipRect,
-        ClipPath,
-        ClipRegion,
-        // Drawing operations
-        DrawDisplayList,
-        DrawLayer,
-        DrawBitmap,
-        DrawBitmapMatrix,
-        DrawBitmapRect,
-        DrawBitmapData,
-        DrawBitmapMesh,
-        DrawPatch,
-        DrawColor,
-        DrawRect,
-        DrawRoundRect,
-        DrawCircle,
-        DrawOval,
-        DrawArc,
-        DrawPath,
-        DrawLines,
-        DrawPoints,
-        DrawTextOnPath,
-        DrawPosText,
-        DrawText,
-        DrawRects,
-        ResetShader,
-        SetupShader,
-        ResetColorFilter,
-        SetupColorFilter,
-        ResetShadow,
-        SetupShadow,
-        ResetPaintFilter,
-        SetupPaintFilter,
-        DrawGLFunction,
-    };
-
     // See flags defined in DisplayList.java
     enum ReplayFlag {
         kReplayFlag_ClipChildren = 0x1
     };
 
-    static const char* OP_NAMES[];
-
     void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
-    void outputViewProperties(OpenGLRenderer& renderer, char* indent);
+    void outputViewProperties(uint32_t level);
 
     ANDROID_API size_t getSize();
     ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
@@ -138,7 +98,7 @@
 
     status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
 
-    void output(OpenGLRenderer& renderer, uint32_t level = 0);
+    void output(uint32_t level = 0);
 
     ANDROID_API void reset();
 
@@ -423,78 +383,6 @@
         const char* mText;
     };
 
-    SkBitmap* getBitmap() {
-        return (SkBitmap*) getInt();
-    }
-
-    SkBitmap* getBitmapData() {
-        return (SkBitmap*) getInt();
-    }
-
-    SkiaShader* getShader() {
-        return (SkiaShader*) getInt();
-    }
-
-    SkiaColorFilter* getColorFilter() {
-        return (SkiaColorFilter*) getInt();
-    }
-
-    inline int32_t getIndex() {
-        return mReader.readInt();
-    }
-
-    inline int32_t getInt() {
-        return mReader.readInt();
-    }
-
-    inline uint32_t getUInt() {
-        return mReader.readU32();
-    }
-
-    SkMatrix* getMatrix() {
-        return (SkMatrix*) getInt();
-    }
-
-    SkPath* getPath() {
-        return (SkPath*) getInt();
-    }
-
-    SkRegion* getRegion() {
-        return (SkRegion*) getInt();
-    }
-
-    SkPaint* getPaint(OpenGLRenderer& renderer) {
-        return renderer.filterPaint((SkPaint*) getInt());
-    }
-
-    DisplayList* getDisplayList() {
-        return (DisplayList*) getInt();
-    }
-
-    inline float getFloat() {
-        return mReader.readScalar();
-    }
-
-    int32_t* getInts(uint32_t& count) {
-        count = getInt();
-        return (int32_t*) mReader.skip(count * sizeof(int32_t));
-    }
-
-    uint32_t* getUInts(int8_t& count) {
-        count = getInt();
-        return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
-    }
-
-    float* getFloats(int32_t& count) {
-        count = getInt();
-        return (float*) mReader.skip(count * sizeof(float));
-    }
-
-    void getText(TextContainer* text) {
-        size_t length = text->mByteLength = getInt();
-        text->mText = (const char*) mReader.skip(length);
-    }
-
     Vector<SkBitmap*> mBitmapResources;
     Vector<SkBitmap*> mOwnedBitmapResources;
     Vector<SkiaColorFilter*> mFilterResources;
@@ -507,7 +395,7 @@
     Vector<SkiaShader*> mShaders;
     Vector<Layer*> mLayers;
 
-    mutable SkFlattenableReadBuffer mReader;
+    sp<DisplayListData> mDisplayListData;
 
     size_t mSize;
 
@@ -634,8 +522,8 @@
 
     ANDROID_API void reset();
 
-    const SkWriter32& writeStream() const {
-        return mWriter;
+    sp<DisplayListData> getDisplayListData() const {
+        return mDisplayListData;
     }
 
     const Vector<SkBitmap*>& getBitmapResources() const {
@@ -683,102 +571,32 @@
     }
 
 private:
-    void insertRestoreToCount() {
-        if (mRestoreSaveCount >= 0) {
-            mWriter.writeInt(DisplayList::RestoreToCount);
-            addInt(mRestoreSaveCount);
-            mRestoreSaveCount = -1;
-        }
-    }
+    void insertRestoreToCount();
+    void insertTranslate();
 
-    void insertTranlate() {
-        if (mHasTranslate) {
-            if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
-                mWriter.writeInt(DisplayList::Translate);
-                addPoint(mTranslateX, mTranslateY);
-                mTranslateX = mTranslateY = 0.0f;
-            }
-            mHasTranslate = false;
-        }
-    }
-
-    inline void addOp(const DisplayList::Op drawOp) {
+    LinearAllocator& alloc() { return mDisplayListData->allocator; }
+    void addStateOp(StateOp* op);
+    bool addDrawOp(DrawOp* op); // returns true if op not rejected
+    void addOpInternal(DisplayListOp* op) {
         insertRestoreToCount();
-        insertTranlate();
-        mWriter.writeInt(drawOp);
-        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
+        insertTranslate();
+        mDisplayListData->displayListOps.add(op);
     }
 
-    uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
-        insertRestoreToCount();
-        insertTranlate();
-        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
-        if (reject) {
-            mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
-            mWriter.writeInt(0xdeaddead);
-            mBufferSize = mWriter.size();
-            return mWriter.peek32(mBufferSize - sizeof(int32_t));
-        }
-        mWriter.writeInt(drawOp);
-        return NULL;
+    template<class T>
+    inline T* refBuffer(const T* srcBuffer, int32_t count) {
+        if (srcBuffer == NULL) return NULL;
+        T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
+        memcpy(dstBuffer, srcBuffer, count * sizeof(T));
+        return dstBuffer;
     }
 
-    inline void addSkip(uint32_t* location) {
-        if (location) {
-            *location = (int32_t) (mWriter.size() - mBufferSize);
-        }
+    inline char* refText(const char* text, size_t byteLength) {
+        return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
     }
 
-    inline void addInt(int32_t value) {
-        mWriter.writeInt(value);
-    }
-
-    inline void addSize(uint32_t w, uint32_t h) {
-        mWriter.writeInt(w);
-        mWriter.writeInt(h);
-    }
-
-    void addInts(const int32_t* values, uint32_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(int32_t));
-    }
-
-    void addUInts(const uint32_t* values, int8_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(uint32_t));
-    }
-
-    inline void addFloat(float value) {
-        mWriter.writeScalar(value);
-    }
-
-    void addFloats(const float* values, int32_t count) {
-        mWriter.writeInt(count);
-        mWriter.write(values, count * sizeof(float));
-    }
-
-    inline void addPoint(float x, float y) {
-        mWriter.writeScalar(x);
-        mWriter.writeScalar(y);
-    }
-
-    inline void addBounds(float left, float top, float right, float bottom) {
-        mWriter.writeScalar(left);
-        mWriter.writeScalar(top);
-        mWriter.writeScalar(right);
-        mWriter.writeScalar(bottom);
-    }
-
-    inline void addText(const void* text, size_t byteLength) {
-        mWriter.writeInt(byteLength);
-        mWriter.writePad(text, byteLength);
-    }
-
-    inline void addPath(SkPath* path) {
-        if (!path) {
-            addInt((int) NULL);
-            return;
-        }
+    inline SkPath* refPath(SkPath* path) {
+        if (!path) return NULL;
 
         SkPath* pathCopy = mPathMap.valueFor(path);
         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
@@ -792,13 +610,11 @@
             mCaches.resourceCache.incrementRefcount(path);
             mSourcePaths.add(path);
         }
-
-        addInt((int) pathCopy);
+        return pathCopy;
     }
 
-    inline SkPaint* addPaint(SkPaint* paint) {
+    inline SkPaint* refPaint(SkPaint* paint) {
         if (!paint) {
-            addInt((int) NULL);
             return paint;
         }
 
@@ -810,14 +626,11 @@
             mPaints.add(paintCopy);
         }
 
-        addInt((int) paintCopy);
-
         return paintCopy;
     }
 
-    inline SkRegion* addRegion(SkRegion* region) {
+    inline SkRegion* refRegion(SkRegion* region) {
         if (!region) {
-            addInt((int) NULL);
             return region;
         }
 
@@ -830,53 +643,35 @@
             mRegions.add(regionCopy);
         }
 
-        addInt((int) regionCopy);
-
         return regionCopy;
     }
 
-    inline void addDisplayList(DisplayList* displayList) {
-        // TODO: To be safe, the display list should be ref-counted in the
-        //       resources cache, but we rely on the caller (UI toolkit) to
-        //       do the right thing for now
-        addInt((int) displayList);
-    }
-
-    inline void addMatrix(SkMatrix* matrix) {
+    inline SkMatrix* refMatrix(SkMatrix* matrix) {
         // Copying the matrix is cheap and prevents against the user changing the original
         // matrix before the operation that uses it
         SkMatrix* copy = new SkMatrix(*matrix);
-        addInt((int) copy);
         mMatrices.add(copy);
+        return copy;
     }
 
-    inline void addLayer(Layer* layer) {
-        addInt((int) layer);
-        mLayers.add(layer);
-        mCaches.resourceCache.incrementRefcount(layer);
-    }
-
-    inline void addBitmap(SkBitmap* bitmap) {
+    inline SkBitmap* refBitmap(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.
-        addInt((int) bitmap);
         mBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
+        return bitmap;
     }
 
-    void addBitmapData(SkBitmap* bitmap) {
-        addInt((int) bitmap);
+    inline SkBitmap* refBitmapData(SkBitmap* bitmap) {
         mOwnedBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
+        return bitmap;
     }
 
-    inline void addShader(SkiaShader* shader) {
-        if (!shader) {
-            addInt((int) NULL);
-            return;
-        }
+    inline SkiaShader* refShader(SkiaShader* shader) {
+        if (!shader) return NULL;
 
         SkiaShader* shaderCopy = mShaderMap.valueFor(shader);
         // TODO: We also need to handle generation ID changes in compose shaders
@@ -887,14 +682,13 @@
             mShaders.add(shaderCopy);
             mCaches.resourceCache.incrementRefcount(shaderCopy);
         }
-
-        addInt((int) shaderCopy);
+        return shaderCopy;
     }
 
-    inline void addColorFilter(SkiaColorFilter* colorFilter) {
-        addInt((int) colorFilter);
+    inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) {
         mFilterResources.add(colorFilter);
         mCaches.resourceCache.incrementRefcount(colorFilter);
+        return colorFilter;
     }
 
     Vector<SkBitmap*> mBitmapResources;
@@ -919,12 +713,10 @@
 
     Vector<Layer*> mLayers;
 
-    uint32_t mBufferSize;
-
     int mRestoreSaveCount;
 
     Caches& mCaches;
-    SkWriter32 mWriter;
+    sp<DisplayListData> mDisplayListData;
 
     float mTranslateX;
     float mTranslateY;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index f55bc9d..c9e51bb 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1096,7 +1096,7 @@
         rects.push(r.fTop);
         rects.push(r.fRight);
         rects.push(r.fBottom);
-        count++;
+        count += 4;
         it.next();
     }
 
@@ -1732,7 +1732,7 @@
 
 void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) {
     if (displayList) {
-        displayList->output(*this, level);
+        displayList->output(level);
     }
 }
 
@@ -2082,7 +2082,6 @@
  */
 void OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
     int color = paint->getColor();
-    SkPaint::Style style = paint->getStyle();
     SkXfermode::Mode mode = getXfermode(paint->getXfermode());
     bool isAA = paint->isAntiAlias();
 
@@ -3193,8 +3192,7 @@
     Vertex mesh[count * 6];
     Vertex* vertex = mesh;
 
-    for (int i = 0; i < count; i++) {
-        int index = i * 4;
+    for (int index = 0; index < count; index += 4) {
         float l = rects[index + 0];
         float t = rects[index + 1];
         float r = rects[index + 2];
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index e490151..45c619e 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -122,8 +122,6 @@
     float rescaleX = 1.0f;
     float rescaleY = 1.0f;
 
-    const float meshWidth = right - left;
-
     if (xStretchCount > 0) {
         uint32_t stretchSize = 0;
         for (uint32_t i = 1; i < mXCount; i += 2) {
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
index dd13d79..d59e36f 100644
--- a/libs/hwui/PathRenderer.cpp
+++ b/libs/hwui/PathRenderer.cpp
@@ -596,7 +596,6 @@
     SkPath::Iter iter(path, forceClose);
     SkPoint pts[4];
     SkPath::Verb v;
-    Vertex* newVertex = 0;
     while (SkPath::kDone_Verb != (v = iter.next(pts))) {
             switch (v) {
                 case SkPath::kMove_Verb:
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 80f39ff90..5f4bb5a 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -171,22 +171,19 @@
     }
 
 private:
-    static inline float min(float a, float b) { return (a < b) ? a : b; }
-    static inline float max(float a, float b) { return (a > b) ? a : b; }
-
     void intersectWith(Rect& tmp) const {
-        tmp.left = max(left, tmp.left);
-        tmp.top = max(top, tmp.top);
-        tmp.right = min(right, tmp.right);
-        tmp.bottom = min(bottom, tmp.bottom);
+        tmp.left = fmaxf(left, tmp.left);
+        tmp.top = fmaxf(top, tmp.top);
+        tmp.right = fminf(right, tmp.right);
+        tmp.bottom = fminf(bottom, tmp.bottom);
     }
 
     Rect intersectWith(float l, float t, float r, float b) const {
         Rect tmp;
-        tmp.left = max(left, l);
-        tmp.top = max(top, t);
-        tmp.right = min(right, r);
-        tmp.bottom = min(bottom, b);
+        tmp.left = fmaxf(left, l);
+        tmp.top = fmaxf(top, t);
+        tmp.right = fminf(right, r);
+        tmp.bottom = fminf(bottom, b);
         return tmp;
     }
 
