Snap for 7595830 from addd383230ca2cf225730abc3ef040c0f594f803 to sc-release

Change-Id: Ideb0e488d3eed9fadc079c48322de14010be1657
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 032ff9a..6253036 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -890,7 +890,11 @@
     mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
     mBufferInfo.mFence = s.acquireFence;
     mBufferInfo.mTransform = s.bufferTransform;
+    auto lastDataspace = mBufferInfo.mDataspace;
     mBufferInfo.mDataspace = translateDataspace(s.dataspace);
+    if (lastDataspace != mBufferInfo.mDataspace) {
+        mFlinger->mSomeDataspaceChanged = true;
+    }
     mBufferInfo.mCrop = computeBufferCrop(s);
     mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
     mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f44ae71..230810c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1643,6 +1643,9 @@
         hdrInfoReporter = sp<HdrLayerInfoReporter>::make();
     }
     hdrInfoReporter->addListener(listener);
+
+
+    mAddingHDRLayerInfoListener = true;
     return OK;
 }
 
@@ -2143,6 +2146,8 @@
             mTracing.notify("bufferLatched");
         }
     }
+
+    mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
     mVisibleRegionsDirty = false;
 
     if (mCompositionEngine->needsAnotherUpdate()) {
@@ -2287,6 +2292,7 @@
 
     std::vector<std::pair<std::shared_ptr<compositionengine::Display>, sp<HdrLayerInfoReporter>>>
             hdrInfoListeners;
+    bool haveNewListeners = false;
     {
         Mutex::Autolock lock(mStateLock);
         if (mFpsReporter) {
@@ -2304,37 +2310,45 @@
                 }
             }
         }
+        haveNewListeners = mAddingHDRLayerInfoListener; // grab this with state lock
+        mAddingHDRLayerInfoListener = false;
     }
 
-    for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
-        HdrLayerInfoReporter::HdrLayerInfo info;
-        int32_t maxArea = 0;
-        mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
-            const auto layerFe = layer->getCompositionEngineLayerFE();
-            if (layer->isVisible() && compositionDisplay->belongsInOutput(layerFe)) {
-                const Dataspace transfer =
+    if (haveNewListeners || mSomeDataspaceChanged || mVisibleRegionsWereDirtyThisFrame) {
+        for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
+            HdrLayerInfoReporter::HdrLayerInfo info;
+            int32_t maxArea = 0;
+            mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
+                const auto layerFe = layer->getCompositionEngineLayerFE();
+                if (layer->isVisible() && compositionDisplay->belongsInOutput(layerFe)) {
+                    const Dataspace transfer =
                         static_cast<Dataspace>(layer->getDataSpace() & Dataspace::TRANSFER_MASK);
-                const bool isHdr = (transfer == Dataspace::TRANSFER_ST2084 ||
-                                    transfer == Dataspace::TRANSFER_HLG);
+                    const bool isHdr = (transfer == Dataspace::TRANSFER_ST2084 ||
+                                        transfer == Dataspace::TRANSFER_HLG);
 
-                if (isHdr) {
-                    const auto* outputLayer = compositionDisplay->getOutputLayerForLayer(layerFe);
-                    if (outputLayer) {
-                        info.numberOfHdrLayers++;
-                        const auto displayFrame = outputLayer->getState().displayFrame;
-                        const int32_t area = displayFrame.width() * displayFrame.height();
-                        if (area > maxArea) {
-                            maxArea = area;
-                            info.maxW = displayFrame.width();
-                            info.maxH = displayFrame.height();
+                    if (isHdr) {
+                        const auto* outputLayer =
+                            compositionDisplay->getOutputLayerForLayer(layerFe);
+                        if (outputLayer) {
+                            info.numberOfHdrLayers++;
+                            const auto displayFrame = outputLayer->getState().displayFrame;
+                            const int32_t area = displayFrame.width() * displayFrame.height();
+                            if (area > maxArea) {
+                                maxArea = area;
+                                info.maxW = displayFrame.width();
+                                info.maxH = displayFrame.height();
+                            }
                         }
                     }
                 }
-            }
-        });
-        listener->dispatchHdrLayerInfo(info);
+            });
+            listener->dispatchHdrLayerInfo(info);
+        }
     }
 
+    mSomeDataspaceChanged = false;
+    mVisibleRegionsWereDirtyThisFrame = false;
+
     mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence);
     mTransactionCallbackInvoker.sendCallbacks();
 
@@ -2481,7 +2495,6 @@
     handleTransactionLocked(transactionFlags);
 
     mDebugInTransaction = 0;
-    invalidateHwcGeometry();
     // here the transaction has been committed
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4fd86af..380f444 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1240,11 +1240,19 @@
     State mDrawingState{LayerVector::StateSet::Drawing};
     bool mVisibleRegionsDirty = false;
 
+    // VisibleRegions dirty is already cleared by postComp, but we need to track it to prevent
+    // extra work in the HDR layer info listener.
+    bool mVisibleRegionsWereDirtyThisFrame = false;
+    // Used to ensure we omit a callback when HDR layer info listener is newly added but the
+    // scene hasn't changed
+    bool mAddingHDRLayerInfoListener = false;
+
     // Set during transaction application stage to track if the input info or children
     // for a layer has changed.
     // TODO: Also move visibleRegions over to a boolean system.
     bool mInputInfoChanged = false;
     bool mSomeChildrenChanged;
+    bool mSomeDataspaceChanged = false;
     bool mForceTransactionDisplayChange = false;
 
     bool mGeometryInvalid = false;