From 12a3b9bba87d831f78faabb42523598a8d891ecc Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 10 Mar 2022 09:55:29 -0800 Subject: CaptureLayers: Avoid promoting parent on binder thread We promote the parent of the root layer when we call getLayerStack. Since we don't hold an IBinder to the root layers parent, just to the layer itself, this could create a situation where we are the last reference to the layer. Layers have to be destroyed on the main thread and so that would be invalid. Hopefully this is the last case and now we can start getting rid of refbase for layer. Bug: 220176775 Bug: 223069308 Bug: 223081111 Test: Existing tests pass Change-Id: I37a0834ddac6d8e84170674aba0c49268d65fa11 --- services/surfaceflinger/SurfaceFlinger.cpp | 36 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 425b78bd68..268036ce0c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6499,19 +6499,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([layerStack = parent->getLayerStack()](const auto& display) { - return display.getLayerStack() == layerStack; - }); - 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 @@ -6640,7 +6627,7 @@ std::shared_future SurfaceFlinger::captureScre renderArea->render([&] { renderEngineResultFuture = - renderScreenImplLocked(*renderArea, traverseLayers, buffer, + renderScreenImpl(*renderArea, traverseLayers, buffer, canCaptureBlackoutContent, regionSampling, grayscale, captureResults); }); @@ -6673,7 +6660,7 @@ std::shared_future SurfaceFlinger::captureScre } } -std::shared_future SurfaceFlinger::renderScreenImplLocked( +std::shared_future SurfaceFlinger::renderScreenImpl( const RenderArea& renderArea, TraverseLayersFunction traverseLayers, const std::shared_ptr& buffer, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, @@ -6697,7 +6684,22 @@ std::shared_future SurfaceFlinger::renderScree } 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([layerStack = parent->getLayerStack()](const auto& display) { + return display.getLayerStack() == layerStack; + }); + 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(); @@ -6715,7 +6717,7 @@ std::shared_future SurfaceFlinger::renderScree clientCompositionDisplay.clip = sourceCrop; clientCompositionDisplay.orientation = rotation; - clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace(); + clientCompositionDisplay.outputDataspace = dataspace; clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; const float colorSaturation = grayscale ? 0 : 1; -- cgit v1.2.3-59-g8ed1b