Support nested display lists.

Change-Id: I3815a2832fc0f722c668ba8f51c5f177edb77c94
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 23ccef6..770e596 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -226,6 +226,10 @@
                         (SkRegion::Op) getInt());
             }
             break;
+            case DrawDisplayList: {
+                renderer.drawDisplayList(getDisplayList());
+            }
+            break;
             case DrawBitmap: {
                 renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
             }
@@ -453,6 +457,11 @@
     return OpenGLRenderer::clipRect(left, top, right, bottom, op);
 }
 
+void DisplayListRenderer::drawDisplayList(DisplayList* displayList) {
+    addOp(DisplayList::DrawDisplayList);
+    addDisplayList(displayList);
+}
+
 void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
     addOp(DisplayList::DrawBitmap);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index fd69fab..b608381 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -92,6 +92,7 @@
         SetMatrix,
         ConcatMatrix,
         ClipRect,
+        DrawDisplayList,
         DrawBitmap,
         DrawBitmapMatrix,
         DrawBitmapRect,
@@ -160,6 +161,10 @@
         return (SkPaint*) getInt();
     }
 
+    DisplayList* getDisplayList() {
+        return (DisplayList*) getInt();
+    }
+
     inline float getFloat() {
         return mReader.readScalar();
     }
@@ -235,6 +240,7 @@
 
     bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
 
+    void drawDisplayList(DisplayList* displayList);
     void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
@@ -348,16 +354,25 @@
 
     inline void addPaint(SkPaint* paint) {
         if (paint == NULL) {
-            addInt((int)NULL);
+            addInt((int) NULL);
             return;
         }
+
         SkPaint *paintCopy =  mPaintMap.valueFor(paint);
         if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
             paintCopy = new SkPaint(*paint);
             mPaintMap.add(paint, paintCopy);
             mPaints.add(paintCopy);
         }
-        addInt((int)paintCopy);
+
+        addInt((int) paintCopy);
+    }
+
+    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) {
@@ -371,21 +386,21 @@
         // 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);
+        addInt((int) bitmap);
         mBitmapResources.add(bitmap);
         Caches& caches = Caches::getInstance();
         caches.resourceCache.incrementRefcount(bitmap);
     }
 
     inline void addShader(SkiaShader* shader) {
-        addInt((int)shader);
+        addInt((int) shader);
         mShaderResources.add(shader);
         Caches& caches = Caches::getInstance();
         caches.resourceCache.incrementRefcount(shader);
     }
 
     inline void addColorFilter(SkiaColorFilter* colorFilter) {
-        addInt((int)colorFilter);
+        addInt((int) colorFilter);
         mFilterResources.add(colorFilter);
         Caches& caches = Caches::getInstance();
         caches.resourceCache.incrementRefcount(colorFilter);
@@ -398,7 +413,7 @@
     Vector<SkiaColorFilter*> mFilterResources;
 
     Vector<SkPaint*> mPaints;
-    DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;
+    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
     Vector<SkMatrix*> mMatrices;
 
     PathHeap* mPathHeap;
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
index fe75ca2..1cf3d20 100644
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -48,6 +48,12 @@
     return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
 }
 
+void OpenGLDebugRenderer::drawDisplayList(DisplayList* displayList) {
+    mPrimitivesCount++;
+    StopWatch w("drawDisplayList");
+    OpenGLRenderer::drawDisplayList(displayList);
+}
+
 void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
         SkPaint* paint) {
     mPrimitivesCount++;
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index 7787ff1..ee34d73 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -40,6 +40,7 @@
     int saveLayer(float left, float top, float right, float bottom,
             SkPaint* p, int flags);
 
+    void drawDisplayList(DisplayList* displayList);
     void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
     void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cad991d..9a6618b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -29,6 +29,7 @@
 #include <ui/Rect.h>
 
 #include "OpenGLRenderer.h"
+#include "DisplayListRenderer.h"
 
 namespace android {
 namespace uirenderer {
@@ -827,6 +828,14 @@
 // Drawing
 ///////////////////////////////////////////////////////////////////////////////
 
+void OpenGLRenderer::drawDisplayList(DisplayList* displayList) {
+    // All the usual checks and setup operations (quickReject, setupDraw, etc.)
+    // will be performed by the display list itself
+    if (displayList) {
+        displayList->replay(*this);
+    }
+}
+
 void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 93c2e6c..3340b4a 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -58,7 +58,7 @@
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
 
-class DisplayListRenderer;
+class DisplayList;
 
 /**
  * OpenGL renderer used to draw accelerated 2D graphics. The API is a
@@ -100,6 +100,7 @@
     bool quickReject(float left, float top, float right, float bottom);
     virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
 
+    virtual void drawDisplayList(DisplayList* displayList);
     virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
     virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
     virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,