Fix damage for layers for projection receivers

 Bug: 16880228

Change-Id: I59ab760a21f49cc2cac0d8936b173cff292e6114
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 1a96b2f..d9f7941 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -100,6 +100,9 @@
 		LOCAL_CFLAGS += -fno-omit-frame-pointer -marm -mapcs
 	endif
 
+	# Defaults for ATRACE_TAG and LOG_TAG for libhwui
+	LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\"
+
 	include $(BUILD_SHARED_LIBRARY)
 
 	include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index dd2e2fd..5ecd77a 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -249,6 +249,10 @@
     mProperty->value = value;
 }
 
+uint32_t CanvasPropertyPrimitiveAnimator::dirtyMask() {
+    return RenderNode::DISPLAY_LIST;
+}
+
 /************************************************************
  *  CanvasPropertySkPaintAnimator
  ************************************************************/
@@ -288,6 +292,10 @@
     LOG_ALWAYS_FATAL("Unknown field %d", (int) mField);
 }
 
+uint32_t CanvasPropertyPaintAnimator::dirtyMask() {
+    return RenderNode::DISPLAY_LIST;
+}
+
 RevealAnimator::RevealAnimator(int centerX, int centerY,
         float startValue, float finalValue)
         : BaseRenderNodeAnimator(finalValue)
@@ -305,5 +313,9 @@
             mCenterX, mCenterY, value);
 }
 
+uint32_t RevealAnimator::dirtyMask() {
+    return RenderNode::GENERIC;
+}
+
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index b0dcf2d..6dfe7b4 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -62,7 +62,7 @@
     bool isFinished() { return mPlayState == FINISHED; }
     float finalValue() { return mFinalValue; }
 
-    ANDROID_API virtual uint32_t dirtyMask() { return 0; }
+    ANDROID_API virtual uint32_t dirtyMask() = 0;
 
 protected:
     BaseRenderNodeAnimator(float finalValue);
@@ -145,6 +145,9 @@
 public:
     ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property,
             float finalValue);
+
+    ANDROID_API virtual uint32_t dirtyMask();
+
 protected:
     virtual float getValue(RenderNode* target) const;
     virtual void setValue(RenderNode* target, float value);
@@ -161,6 +164,9 @@
 
     ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property,
             PaintField field, float finalValue);
+
+    ANDROID_API virtual uint32_t dirtyMask();
+
 protected:
     virtual float getValue(RenderNode* target) const;
     virtual void setValue(RenderNode* target, float value);
@@ -173,13 +179,15 @@
 public:
     ANDROID_API RevealAnimator(int centerX, int centerY,
             float startValue, float finalValue);
+
+    ANDROID_API virtual uint32_t dirtyMask();
+
 protected:
     virtual float getValue(RenderNode* target) const;
     virtual void setValue(RenderNode* target, float value);
 
 private:
     int mCenterX, mCenterY;
-    bool mInverseClip;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 27b0893..7221295a4 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -66,22 +66,26 @@
 class AnimateFunctor {
 public:
     AnimateFunctor(RenderNode& target, TreeInfo& info)
-            : mTarget(target), mInfo(info) {}
+            : dirtyMask(0), mTarget(target), mInfo(info) {}
 
     bool operator() (BaseRenderNodeAnimator* animator) {
+        dirtyMask |= animator->dirtyMask();
         bool remove = animator->animate(mInfo);
         if (remove) {
             animator->decStrong(0);
         }
         return remove;
     }
+
+    uint32_t dirtyMask;
+
 private:
     RenderNode& mTarget;
     TreeInfo& mInfo;
 };
 
-void AnimatorManager::animate(TreeInfo& info) {
-    if (!mAnimators.size()) return;
+uint32_t AnimatorManager::animate(TreeInfo& info) {
+    if (!mAnimators.size()) return 0;
 
     // TODO: Can we target this better? For now treat it like any other staging
     // property push and just damage self before and after animators are run
@@ -97,6 +101,8 @@
     mParent.mProperties.updateMatrix();
     info.damageAccumulator->pushTransform(&mParent);
     mParent.damageSelf(info);
+
+    return functor.dirtyMask;
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
index 2568121..0d177c5 100644
--- a/libs/hwui/AnimatorManager.h
+++ b/libs/hwui/AnimatorManager.h
@@ -40,7 +40,8 @@
     void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
 
     void pushStaging(TreeInfo& info);
-    void animate(TreeInfo& info);
+    // Returns the combined dirty mask of all animators run
+    uint32_t animate(TreeInfo& info);
 
 private:
     RenderNode& mParent;
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 8b32c40..15bed58 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -83,11 +83,6 @@
     mHead->matrix4 = transform;
 }
 
-void DamageAccumulator::pushNullTransform() {
-    pushCommon();
-    mHead->type = TransformNone;
-}
-
 void DamageAccumulator::popTransform() {
     LOG_ALWAYS_FATAL_IF(mHead->prev == mHead, "Cannot pop the root frame!");
     DirtyStack* dirtyFrame = mHead;
diff --git a/libs/hwui/DamageAccumulator.h b/libs/hwui/DamageAccumulator.h
index fc9b41b..90d9425 100644
--- a/libs/hwui/DamageAccumulator.h
+++ b/libs/hwui/DamageAccumulator.h
@@ -35,7 +35,6 @@
 public:
     virtual void pushTransform(const RenderNode* transform) = 0;
     virtual void pushTransform(const Matrix4* transform) = 0;
-    virtual void pushNullTransform() = 0;
     virtual void popTransform() = 0;
     virtual void dirty(float left, float top, float right, float bottom) = 0;
     virtual void peekAtDirty(SkRect* dest) = 0;
@@ -54,9 +53,6 @@
     // will be affected by the transform when popTransform() is called.
     virtual void pushTransform(const RenderNode* transform);
     virtual void pushTransform(const Matrix4* transform);
-    // This is used in combination with peekAtDirty to inspect the damage
-    // area of a subtree
-    virtual void pushNullTransform();
 
     // Pops a transform node from the stack, propagating the dirty rect
     // up to the parent node. Returns the IDamageTransform that was just applied
@@ -83,7 +79,6 @@
 public:
     virtual void pushTransform(const RenderNode* transform) { }
     virtual void pushTransform(const Matrix4* transform) { }
-    virtual void pushNullTransform() { }
     virtual void popTransform() { }
     virtual void dirty(float left, float top, float right, float bottom) { }
     virtual void peekAtDirty(SkRect* dest) { dest->setEmpty(); }
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 396c7f3..636f218 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -598,6 +598,7 @@
 }
 
 void OpenGLRenderer::flushLayerUpdates() {
+    ATRACE_CALL();
     syncState();
     updateLayers();
     flushLayers();
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 23940ee..c59b010 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -136,13 +136,18 @@
     }
 }
 
-void RenderNode::prepareLayer(TreeInfo& info) {
+void RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) {
     LayerType layerType = properties().layerProperties().type();
     if (CC_UNLIKELY(layerType == kLayerTypeRenderLayer)) {
-        // We push a null transform here as we don't care what the existing dirty
-        // area is, only what our display list dirty is as well as our children's
-        // dirty area
-        info.damageAccumulator->pushNullTransform();
+        // Damage applied so far needs to affect our parent, but does not require
+        // the layer to be updated. So we pop/push here to clear out the current
+        // damage and get a clean state for display list or children updates to
+        // affect, which will require the layer to be updated
+        info.damageAccumulator->popTransform();
+        info.damageAccumulator->pushTransform(this);
+        if (dirtyMask & DISPLAY_LIST) {
+            damageSelf(info);
+        }
     }
 }
 
@@ -151,9 +156,6 @@
     // If we are not a layer OR we cannot be rendered (eg, view was detached)
     // we need to destroy any Layers we may have had previously
     if (CC_LIKELY(layerType != kLayerTypeRenderLayer) || CC_UNLIKELY(!isRenderable())) {
-        if (layerType == kLayerTypeRenderLayer) {
-            info.damageAccumulator->popTransform();
-        }
         if (CC_UNLIKELY(mLayer)) {
             LayerRenderer::destroyLayer(mLayer);
             mLayer = NULL;
@@ -175,7 +177,6 @@
 
     SkRect dirty;
     info.damageAccumulator->peekAtDirty(&dirty);
-    info.damageAccumulator->popTransform();
 
     if (!mLayer) {
         if (info.errorHandler) {
@@ -204,8 +205,8 @@
     if (info.mode == TreeInfo::MODE_FULL) {
         pushStagingPropertiesChanges(info);
     }
-    mAnimatorManager.animate(info);
-    prepareLayer(info);
+    uint32_t animatorDirtyMask = mAnimatorManager.animate(info);
+    prepareLayer(info, animatorDirtyMask);
     if (info.mode == TreeInfo::MODE_FULL) {
         pushStagingDisplayListChanges(info);
     }
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 8cc65b2..fa310e0 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -90,6 +90,7 @@
         Y               = 1 << 11,
         Z               = 1 << 12,
         ALPHA           = 1 << 13,
+        DISPLAY_LIST    = 1 << 14,
     };
 
     ANDROID_API RenderNode();
@@ -244,7 +245,7 @@
     void pushStagingDisplayListChanges(TreeInfo& info);
     void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
     void applyLayerPropertiesToLayer(TreeInfo& info);
-    void prepareLayer(TreeInfo& info);
+    void prepareLayer(TreeInfo& info, uint32_t dirtyMask);
     void pushLayerUpdate(TreeInfo& info);
     void deleteDisplayListData();
     void damageSelf(TreeInfo& info);