diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-05 10:06:28 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-05 10:06:28 +0000 |
commit | c2d8c62c743da5ba1bb6b8a40cf066ff0b607eb6 (patch) | |
tree | e28f068cec492220f8785870df792caf6deb4c08 | |
parent | 50ede759561d167033ae84ad2f45c08131f9a756 (diff) | |
parent | 843be86c432287f499845d6032e5568ff0313924 (diff) |
Snap for 8406016 from 843be86c432287f499845d6032e5568ff0313924 to s-keystone-qcom-release
Change-Id: I3c6f1004a320cf08e039ecda0cd448890cd2a3f1
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.cpp | 24 | ||||
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RenderArea.h | 5 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 47 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/CompositionTest.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h | 4 |
9 files changed, 66 insertions, 40 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 07de93f49b..f0405fb232 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -559,6 +559,13 @@ status_t HWComposer::getDeviceCompositionChanges( sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const { RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE); + + auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay; + + if (!hwcDisplay->isConnected()) { + return Fence::NO_FENCE; + } + return mDisplayData.at(displayId).lastPresentFence; } @@ -583,6 +590,10 @@ status_t HWComposer::presentAndGetReleaseFences( auto& displayData = mDisplayData[displayId]; auto& hwcDisplay = displayData.hwcDisplay; + if (!hwcDisplay->isConnected()) { + return NO_ERROR; + } + if (displayData.validateWasSkipped) { displayData.validateWasSkipped = false; // explicitly flush all pending commands diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 512dd6e5d3..a95f9085d7 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -1,4 +1,3 @@ - /* * Copyright (C) 2007 The Android Open Source Project * diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp index 11fe6d0755..bced928101 100644 --- a/services/surfaceflinger/LayerRenderArea.cpp +++ b/services/surfaceflinger/LayerRenderArea.cpp @@ -26,18 +26,12 @@ namespace android { namespace { -struct ReparentForDrawing { - const sp<Layer>& oldParent; - - ReparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent, - const Rect& drawingBounds) - : oldParent(oldParent) { +void reparentForDrawing(const sp<Layer>& oldParent, const sp<Layer>& newParent, + const Rect& drawingBounds) { // Compute and cache the bounds for the new parent layer. newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform(), - 0.f /* shadowRadius */); + 0.f /* shadowRadius */); oldParent->setChildrenDrawingParent(newParent); - } - ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); } }; } // namespace @@ -116,11 +110,19 @@ void LayerRenderArea::render(std::function<void()> drawLayers) { uint32_t h = static_cast<uint32_t>(getHeight()); // In the "childrenOnly" case we reparent the children to a screenshot // layer which has no properties set and which does not draw. + // We hold the statelock as the reparent-for-drawing operation modifies the + // hierarchy and there could be readers on Binder threads, like dump. sp<ContainerLayer> screenshotParentLayer = mFlinger.getFactory().createContainerLayer( {&mFlinger, nullptr, "Screenshot Parent"s, w, h, 0, LayerMetadata()}); - - ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop); + { + Mutex::Autolock _l(mFlinger.mStateLock); + reparentForDrawing(mLayer, screenshotParentLayer, sourceCrop); + } drawLayers(); + { + Mutex::Autolock _l(mFlinger.mStateLock); + mLayer->setChildrenDrawingParent(mLayer); + } } } diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h index 6a906944a7..41273e01c1 100644 --- a/services/surfaceflinger/LayerRenderArea.h +++ b/services/surfaceflinger/LayerRenderArea.h @@ -46,6 +46,7 @@ public: Rect getSourceCrop() const override; void render(std::function<void()> drawLayers) override; + virtual sp<Layer> getParentLayer() const { return mLayer; } private: const sp<Layer> mLayer; @@ -58,4 +59,4 @@ private: const bool mChildrenOnly; }; -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h index c9f7f46953..387364c03a 100644 --- a/services/surfaceflinger/RenderArea.h +++ b/services/surfaceflinger/RenderArea.h @@ -4,6 +4,7 @@ #include <ui/Transform.h> #include <functional> +#include "Layer.h" namespace android { @@ -85,6 +86,10 @@ public: // Returns the source display viewport. const Rect& getLayerStackSpaceRect() const { return mLayerStackSpaceRect; } + // If this is a LayerRenderArea, return the root layer of the + // capture operation. + virtual sp<Layer> getParentLayer() const { return nullptr; } + protected: const bool mAllowSecureLayers; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 223e71dba5..04b49325d2 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -4901,14 +4901,19 @@ status_t SurfaceFlinger::setTransactionState( state.traverseStatesWithBuffers([&](const layer_state_t& state) { sp<Layer> layer = fromHandle(state.surface).promote(); if (layer != nullptr) { - const uint32_t layerStackId = layer->getLayerStack(); SmomoIntf *smoMo = nullptr; - for (auto &instance: mSmomoInstances) { - if (instance.layerStackId == layerStackId) { - smoMo = instance.smoMo; - break; + if (mSmomoInstances.size() > 1) { + const uint32_t layerStackId = layer->getLayerStack(); + for (auto &instance: mSmomoInstances) { + if (instance.layerStackId == layerStackId) { + smoMo = instance.smoMo; + break; + } } } + else if (mSmomoInstances.size() == 1) { + smoMo = mSmomoInstances[0].smoMo; + } if (smoMo) { smomo::SmomoBufferStats bufferStats; @@ -7931,17 +7936,6 @@ status_t SurfaceFlinger::captureLayers(const LayerCaptureArgs& args, // and failed if display is not in native mode. This provide a way to force using native // colors when capture. dataspace = args.dataspace; - if (dataspace == ui::Dataspace::UNKNOWN) { - auto display = findDisplay(WithLayerStack(parent->getLayerStack())); - if (!display) { - // If the layer is not on a display, use the dataspace for the default display. - display = getDefaultDisplayDeviceLocked(); - } - - const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode; - dataspace = pickDataspaceFromColorMode(colorMode); - } - } // mStateLock // really small crop or frameScale @@ -8078,7 +8072,7 @@ status_t SurfaceFlinger::captureScreenCommon( status_t result = NO_ERROR; renderArea->render([&] { - result = renderScreenImplLocked(*renderArea, traverseLayers, buffer, + result = renderScreenImpl(*renderArea, traverseLayers, buffer, canCaptureBlackoutContent, regionSampling, grayscale, captureResults); }); @@ -8090,7 +8084,7 @@ status_t SurfaceFlinger::captureScreenCommon( return NO_ERROR; } -status_t SurfaceFlinger::renderScreenImplLocked( +status_t SurfaceFlinger::renderScreenImpl( const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, @@ -8113,7 +8107,20 @@ status_t SurfaceFlinger::renderScreenImplLocked( } captureResults.buffer = buffer->getBuffer(); - captureResults.capturedDataspace = renderArea.getReqDataSpace(); + auto dataspace = renderArea.getReqDataSpace(); + auto parent = renderArea.getParentLayer(); + if ((dataspace == ui::Dataspace::UNKNOWN) && (parent != nullptr)) { + Mutex::Autolock lock(mStateLock); + auto display = findDisplay(WithLayerStack(parent->getLayerStack())); + if (!display) { + // If the layer is not on a display, use the dataspace for the default display. + display = getDefaultDisplayDeviceLocked(); + } + + const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode; + dataspace = pickDataspaceFromColorMode(colorMode); + } + captureResults.capturedDataspace = dataspace; const auto reqWidth = renderArea.getReqWidth(); const auto reqHeight = renderArea.getReqHeight(); @@ -8131,7 +8138,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( clientCompositionDisplay.clip = sourceCrop; clientCompositionDisplay.orientation = rotation; - clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace(); + clientCompositionDisplay.outputDataspace = dataspace; clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; const float colorSaturation = grayscale ? 0 : 1; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index dad158d89b..16305aa135 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -443,6 +443,7 @@ private: friend class RefreshRateOverlay; friend class RegionSamplingThread; friend class SurfaceTracing; + friend class LayerRenderArea; // For unit tests friend class TestableSurfaceFlinger; @@ -1023,10 +1024,10 @@ private: const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling, bool grayscale, const sp<IScreenCaptureListener>&); - status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool canCaptureBlackoutContent, bool regionSampling, - bool grayscale, ScreenCaptureResults&); + status_t renderScreenImpl(const RenderArea&, TraverseLayersFunction, + const std::shared_ptr<renderengine::ExternalTexture>&, + bool canCaptureBlackoutContent, bool regionSampling, + bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock); bool canAllocateHwcDisplayIdForVDS(uint64_t usage); diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 52a36a2719..fdf445fd93 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -248,7 +248,7 @@ void CompositionTest::captureScreenComposition() { *mRenderEngine, true); status_t result = - mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer, + mFlinger.renderScreenImpl(*renderArea, traverseLayers, mCaptureScreenBuffer, forSystem, regionSampling); EXPECT_EQ(NO_ERROR, result); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index 8656c16198..3e676560c5 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -347,12 +347,12 @@ public: return mFlinger->onMessageReceived(what, /*vsyncId=*/0, systemTime()); } - auto renderScreenImplLocked(const RenderArea& renderArea, + auto renderScreenImpl(const RenderArea& renderArea, SurfaceFlinger::TraverseLayersFunction traverseLayers, const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem, bool regionSampling) { ScreenCaptureResults captureResults; - return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem, + return mFlinger->renderScreenImpl(renderArea, traverseLayers, buffer, forSystem, regionSampling, false /* grayscale */, captureResults); } |