summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/Layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r--services/surfaceflinger/Layer.cpp105
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);
}
}