From db66e627ad8904491e384c64f82fc77a939b9705 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 10 Apr 2017 16:55:57 -0700 Subject: SurfaceFlinger: Add parent-less relative layering. This is a temporary functionality for the intermediate state where not all child-surface like things in WM land are ported to use Child Surfaces. In particular, we have ported SurfaceView to use child surfaces and relative Z ordering. However the TV frameworks provide a View framework component which overlays views over the SurfaceView but below the main application window. Since we have not ported View framework surfaces to use child layers, there is nothing the WM or View Framework can do about this situation. Luckily the WM API's to have requested this are @hide but we have the one media framework component using it. In order to solve this issue we provide a method to set Z ordering relative to another window without inheriting its coordinate space as a child window would. This way the WM can recognize these TYPE_APPLICATION_MEDIA_OVERLAY windows and Z-order them at -1 with respect to the parents (and the SurfaceView can be at -2). Test: Included in transaction tests. Also manual test of bug repro steps with accomp frameworks/base CL Bug: 36693738 Change-Id: I921852d3d34f67f79ec745b9703f9e679867e7a1 --- services/surfaceflinger/Layer.cpp | 105 ++++++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 15 deletions(-) (limited to 'services/surfaceflinger/Layer.cpp') 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 strongRelative = mCurrentState.zOrderRelativeOf.promote(); + if (strongRelative != nullptr) { + strongRelative->removeZOrderRelative(this); + } + mCurrentState.zOrderRelativeOf = nullptr; + } setTransactionFlags(eTransactionNeeded); return true; } +void Layer::removeZOrderRelative(const wp& relative) { + mCurrentState.zOrderRelatives.remove(relative); + mCurrentState.sequence++; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); +} + +void Layer::addZOrderRelative(const wp& relative) { + mCurrentState.zOrderRelatives.add(relative); + mCurrentState.modified = true; + mCurrentState.sequence++; + setTransactionFlags(eTransactionNeeded); +} + +bool Layer::setRelativeLayer(const sp& relativeToHandle, int32_t z) { + sp handle = static_cast(relativeToHandle.get()); + if (handle == nullptr) { + return false; + } + sp 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& weakRelative : mDrawingState.zOrderRelatives) { + sp 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& 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& 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& 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); } } -- cgit v1.2.3-59-g8ed1b