diff options
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 105 |
1 files changed, 90 insertions, 15 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c211c7b4ed..b10d437fea 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1719,10 +1719,55 @@ bool Layer::setLayer(int32_t z) { mCurrentState.sequence++; mCurrentState.z = z; mCurrentState.modified = true; + + // Discard all relative layering. + if (mCurrentState.zOrderRelativeOf != nullptr) { + sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote(); + if (strongRelative != nullptr) { + strongRelative->removeZOrderRelative(this); + } + mCurrentState.zOrderRelativeOf = nullptr; + } setTransactionFlags(eTransactionNeeded); return true; } +void Layer::removeZOrderRelative(const wp<Layer>& relative) { + mCurrentState.zOrderRelatives.remove(relative); + mCurrentState.sequence++; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); +} + +void Layer::addZOrderRelative(const wp<Layer>& relative) { + mCurrentState.zOrderRelatives.add(relative); + mCurrentState.modified = true; + mCurrentState.sequence++; + setTransactionFlags(eTransactionNeeded); +} + +bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t z) { + sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get()); + if (handle == nullptr) { + return false; + } + sp<Layer> relative = handle->owner.promote(); + if (relative == nullptr) { + return false; + } + + mCurrentState.sequence++; + mCurrentState.modified = true; + mCurrentState.z = z; + + mCurrentState.zOrderRelativeOf = relative; + relative->addZOrderRelative(this); + + setTransactionFlags(eTransactionNeeded); + + return true; +} + bool Layer::setSize(uint32_t w, uint32_t h) { if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) return false; @@ -2506,40 +2551,70 @@ int32_t Layer::getZ() const { return mDrawingState.z; } +LayerVector Layer::makeTraversalList() { + if (mDrawingState.zOrderRelatives.size() == 0) { + return mDrawingChildren; + } + LayerVector traverse; + + for (const wp<Layer>& weakRelative : mDrawingState.zOrderRelatives) { + sp<Layer> strongRelative = weakRelative.promote(); + if (strongRelative != nullptr) { + traverse.add(strongRelative); + } else { + // We need to erase from current state instead of drawing + // state so we don't overwrite when copying + // the current state to the drawing state. + mCurrentState.zOrderRelatives.remove(weakRelative); + } + } + + for (const sp<Layer>& child : mDrawingChildren) { + traverse.add(child); + } + + return traverse; +} + /** - * Negatively signed children are before 'this' in Z-order. + * Negatively signed relatives are before 'this' in Z-order. */ void Layer::traverseInZOrder(const std::function<void(Layer*)>& exec) { + LayerVector list = makeTraversalList(); + size_t i = 0; - for (; i < mDrawingChildren.size(); i++) { - const auto& child = mDrawingChildren[i]; - if (child->getZ() >= 0) + for (; i < list.size(); i++) { + const auto& relative = list[i]; + if (relative->getZ() >= 0) { break; - child->traverseInZOrder(exec); + } + relative->traverseInZOrder(exec); } exec(this); - for (; i < mDrawingChildren.size(); i++) { - const auto& child = mDrawingChildren[i]; - child->traverseInZOrder(exec); + for (; i < list.size(); i++) { + const auto& relative = list[i]; + relative->traverseInZOrder(exec); } } /** - * Positively signed children are before 'this' in reverse Z-order. + * Positively signed relatives are before 'this' in reverse Z-order. */ void Layer::traverseInReverseZOrder(const std::function<void(Layer*)>& exec) { + LayerVector list = makeTraversalList(); + int32_t i = 0; - for (i = mDrawingChildren.size()-1; i>=0; i--) { - const auto& child = mDrawingChildren[i]; - if (child->getZ() < 0) { + for (i = list.size()-1; i>=0; i--) { + const auto& relative = list[i]; + if (relative->getZ() < 0) { break; } - child->traverseInReverseZOrder(exec); + relative->traverseInReverseZOrder(exec); } exec(this); for (; i>=0; i--) { - const auto& child = mDrawingChildren[i]; - child->traverseInReverseZOrder(exec); + const auto& relative = list[i]; + relative->traverseInReverseZOrder(exec); } } |