Fully deferred displaylist replay

bug:8037003

A recursive drawDisplayList call is now entirely deferred before
playing back to the screen and issuing GL commands. This way, the
entire stream can be inspected, optimized, and batch work (such as
uploading textures) before issuing commands.

Additionally, this fixes an issue where operations draw could move
across restores corresponding to saveLayer(alpha). Those and other
similar cases (such as complex clipping, requiring the stencil) are
now treated as batching barriers, with the operations that change
renderer state in a way that's difficult to defer are just re-issued
at flush time.

Change-Id: Ie7348166662a5ad89fb9b1e87558334fb826b01e
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e961af2..e6c636c 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -65,6 +65,11 @@
     int mPaintFilterSetBits;
 };
 
+enum StateDeferFlags {
+    kStateDeferFlag_Draw = 0x1,
+    kStateDeferFlag_Clip = 0x2
+};
+
 struct DeferredDisplayState {
     Rect mBounds; // local bounds, mapped with matrix to be in screen space coordinates, clipped.
     int mMultipliedAlpha; // -1 if invalid (because caching not set)
@@ -72,8 +77,8 @@
     // the below are set and used by the OpenGLRenderer at record and deferred playback
     Rect mClip;
     mat4 mMatrix;
-    SkiaShader* mShader;
     DrawModifiers mDrawModifiers;
+    float mAlpha;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -188,10 +193,18 @@
     virtual void restore();
     virtual void restoreToCount(int saveCount);
 
+    ANDROID_API int saveLayer(float left, float top, float right, float bottom,
+            SkPaint* paint, int flags) {
+        SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
+        if (paint) mode = getXfermode(paint->getXfermode());
+        return saveLayer(left, top, right, bottom, paint ? paint->getAlpha() : 255, mode, flags);
+    }
+    ANDROID_API int saveLayerAlpha(float left, float top, float right, float bottom,
+            int alpha, int flags) {
+        return saveLayer(left, top, right, bottom, alpha, SkXfermode::kSrcOver_Mode, flags);
+    }
     virtual int saveLayer(float left, float top, float right, float bottom,
-            SkPaint* p, int flags);
-    virtual int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, int flags);
+            int alpha, SkXfermode::Mode mode, int flags);
 
     virtual void translate(float dx, float dy);
     virtual void rotate(float degrees);
@@ -211,7 +224,7 @@
     virtual bool clipRegion(SkRegion* region, SkRegion::Op op);
     virtual Rect* getClipRect();
 
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags);
+    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags);
     virtual void outputDisplayList(DisplayList* displayList);
     virtual status_t drawLayer(Layer* layer, float x, float y, SkPaint* paint);
     virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
@@ -261,21 +274,10 @@
 
     SkPaint* filterPaint(SkPaint* paint, bool alwaysCopy = false);
 
-    bool disallowDeferral() {
-        // returns true if the OpenGLRenderer's state can be completely represented by
-        // a DeferredDisplayState object
-        return !mSnapshot->clipRegion->isEmpty() ||
-                mSnapshot->alpha < 1.0 ||
-                (mSnapshot->flags & Snapshot::kFlagIsLayer) ||
-                (mSnapshot->flags & Snapshot::kFlagFboTarget); // ensure we're not in a layer
-    }
+    bool storeDisplayState(DeferredDisplayState& state, int stateDeferFlags);
+    void restoreDisplayState(const DeferredDisplayState& state, int stateDeferFlags);
 
-    bool storeDisplayState(DeferredDisplayState& state);
-    void restoreDisplayState(const DeferredDisplayState& state);
-
-    const DrawModifiers& getDrawModifiers() { return mDrawModifiers; }
-    void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; }
-
+    // TODO: what does this mean? no perspective? no rotate?
     ANDROID_API bool isCurrentTransformSimple() {
         return mSnapshot->transform->isSimple();
     }
@@ -284,6 +286,11 @@
         return mCaches;
     }
 
+    // simple rect clip
+    bool isCurrentClipSimple() {
+        return mSnapshot->clipRegion->isEmpty();
+    }
+
     /**
      * Sets the alpha on the current snapshot. This alpha value will be modulated
      * with other alpha values when drawing primitives.