summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rob Carr <racarr@google.com> 2022-03-23 22:14:45 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-03-23 22:14:45 +0000
commita8ceadf9010e09678ff4df577f44f70eaaf69497 (patch)
tree8716042ae023043313e0a0bb70a72e237883b759
parentaf5fa6bf7519e780e017cd1af87ed0a4b3dcb5b8 (diff)
parent88b85e1f9b2fb3cf1ab9da1967e1d454be2d5be0 (diff)
Merge "SurfaceFlinger: Detect Rel Z loops" into tm-dev
-rw-r--r--services/surfaceflinger/Layer.cpp31
-rw-r--r--services/surfaceflinger/Layer.h1
2 files changed, 32 insertions, 0 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ac7bcde7a8..224faf107e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -833,6 +833,14 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati
return false;
}
+ if (CC_UNLIKELY(relative->usingRelativeZ(LayerVector::StateSet::Drawing)) &&
+ (relative->mDrawingState.zOrderRelativeOf == this)) {
+ ALOGE("Detected relative layer loop between %s and %s",
+ mName.c_str(), relative->mName.c_str());
+ ALOGE("Ignoring new call to set relative layer");
+ return false;
+ }
+
mFlinger->mSomeChildrenChanged = true;
mDrawingState.sequence++;
@@ -1990,6 +1998,18 @@ void Layer::prepareShadowClientComposition(LayerFE::LayerSettings& caster,
}
}
+bool Layer::findInHierarchy(const sp<Layer>& l) {
+ if (l == this) {
+ return true;
+ }
+ for (auto& child : mDrawingChildren) {
+ if (child->findInHierarchy(l)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
const auto& child = mCurrentChildren[i];
@@ -1997,6 +2017,17 @@ void Layer::commitChildList() {
}
mDrawingChildren = mCurrentChildren;
mDrawingParent = mCurrentParent;
+ if (CC_UNLIKELY(usingRelativeZ(LayerVector::StateSet::Drawing))) {
+ auto zOrderRelativeOf = mDrawingState.zOrderRelativeOf.promote();
+ if (zOrderRelativeOf == nullptr) return;
+ if (findInHierarchy(zOrderRelativeOf)) {
+ ALOGE("Detected Z ordering loop between %s and %s", mName.c_str(),
+ zOrderRelativeOf->mName.c_str());
+ ALOGE("Severing rel Z loop, potentially dangerous");
+ mDrawingState.isRelativeOf = false;
+ zOrderRelativeOf->removeZOrderRelative(this);
+ }
+ }
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 48a9bc50c4..846460d4b1 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1138,6 +1138,7 @@ private:
bool mIsAtRoot = false;
uint32_t mLayerCreationFlags;
+ bool findInHierarchy(const sp<Layer>&);
};
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);