summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Robert Carr <racarr@google.com> 2022-03-10 09:55:29 -0800
committer Robert Carr <racarr@google.com> 2022-03-15 12:36:42 -0700
commit12a3b9bba87d831f78faabb42523598a8d891ecc (patch)
treedb04c787b29a19cf0d301c6906354c8e61a237f1
parent70fa373dc64bfeab4279e291fd5d876f6a86fe51 (diff)
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
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/LayerRenderArea.h3
-rw-r--r--services/surfaceflinger/RenderArea.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp36
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h4
-rw-r--r--services/surfaceflinger/tests/unittests/CompositionTest.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h4
7 files changed, 32 insertions, 25 deletions
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 0fb16f2f12..48a9bc50c4 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.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 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<renderengine::RenderEngineResult> SurfaceFlinger::captureScre
renderArea->render([&] {
renderEngineResultFuture =
- renderScreenImplLocked(*renderArea, traverseLayers, buffer,
+ renderScreenImpl(*renderArea, traverseLayers, buffer,
canCaptureBlackoutContent, regionSampling, grayscale,
captureResults);
});
@@ -6673,7 +6660,7 @@ std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::captureScre
}
}
-std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::renderScreenImplLocked(
+std::shared_future<renderengine::RenderEngineResult> SurfaceFlinger::renderScreenImpl(
const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
const std::shared_ptr<renderengine::ExternalTexture>& buffer,
bool canCaptureBlackoutContent, bool regionSampling, bool grayscale,
@@ -6697,7 +6684,22 @@ std::shared_future<renderengine::RenderEngineResult> 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<renderengine::RenderEngineResult> 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;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index fa6580342b..370afc1265 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -863,10 +863,10 @@ private:
RenderAreaFuture, TraverseLayersFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool regionSampling,
bool grayscale, const sp<IScreenCaptureListener>&);
- std::shared_future<renderengine::RenderEngineResult> renderScreenImplLocked(
+ std::shared_future<renderengine::RenderEngineResult> renderScreenImpl(
const RenderArea&, TraverseLayersFunction,
const std::shared_ptr<renderengine::ExternalTexture>&, bool canCaptureBlackoutContent,
- bool regionSampling, bool grayscale, ScreenCaptureResults&);
+ bool regionSampling, bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock);
// If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
// matching ownerUid
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 16690757e9..15c9d199cd 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -244,8 +244,8 @@ void CompositionTest::captureScreenComposition() {
HAL_PIXEL_FORMAT_RGBA_8888, 1,
usage);
- auto result = mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer,
- forSystem, regionSampling);
+ auto result = mFlinger.renderScreenImpl(*renderArea, traverseLayers, mCaptureScreenBuffer,
+ forSystem, regionSampling);
EXPECT_TRUE(result.valid());
auto& [status, drawFence] = result.get();
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index fe0564e0d3..6780108c4f 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -400,12 +400,12 @@ public:
return mFlinger->setPowerModeInternal(display, mode);
}
- 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);
}