diff options
author | Chia-I Wu <olv@google.com> | 2017-06-06 15:32:08 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-06-06 15:32:10 +0000 |
commit | 39cf8b4944bbbaeeabae357ef2122bfc4457f211 (patch) | |
tree | f8f8140fb9c63cf3755a2125be4820f6acb9448d | |
parent | eed865e61b98aa3cae2b323cc95930b430ed1e8c (diff) | |
parent | e6b63e1ae12692327f7e46d5f10d6ade5a7bf192 (diff) | |
download | native-39cf8b4944bbbaeeabae357ef2122bfc4457f211.tar.gz |
Merge "surfaceflinger: fix layer count" into oc-dev
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 18 |
3 files changed, 26 insertions, 1 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6f430a386f..2ff14aa395 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2523,6 +2523,14 @@ bool Layer::getTransformToDisplayInverse() const { return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); } +size_t Layer::getChildrenCount() const { + size_t count = 0; + for (const sp<Layer>& child : mCurrentChildren) { + count += 1 + child->getChildrenCount(); + } + return count; +} + void Layer::addChild(const sp<Layer>& layer) { mCurrentChildren.add(layer); layer->setParent(this); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 05c367dfad..5335fff9ff 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -519,6 +519,7 @@ public: const LayerVector::Visitor& visitor); void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor); + size_t getChildrenCount() const; void addChild(const sp<Layer>& layer); // Returns index if removed, or negative value otherwise // for symmetry with Vector::remove diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 29a8292ff6..801e8ddf4d 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2656,8 +2656,13 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, if (parent == nullptr) { mCurrentState.layersSortedByZ.add(lbc); } else { + if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) { + ALOGE("addClientLayer called with a removed parent"); + return NAME_NOT_FOUND; + } parent->addChild(lbc); } + mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); mLayersAdded = true; mNumLayers++; @@ -2676,6 +2681,17 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { const ssize_t index = (p != nullptr) ? p->removeChild(layer) : mCurrentState.layersSortedByZ.remove(layer); + if (p != nullptr) { + sp<Layer> ancestor = p; + while (ancestor->getParent() != nullptr) { + ancestor = ancestor->getParent(); + } + if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) { + ALOGE("removeLayer called with a layer whose parent has been removed"); + return NAME_NOT_FOUND; + } + } + // As a matter of normal operation, the LayerCleaner will produce a second // attempt to remove the surface. The Layer will be kept alive in mDrawingState // so we will succeed in promoting it, but it's already been removed @@ -2692,7 +2708,7 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { mLayersPendingRemoval.add(layer); mLayersRemoved = true; - mNumLayers--; + mNumLayers -= 1 + layer->getChildrenCount(); setTransactionFlags(eTransactionNeeded); return NO_ERROR; } |