From e7f8dde3f3c398c1ea1bec14e76725a760f71d31 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Thu, 30 Apr 2015 13:29:25 -0700 Subject: [PATCH] SurfaceFlinger: Limit to 4k Layers Sets a limit of 4k Layers which SurfaceFlinger will allow to be in existence at any given time. An attempt to create Layers in excess of this limit will fail with NO_MEMORY. Bug: 20674586 Change-Id: I2dfaf59643d826f982b2fa44e8a9ed643176d972 --- services/surfaceflinger/SurfaceFlinger.cpp | 29 ++++++++++++++++------ services/surfaceflinger/SurfaceFlinger.h | 4 ++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index df4ac2e66..715b92f11 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1994,18 +1994,25 @@ void SurfaceFlinger::drawWormhole(const sp& hw, const Regio engine.fillRegionWithColor(region, height, 0, 0, 0, 0); } -void SurfaceFlinger::addClientLayer(const sp& client, +status_t SurfaceFlinger::addClientLayer(const sp& client, const sp& handle, const sp& gbc, const sp& lbc) { + // add this layer to the current state list + { + Mutex::Autolock _l(mStateLock); + if (mCurrentState.layersSortedByZ.size() >= MAX_LAYERS) { + return NO_MEMORY; + } + mCurrentState.layersSortedByZ.add(lbc); + mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); + } + // attach this layer to the client client->attachLayer(handle, lbc); - // add this layer to the current state list - Mutex::Autolock _l(mStateLock); - mCurrentState.layersSortedByZ.add(lbc); - mGraphicBufferProducerList.add(IInterface::asBinder(gbc)); + return NO_ERROR; } status_t SurfaceFlinger::removeLayer(const sp& layer) { @@ -2262,10 +2269,16 @@ status_t SurfaceFlinger::createLayer( break; } - if (result == NO_ERROR) { - addClientLayer(client, *handle, *gbp, layer); - setTransactionFlags(eTransactionNeeded); + if (result != NO_ERROR) { + return result; } + + result = addClientLayer(client, *handle, *gbp, layer); + if (result != NO_ERROR) { + return result; + } + + setTransactionFlags(eTransactionNeeded); return result; } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a06d1be1b..74f903148 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -144,6 +144,8 @@ private: // every half hour. enum { LOG_FRAME_STATS_PERIOD = 30*60*60 }; + static const size_t MAX_LAYERS = 4096; + // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); @@ -305,7 +307,7 @@ private: status_t removeLayer(const sp& layer); // add a layer to SurfaceFlinger - void addClientLayer(const sp& client, + status_t addClientLayer(const sp& client, const sp& handle, const sp& gbc, const sp& lbc);