SF: Interleave writes to HWC with other work

This is at least a partial fix for a reported regression in the
FadingEdgeListViewFling jank test caused by work to refactor
Layer::setPerFrameData (affecting SurfaceFlinger::calculateWorkingSet)

Note that I failed to reproduce the same regression in
gfx-max-frame-time-95 visible on the dashboard (regressed from 5 to
15ms) on a borrowed walleye, so I ended up having to analyze the
performance differences locally, to see what I could find.

After instrumenting the code, I found that the biggest difference
between the performance before my change and after was that
*standard deviation* in the overall time for
SurfaceFlinger::handleMessageFresh() jumped from 0.06ms to 0.13ms.
In particular this seemed to be most correspond to a jump in the
*standard deviation* for SurfaceFlinger::prepareFrame() jumping from
0.04ms to 0.08ms.

In other words, the regression seems to be caused by the wait on the HWC
implementation for it to process the validateorPresent() call

I had a memory of b/117282234 causing a similar regression in the jank
test last year when moving the calls to set the HWC data to be done all
at once for all layers, instead of being interleaved with other work.

This patch makes a simple change which does substantially the same thing
-- interleaving calls to set the HWC state with other work.

It additionally eliminates the use of a map which was introduced to try
and eliminate redundant  calls to Layer::setPerFrameData for the same
layer, as another potential source of inconsistent runtime performance.

The result is that the standard deviation in handleMessageRefresh()
dropped to 0.10ms, and for prepareFrame() it dropped to 0.6ms.

It does not bring things back to the same consistenency in the runtime,
but it is a good step towards that.

The other thing I can try is to reorder the calls to the HWC, as that
would seem to be the only other reason there might be a difference in
runtime.

Test: atest UbSystemUIJankTests:SettingsJankTests on walleye
Test: Profiling handleMessageRefresh etc.
Bug: 138853920
Change-Id: Icd12b3055035c9fc30e68d5b38b37251accafd51
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 213160d..7eca6df 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1854,24 +1854,13 @@
     const bool updatingGeometryThisFrame = mGeometryInvalid;
     mGeometryInvalid = false;
 
-    {
-        // Use a map so that we latch the state of each front-end layer once.
-        std::unordered_map<compositionengine::LayerFE*, compositionengine::LayerFECompositionState*>
-                uniqueVisibleLayers;
-
-        // Figure out which frontend layers are being composed, and build the unique
-        // set of them (and the corresponding composition layer)
-        for (const auto& [token, displayDevice] : mDisplays) {
-            auto display = displayDevice->getCompositionDisplay();
-            for (auto& layer : display->getOutputLayersOrderedByZ()) {
-                uniqueVisibleLayers.insert(std::make_pair(&layer->getLayerFE(),
-                                                          &layer->getLayer().editState().frontEnd));
-            }
-        }
-
-        // Update the composition state from each front-end layer.
-        for (auto& [layerFE, state] : uniqueVisibleLayers) {
-            layerFE->latchCompositionState(*state, updatingGeometryThisFrame);
+    // Latch the frontend layer composition state for each layer being
+    // composed.
+    for (const auto& [token, displayDevice] : mDisplays) {
+        auto display = displayDevice->getCompositionDisplay();
+        for (auto& layer : display->getOutputLayersOrderedByZ()) {
+            layer->getLayerFE().latchCompositionState(layer->getLayer().editState().frontEnd,
+                                                      updatingGeometryThisFrame);
         }
     }
 
@@ -1907,13 +1896,7 @@
             // Update the composition state of the output layer, as needed
             // recomputing it from the state given by the front-end layer.
             layer->updateCompositionState(updatingGeometryThisFrame);
-        }
-    }
 
-    for (const auto& [token, displayDevice] : mDisplays) {
-        auto display = displayDevice->getCompositionDisplay();
-
-        for (auto& layer : display->getOutputLayersOrderedByZ()) {
             // Send the updated state to the HWC, if appropriate.
             layer->writeStateToHWC(updatingGeometryThisFrame);
         }