SF: Add ability to get basic geometry

For computing the layer visibility, CompositionEngine will need to get
basic geometry state for every layer, without getting everything. Add a
new request type for the basic geometry state, and modify the existing
code in computeVisibleRegions to use it rather than accessing directly
through the front-end layer pointer.

Test: atest libsurfaceflinger_unittest libcompositionengine_test
Test: go/wm-smoke
Bug: 121291683
Change-Id: Ie286fe1986a4c383ee390c1f646c7a8a5b8c14f4
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3498419..6d853f9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2757,11 +2757,22 @@
             return;
         }
 
-        // start with the whole surface at its current location
-        const Layer::State& s(layer->getDrawingState());
+        // Note: Converts a wp<LayerFE> to a sp<LayerFE>
+        auto layerFE = compositionLayer->getLayerFE();
+        if (layerFE == nullptr) {
+            return;
+        }
+
+        // Request a snapshot of the subset of state relevant to visibility
+        // determination
+        layerFE->latchCompositionState(compositionLayer->editState().frontEnd,
+                                       compositionengine::LayerFE::StateSubset::BasicGeometry);
+
+        // Work with a read-only copy of the snapshot
+        const auto& layerFEState = compositionLayer->getState().frontEnd;
 
         // only consider the layers on the given layer stack
-        if (!display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
+        if (!display->belongsInOutput(layerFEState.layerStackId, layerFEState.internalOnly)) {
             return;
         }
 
@@ -2795,18 +2806,17 @@
         Region transparentRegion;
 
         // handle hidden surfaces by setting the visible region to empty
-        if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isOpaque(s);
-            Rect bounds(layer->getScreenBounds());
-
-            visibleRegion.set(bounds);
-            ui::Transform tr = layer->getTransform();
+        if (CC_LIKELY(layerFEState.isVisible)) {
+            // Get the visible region
+            visibleRegion.set(
+                    Rect(layerFEState.geomLayerTransform.transform(layerFEState.geomLayerBounds)));
+            const ui::Transform& tr = layerFEState.geomLayerTransform;
             if (!visibleRegion.isEmpty()) {
                 // Remove the transparent area from the visible region
-                if (translucent) {
+                if (!layerFEState.isOpaque) {
                     if (tr.preserveRects()) {
                         // transform the transparent region
-                        transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
+                        transparentRegion = tr.transform(layerFEState.transparentRegionHint);
                     } else {
                         // transformation too complex, can't do the
                         // transparent region optimization.
@@ -2816,9 +2826,8 @@
 
                 // compute the opaque region
                 const int32_t layerOrientation = tr.getOrientation();
-                if (layer->getAlpha() == 1.0f && !translucent &&
-                        layer->getRoundedCornerState().radius == 0.0f &&
-                        ((layerOrientation & ui::Transform::ROT_INVALID) == false)) {
+                if (layerFEState.isOpaque &&
+                    ((layerOrientation & ui::Transform::ROT_INVALID) == false)) {
                     // the opaque region is the layer's footprint
                     opaqueRegion = visibleRegion;
                 }
@@ -2848,12 +2857,11 @@
                 prevOutputLayer ? prevOutputLayer->getState().coveredRegion : kEmptyRegion;
 
         // compute this layer's dirty region
-        if (layer->contentDirty) {
+        if (layerFEState.contentDirty) {
             // we need to invalidate the whole region
             dirty = visibleRegion;
             // as well, as the old visible region
             dirty.orSelf(oldVisibleRegion);
-            layer->contentDirty = false;
         } else {
             /* compute the exposed region:
              *   the exposed region consists of two components:
@@ -2892,8 +2900,6 @@
         }
 
         const auto displayId = displayDevice->getId();
-        sp<compositionengine::LayerFE> layerFE = compositionLayer->getLayerFE();
-        LOG_ALWAYS_FATAL_IF(layerFE.get() == nullptr);
 
         outLayersSortedByZ.emplace_back(
                 display->getOrCreateOutputLayer(displayId, compositionLayer, layerFE));