diff options
| author | 2022-03-23 22:14:45 +0000 | |
|---|---|---|
| committer | 2022-03-23 22:14:45 +0000 | |
| commit | a8ceadf9010e09678ff4df577f44f70eaaf69497 (patch) | |
| tree | 8716042ae023043313e0a0bb70a72e237883b759 | |
| parent | af5fa6bf7519e780e017cd1af87ed0a4b3dcb5b8 (diff) | |
| parent | 88b85e1f9b2fb3cf1ab9da1967e1d454be2d5be0 (diff) | |
Merge "SurfaceFlinger: Detect Rel Z loops" into tm-dev
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 31 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 1 |
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); |