diff options
author | Rob Carr <racarr@google.com> | 2021-07-29 22:04:47 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-07-29 22:04:47 +0000 |
commit | f6e2ea73ad00303b2846ae2bf04091ae1269b456 (patch) | |
tree | aacca54890e1ab34b4875bafa3a48aa2a98e6fbc | |
parent | 7089fbbfe5ca8b40fbc1fc41f0272642d6d427d8 (diff) | |
parent | 167bdde88b9159c62c5c4d839e7615c94e7851dc (diff) | |
download | native-f6e2ea73ad00303b2846ae2bf04091ae1269b456.tar.gz |
Merge "Prevent HDRLayerInfoListener traversal from running on every frame" into sc-dev
-rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 60 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 8 |
3 files changed, 49 insertions, 23 deletions
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 032ff9a572..6253036c41 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -890,7 +890,11 @@ void BufferStateLayer::gatherBufferInfo() { 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 f44ae71896..e0af028ea5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1643,6 +1643,9 @@ status_t SurfaceFlinger::addHdrLayerInfoListener(const sp<IBinder>& displayToken hdrInfoReporter = sp<HdrLayerInfoReporter>::make(); } hdrInfoReporter->addListener(listener); + + + mAddingHDRLayerInfoListener = true; return OK; } @@ -2143,6 +2146,8 @@ void SurfaceFlinger::onMessageRefresh() { mTracing.notify("bufferLatched"); } } + + mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp mVisibleRegionsDirty = false; if (mCompositionEngine->needsAnotherUpdate()) { @@ -2287,6 +2292,7 @@ void SurfaceFlinger::postComposition() { 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 @@ void SurfaceFlinger::postComposition() { } } } + 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); - - 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(); + 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(); + } } } } - } - }); - listener->dispatchHdrLayerInfo(info); + }); + listener->dispatchHdrLayerInfo(info); + } } + mSomeDataspaceChanged = false; + mVisibleRegionsWereDirtyThisFrame = false; + mTransactionCallbackInvoker.addPresentFence(mPreviousPresentFences[0].fence); mTransactionCallbackInvoker.sendCallbacks(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4fd86af24f..380f444221 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1240,11 +1240,19 @@ private: 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; |