summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/LayerRenderArea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/LayerRenderArea.cpp')
-rw-r--r--services/surfaceflinger/LayerRenderArea.cpp38
1 files changed, 27 insertions, 11 deletions
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index e84508febc..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
@@ -94,19 +88,41 @@ void LayerRenderArea::render(std::function<void()> drawLayers) {
// no need to check rotation because there is none
mNeedsFiltering = sourceCrop.width() != getReqWidth() || sourceCrop.height() != getReqHeight();
+ // If layer is offscreen, update mirroring info if it exists
+ if (mLayer->isRemovedFromCurrentState()) {
+ mLayer->traverse(LayerVector::StateSet::Drawing,
+ [&](Layer* layer) { layer->updateMirrorInfo(); });
+ mLayer->traverse(LayerVector::StateSet::Drawing,
+ [&](Layer* layer) { layer->updateCloneBufferInfo(); });
+ }
+
if (!mChildrenOnly) {
mTransform = mLayer->getTransform().inverse();
+ // If the layer is offscreen, compute bounds since we don't compute bounds for offscreen
+ // layers in a regular cycles.
+ if (mLayer->isRemovedFromCurrentState()) {
+ FloatRect maxBounds = mFlinger.getMaxDisplayBounds();
+ mLayer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
+ }
drawLayers();
} else {
uint32_t w = static_cast<uint32_t>(getWidth());
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);
+ }
}
}