Correct setLayer variants.
Correct a legitimate bug in setLayer where it would fail
to clear a relative layer equal to the new absolute layer. Optimize
all the other variants to not trigger rebuilding of layer stacks in
the case of redundant Z setting.
Test: Existing tests pass.
Change-Id: I6559322017a7b8c5510f8ff265216af3d414696a
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 298f597..ff5e6f6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1109,8 +1109,9 @@
if (childLayer->setLayer(z)) {
mCurrentChildren.removeAt(idx);
mCurrentChildren.add(childLayer);
+ return true;
}
- return true;
+ return false;
}
bool Layer::setChildRelativeLayer(const sp<Layer>& childLayer,
@@ -1122,12 +1123,13 @@
if (childLayer->setRelativeLayer(relativeToHandle, relativeZ)) {
mCurrentChildren.removeAt(idx);
mCurrentChildren.add(childLayer);
+ return true;
}
- return true;
+ return false;
}
bool Layer::setLayer(int32_t z) {
- if (mCurrentState.z == z) return false;
+ if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
mCurrentState.sequence++;
mCurrentState.z = z;
mCurrentState.modified = true;
@@ -1158,7 +1160,7 @@
setTransactionFlags(eTransactionNeeded);
}
-bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t z) {
+bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
if (handle == nullptr) {
return false;
@@ -1168,9 +1170,14 @@
return false;
}
+ if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
+ mCurrentState.zOrderRelativeOf == relative) {
+ return false;
+ }
+
mCurrentState.sequence++;
mCurrentState.modified = true;
- mCurrentState.z = z;
+ mCurrentState.z = relativeZ;
auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
if (oldZOrderRelativeOf != nullptr) {