summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rob Carr <racarr@google.com> 2022-03-16 15:53:56 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-03-16 15:53:56 +0000
commita49b7b35cbf05725ff33badc8794d12fbc8a3190 (patch)
treef02e20ead690bfd63aaacaad0709ee4f608e3c54
parent92e0d0db2dc3341ce2b0f05f18bdce675e829e20 (diff)
parent22ceeaaff9be3e71c5473aeabccdb02705565190 (diff)
Merge "SurfaceFlinger/LayerRenderArea: Hold lock while modifying hierarchy" into tm-dev
-rw-r--r--services/surfaceflinger/LayerRenderArea.cpp26
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
2 files changed, 15 insertions, 12 deletions
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index a1e14559e9..896f25404d 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
@@ -114,11 +108,19 @@ void LayerRenderArea::render(std::function<void()> drawLayers) {
} else {
// 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, 0, LayerMetadata()});
-
- ReparentForDrawing reparent(mLayer, screenshotParentLayer, sourceCrop);
+ {&mFlinger, nullptr, "Screenshot Parent"s, 0, LayerMetadata()});
+ {
+ Mutex::Autolock _l(mFlinger.mStateLock);
+ reparentForDrawing(mLayer, screenshotParentLayer, sourceCrop);
+ }
drawLayers();
+ {
+ Mutex::Autolock _l(mFlinger.mStateLock);
+ mLayer->setChildrenDrawingParent(mLayer);
+ }
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 370afc1265..81afa9b0fa 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -375,6 +375,7 @@ private:
friend class MonitoredProducer;
friend class RefreshRateOverlay;
friend class RegionSamplingThread;
+ friend class LayerRenderArea;
friend class LayerTracing;
// For unit tests