Set visible region dirty flag when alpha changes

Removes an optimzation which only set the
visible region dirty flag when alpha changed
from 1->0 or 0->1. This optimization broke an
assumption in CE. Alpha is only passed to HWC
when there are geometry changes which are
tracked by the visible region dirty flag.

Fixes: 299256533
Test: presubmit
Test: dim layer alpha animates when showing a dialog
Change-Id: I4c56171d19d582e26b9c2c7be6c555a6c1d7494c
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 4371007..2c123b3 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -277,8 +277,8 @@
             layer_state_t::eLayerStackChanged;
 
     // Changes that affect the visible region on a display.
-    static constexpr uint64_t VISIBLE_REGION_CHANGES =
-            layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES;
+    static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES |
+            layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged;
 
     bool hasValidBuffer() const;
     void sanitize(int32_t permissions);
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 168267b..f137ec4 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -237,8 +237,7 @@
     }
     if (what & (layer_state_t::eAlphaChanged)) {
         if (oldAlpha == 0 || color.a == 0) {
-            changes |= RequestedLayerState::Changes::Visibility |
-                    RequestedLayerState::Changes::VisibleRegion;
+            changes |= RequestedLayerState::Changes::Visibility;
         }
     }
 
diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
index 1fde9b8..aecfcba 100644
--- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
@@ -525,4 +525,39 @@
     mLifecycleManager.commitChanges();
 }
 
+// Even when it does not change visible region, we should mark alpha changes as affecting
+// visible region because HWC impl depends on it. writeOutputIndependentGeometryStateToHWC
+// is only called if we are updating geometry.
+TEST_F(LayerLifecycleManagerTest, alphaChangesAlwaysSetsVisibleRegionFlag) {
+    mLifecycleManager.commitChanges();
+    float startingAlpha = 0.5f;
+    setAlpha(1, startingAlpha);
+
+    // this is expected because layer alpha changes from 1 to 0.5, it may no longer be opaque
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
+              ftl::Flags<RequestedLayerState::Changes>(
+                      RequestedLayerState::Changes::Content |
+                      RequestedLayerState::Changes::AffectsChildren |
+                      RequestedLayerState::Changes::VisibleRegion)
+                      .string());
+    EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(startingAlpha));
+    mLifecycleManager.commitChanges();
+
+    float endingAlpha = 0.2f;
+    setAlpha(1, endingAlpha);
+
+    // this is not expected but we should make sure this behavior does not change
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
+              ftl::Flags<RequestedLayerState::Changes>(
+                      RequestedLayerState::Changes::Content |
+                      RequestedLayerState::Changes::AffectsChildren |
+                      RequestedLayerState::Changes::VisibleRegion)
+                      .string());
+    EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(endingAlpha));
+    mLifecycleManager.commitChanges();
+
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges().string(),
+              ftl::Flags<RequestedLayerState::Changes>().string());
+}
+
 } // namespace android::surfaceflinger::frontend