summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishnu Nair <vishnun@google.com>2021-11-26 09:24:11 -0800
committerVishnu Nair <vishnun@google.com>2021-11-29 18:18:02 +0000
commit3bb11d07d941a7db96eefd389862fa1d87c810fc (patch)
tree50e94f389a56a68841a477b898b26f535e569d5d
parent3316c9775acab304c5f790b6fa48a576563b7bcc (diff)
downloadnative-3bb11d07d941a7db96eefd389862fa1d87c810fc.tar.gz
SF: Fix duplicate callbacks from mirrored layers
When cloning layers, we would also clone the layer's callback handles which resulted in SF emitting duplicate callbacks. Test: presubmit Test: launcher does not ANR when switching wallpapers with screen recording enabled Bug: 205922358 Change-Id: Ic0435164f27d9bca7f80fc57d9021a9f544c936f
-rw-r--r--services/surfaceflinger/BufferLayer.cpp2
-rw-r--r--services/surfaceflinger/BufferStateLayer.cpp2
-rw-r--r--services/surfaceflinger/Layer.cpp12
-rw-r--r--services/surfaceflinger/Layer.h1
4 files changed, 12 insertions, 5 deletions
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 71db330f01..8c97f127e5 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -831,7 +831,7 @@ void BufferLayer::updateCloneBufferInfo() {
wp<Layer> tmpTouchableRegionCrop = mDrawingState.touchableRegionCrop;
WindowInfo tmpInputInfo = mDrawingState.inputInfo;
- mDrawingState = clonedFrom->mDrawingState;
+ cloneDrawingState(clonedFrom.get());
mDrawingState.touchableRegionCrop = tmpTouchableRegionCrop;
mDrawingState.zOrderRelativeOf = tmpZOrderRelativeOf;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index cd531d6afc..df91904ac8 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -66,7 +66,7 @@ BufferStateLayer::~BufferStateLayer() {
// one of the layers, in this case the original layer, needs to handle the deletion. The
// original layer and the clone should be removed at the same time so there shouldn't be any
// issue with the clone layer trying to use the texture.
- if (mBufferInfo.mBuffer != nullptr && !isClone()) {
+ if (mBufferInfo.mBuffer != nullptr) {
callReleaseBufferCallback(mDrawingState.releaseBufferListener,
mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
mBufferInfo.mFence, mTransformHint,
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e2f34fabc2..80c61b90f8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2485,8 +2485,7 @@ Region Layer::getVisibleRegion(const DisplayDevice* display) const {
}
void Layer::setInitialValuesForClone(const sp<Layer>& clonedFrom) {
- // copy drawing state from cloned layer
- mDrawingState = clonedFrom->mDrawingState;
+ cloneDrawingState(clonedFrom.get());
mClonedFrom = clonedFrom;
}
@@ -2521,7 +2520,7 @@ void Layer::updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayer
// since we may be able to pull out other children that are still alive.
if (isClonedFromAlive()) {
sp<Layer> clonedFrom = getClonedFrom();
- mDrawingState = clonedFrom->mDrawingState;
+ cloneDrawingState(clonedFrom.get());
clonedLayersMap.emplace(clonedFrom, this);
}
@@ -2684,6 +2683,13 @@ bool Layer::setDropInputMode(gui::DropInputMode mode) {
return true;
}
+void Layer::cloneDrawingState(const Layer* from) {
+ mDrawingState = from->mDrawingState;
+ // Skip callback info since they are not applicable for cloned layers.
+ mDrawingState.releaseBufferListener = nullptr;
+ mDrawingState.callbackHandles = {};
+}
+
// ---------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b107f8e9d7..c1af4685f0 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -929,6 +929,7 @@ protected:
bool isClone() { return mClonedFrom != nullptr; }
bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
+ void cloneDrawingState(const Layer* from);
void updateClonedDrawingState(std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);
void updateClonedChildren(const sp<Layer>& mirrorRoot,
std::map<sp<Layer>, sp<Layer>>& clonedLayersMap);