diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2022-04-07 00:06:18 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2022-04-07 00:06:18 -0700 |
commit | ede31eb457a1547e9e60a1376d3db7157aa7f3f6 (patch) | |
tree | 6fb524f9d0c58687e5308c31b1ea402f5cfb6402 | |
parent | 3fd75d02744cb2239673fd1958df6651d461be83 (diff) | |
parent | 85389d570c06393d17821c798e4072dd8ca7a1d1 (diff) |
Merge "SurfaceFlinger/LayerRenderArea: Hold lock while modifying hierarchy" into ks-aosp.lnx.12.0.r1-rel
-rw-r--r-- | services/surfaceflinger/LayerRenderArea.cpp | 24 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 |
2 files changed, 14 insertions, 11 deletions
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/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 2096e63575..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; |