Finish shadow support in new reorderer/renderer

Now passes alphas and light radius, and correctly transforms light
center for layers.

Also fixes begin-frame/layer clears to be damage rect aware.

Change-Id: I3b1415cd7bf1518c510145ebebdb745f494a2542
diff --git a/libs/hwui/OpReorderer.cpp b/libs/hwui/OpReorderer.cpp
index 80efaed..b04f16f 100644
--- a/libs/hwui/OpReorderer.cpp
+++ b/libs/hwui/OpReorderer.cpp
@@ -18,6 +18,7 @@
 
 #include "LayerUpdateQueue.h"
 #include "RenderNode.h"
+#include "renderstate/OffscreenBufferPool.h"
 #include "utils/FatVector.h"
 #include "utils/PaintUtils.h"
 
@@ -33,8 +34,8 @@
 
 public:
     BatchBase(batchid_t batchId, BakedOpState* op, bool merging)
-        : mBatchId(batchId)
-        , mMerging(merging) {
+            : mBatchId(batchId)
+            , mMerging(merging) {
         mBounds = op->computedState.clippedBounds;
         mOps.push_back(op);
     }
@@ -207,9 +208,10 @@
 };
 
 OpReorderer::LayerReorderer::LayerReorderer(uint32_t width, uint32_t height,
-        const BeginLayerOp* beginLayerOp, RenderNode* renderNode)
+        const Rect& repaintRect, const BeginLayerOp* beginLayerOp, RenderNode* renderNode)
         : width(width)
         , height(height)
+        , repaintRect(repaintRect)
         , offscreenBuffer(renderNode ? renderNode->getLayer() : nullptr)
         , beginLayerOp(beginLayerOp)
         , renderNode(renderNode) {}
@@ -309,15 +311,19 @@
 
 OpReorderer::OpReorderer(const LayerUpdateQueue& layers, const SkRect& clip,
         uint32_t viewportWidth, uint32_t viewportHeight,
-        const std::vector< sp<RenderNode> >& nodes)
+        const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter)
         : mCanvasState(*this) {
     ATRACE_NAME("prepare drawing commands");
-    mLayerReorderers.emplace_back(viewportWidth, viewportHeight);
-    mLayerStack.push_back(0);
 
+    mLayerReorderers.reserve(layers.entries().size());
+    mLayerStack.reserve(layers.entries().size());
+
+    // Prepare to defer Fbo0
+    mLayerReorderers.emplace_back(viewportWidth, viewportHeight, Rect(clip));
+    mLayerStack.push_back(0);
     mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
             clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
-            Vector3());
+            lightCenter);
 
     // Render all layers to be updated, in order. Defer in reverse order, so that they'll be
     // updated in the order they're passed in (mLayerReorderers are issued to Renderer in reverse)
@@ -325,7 +331,8 @@
         RenderNode* layerNode = layers.entries()[i].renderNode;
         const Rect& layerDamage = layers.entries()[i].damage;
 
-        saveForLayer(layerNode->getWidth(), layerNode->getHeight(), nullptr, layerNode);
+        saveForLayer(layerNode->getWidth(), layerNode->getHeight(),
+                layerDamage, nullptr, layerNode);
         mCanvasState.writableSnapshot()->setClip(
                 layerDamage.left, layerDamage.top, layerDamage.right, layerDamage.bottom);
 
@@ -345,14 +352,17 @@
     }
 }
 
-OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList)
+OpReorderer::OpReorderer(int viewportWidth, int viewportHeight, const DisplayList& displayList,
+        const Vector3& lightCenter)
         : mCanvasState(*this) {
     ATRACE_NAME("prepare drawing commands");
-    mLayerReorderers.emplace_back(viewportWidth, viewportHeight);
+    // Prepare to defer Fbo0
+    mLayerReorderers.emplace_back(viewportWidth, viewportHeight,
+            Rect(viewportWidth, viewportHeight));
     mLayerStack.push_back(0);
-
     mCanvasState.initializeSaveStack(viewportWidth, viewportHeight,
-            0, 0, viewportWidth, viewportHeight, Vector3());
+            0, 0, viewportWidth, viewportHeight, lightCenter);
+
     deferImpl(displayList);
 }
 
@@ -508,7 +518,8 @@
     }
 
     ShadowOp* shadowOp = new (mAllocator) ShadowOp(casterNodeOp, casterAlpha, casterPath,
-            mCanvasState.getLocalClipBounds());
+            mCanvasState.getLocalClipBounds(),
+            mCanvasState.currentSnapshot()->getRelativeLightCenter());
     BakedOpState* bakedOpState = BakedOpState::tryShadowOpConstruct(
             mAllocator, *mCanvasState.currentSnapshot(), shadowOp);
     if (CC_LIKELY(bakedOpState)) {
@@ -589,17 +600,36 @@
     currentLayer().deferUnmergeableOp(mAllocator, bakedStateOp, OpBatchType::Vertices);
 }
 
-void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight,
+void OpReorderer::saveForLayer(uint32_t layerWidth, uint32_t layerHeight, const Rect& repaintRect,
         const BeginLayerOp* beginLayerOp, RenderNode* renderNode) {
 
+    auto previous = mCanvasState.currentSnapshot();
     mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);
     mCanvasState.writableSnapshot()->transform->loadIdentity();
     mCanvasState.writableSnapshot()->initializeViewport(layerWidth, layerHeight);
     mCanvasState.writableSnapshot()->roundRectClipState = nullptr;
 
+    Vector3 lightCenter = previous->getRelativeLightCenter();
+    if (renderNode) {
+        Matrix4& inverse = renderNode->getLayer()->inverseTransformInWindow;
+        inverse.mapPoint3d(lightCenter);
+    } else {
+        // Combine all transforms used to present saveLayer content:
+        // parent content transform * canvas transform * bounds offset
+        Matrix4 contentTransform(*previous->transform);
+        contentTransform.multiply(beginLayerOp->localMatrix);
+        contentTransform.translate(beginLayerOp->unmappedBounds.left, beginLayerOp->unmappedBounds.top);
+
+        // inverse the total transform, to map light center into layer-relative space
+        Matrix4 inverse;
+        inverse.loadInverse(contentTransform);
+        inverse.mapPoint3d(lightCenter);
+    }
+    mCanvasState.writableSnapshot()->setRelativeLightCenter(lightCenter);
+
     // create a new layer, and push its index on the stack
     mLayerStack.push_back(mLayerReorderers.size());
-    mLayerReorderers.emplace_back(layerWidth, layerHeight, beginLayerOp, renderNode);
+    mLayerReorderers.emplace_back(layerWidth, layerHeight, repaintRect, beginLayerOp, renderNode);
 }
 
 void OpReorderer::restoreForLayer() {
@@ -612,7 +642,7 @@
 void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
     const uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
     const uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();
-    saveForLayer(layerWidth, layerHeight, &op, nullptr);
+    saveForLayer(layerWidth, layerHeight, Rect(layerWidth, layerHeight), &op, nullptr);
 }
 
 void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {