Initial HW layer support in new reorderer/renderer

Shares vast majority of clipped savelayer code, with only minor
differences in lifecycle.

Doesn't yet handle fill region, resize, or window transform.

Change-Id: Iabdd71811590d2b937eb11e1b01ce556ade54a5a
diff --git a/libs/hwui/OpReorderer.h b/libs/hwui/OpReorderer.h
index 927ecfa..77be402 100644
--- a/libs/hwui/OpReorderer.h
+++ b/libs/hwui/OpReorderer.h
@@ -32,6 +32,7 @@
 
 class BakedOpState;
 class BatchBase;
+class LayerUpdateQueue;
 class MergingOpBatch;
 class OffscreenBuffer;
 class OpBatch;
@@ -64,9 +65,14 @@
      */
     class LayerReorderer {
     public:
+        // Create LayerReorderer for Fbo0
         LayerReorderer(uint32_t width, uint32_t height)
-                : width(width)
-                , height(height) {}
+                : LayerReorderer(width, height, nullptr, nullptr) {};
+
+        // Create LayerReorderer for an offscreen layer, where beginLayerOp is present for a
+        // saveLayer, renderNode is present for a HW layer.
+        LayerReorderer(uint32_t width, uint32_t height,
+                const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
 
         // iterate back toward target to see if anything drawn since should overlap the new op
         // if no target, merging ops still iterate to find similar batch to insert after
@@ -92,12 +98,12 @@
 
         void dump() const;
 
-        OffscreenBuffer* offscreenBuffer = nullptr;
-        const BeginLayerOp* beginLayerOp = nullptr;
         const uint32_t width;
         const uint32_t height;
+        OffscreenBuffer* offscreenBuffer;
+        const BeginLayerOp* beginLayerOp;
+        const RenderNode* renderNode;
     private:
-
         std::vector<BatchBase*> mBatches;
 
         /**
@@ -112,8 +118,8 @@
 
     };
 public:
-    // TODO: not final, just presented this way for simplicity. Layers too?
-    OpReorderer(const SkRect& clip, uint32_t viewportWidth, uint32_t viewportHeight,
+    OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
+            uint32_t viewportWidth, uint32_t viewportHeight,
             const std::vector< sp<RenderNode> >& nodes);
 
     OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList);
@@ -144,8 +150,13 @@
         // later in the list will be drawn by earlier ones
         for (int i = mLayerReorderers.size() - 1; i >= 1; i--) {
             LayerReorderer& layer = mLayerReorderers[i];
-            if (!layer.empty()) {
-                layer.offscreenBuffer = renderer.startLayer(layer.width, layer.height);
+            if (layer.renderNode) {
+                // cached HW layer - can't skip layer if empty
+                renderer.startLayer(layer.offscreenBuffer);
+                layer.replayBakedOpsImpl((void*)&renderer, receivers);
+                renderer.endLayer();
+            } else if (!layer.empty()) { // save layer - skip entire layer if empty
+                layer.offscreenBuffer = renderer.createLayer(layer.width, layer.height);
                 layer.replayBakedOpsImpl((void*)&renderer, receivers);
                 renderer.endLayer();
             }
@@ -171,12 +182,19 @@
     virtual GLuint getTargetFbo() const override { return 0; }
 
 private:
+    void saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
+            const BeginLayerOp* beginLayerOp, RenderNode* renderNode);
+    void restoreForLayer();
+
     LayerReorderer& currentLayer() { return mLayerReorderers[mLayerStack.back()]; }
 
     BakedOpState* tryBakeOpState(const RecordedOp& recordedOp) {
         return BakedOpState::tryConstruct(mAllocator, *mCanvasState.currentSnapshot(), recordedOp);
     }
 
+    // should always be surrounded by a save/restore pair
+    void deferNodePropsAndOps(RenderNode& node);
+
     void deferImpl(const DisplayList& displayList);
 
     void replayBakedOpsImpl(void* arg, BakedOpDispatcher* receivers);