Optimize display lists

Remove redundant or useless operations

Change-Id: If989b4eaa9143eef4254c38b39959aeed1f2b9ab
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 88cfc5a..cedf456 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -194,6 +194,7 @@
 
 void DisplayList::init() {
     mSize = 0;
+    mIsRenderable = true;
 }
 
 size_t DisplayList::getSize() {
@@ -892,7 +893,7 @@
 // Base structure
 ///////////////////////////////////////////////////////////////////////////////
 
-DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
+DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
 }
 
 DisplayListRenderer::~DisplayListRenderer() {
@@ -926,6 +927,8 @@
     mPathMap.clear();
 
     mMatrices.clear();
+
+    mHasDrawOps = false;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -938,6 +941,7 @@
     } else {
         displayList->initFromDisplayListRenderer(*this, true);
     }
+    displayList->setRenderable(mHasDrawOps);
     return displayList;
 }
 
@@ -982,7 +986,11 @@
 }
 
 void DisplayListRenderer::restore() {
-    addOp(DisplayList::Restore);
+    if (mRestoreSaveCount < 0) {
+        addOp(DisplayList::Restore);
+    } else {
+        mRestoreSaveCount--;
+    }
     OpenGLRenderer::restore();
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 69e72a4..8cd7fea 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -63,6 +63,7 @@
     // IMPORTANT: Update the intialization of OP_NAMES in the .cpp file
     //            when modifying this file
     enum Op {
+        // Non-drawing operations
         Save = 0,
         Restore,
         RestoreToCount,
@@ -75,6 +76,7 @@
         SetMatrix,
         ConcatMatrix,
         ClipRect,
+        // Drawing operations
         DrawDisplayList,
         DrawLayer,
         DrawBitmap,
@@ -113,6 +115,14 @@
 
     static void outputLogBuffer(int fd);
 
+    void setRenderable(bool renderable) {
+        mIsRenderable = renderable;
+    }
+
+    bool isRenderable() const {
+        return mIsRenderable;
+    }
+
 private:
     void init();
 
@@ -207,6 +217,8 @@
     mutable SkFlattenableReadBuffer mReader;
 
     size_t mSize;
+
+    bool mIsRenderable;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -328,6 +340,7 @@
     inline void addOp(DisplayList::Op drawOp) {
         insertRestoreToCount();
         mWriter.writeInt(drawOp);
+        mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
     }
 
     inline void addInt(int value) {
@@ -479,6 +492,7 @@
     SkWriter32 mWriter;
 
     int mRestoreSaveCount;
+    bool mHasDrawOps;
 
     friend class DisplayList;
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 04f3c58..a20a88e 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1278,7 +1278,7 @@
 
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
     // will be performed by the display list itself
-    if (displayList) {
+    if (displayList && displayList->isRenderable()) {
         return displayList->replay(*this, dirty, level);
     }