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
This commit is contained in:
Dan Stoza 2015-04-30 13:29:25 -07:00
parent 8de71a2408
commit e7f8dde3f3
2 changed files with 24 additions and 9 deletions

View File

@ -1994,18 +1994,25 @@ void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Regio
engine.fillRegionWithColor(region, height, 0, 0, 0, 0); engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
} }
void SurfaceFlinger::addClientLayer(const sp<Client>& client, status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc, const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc) const sp<Layer>& 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 // attach this layer to the client
client->attachLayer(handle, lbc); client->attachLayer(handle, lbc);
// add this layer to the current state list return NO_ERROR;
Mutex::Autolock _l(mStateLock);
mCurrentState.layersSortedByZ.add(lbc);
mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
} }
status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
@ -2262,10 +2269,16 @@ status_t SurfaceFlinger::createLayer(
break; break;
} }
if (result == NO_ERROR) { if (result != NO_ERROR) {
addClientLayer(client, *handle, *gbp, layer); return result;
setTransactionFlags(eTransactionNeeded);
} }
result = addClientLayer(client, *handle, *gbp, layer);
if (result != NO_ERROR) {
return result;
}
setTransactionFlags(eTransactionNeeded);
return result; return result;
} }

View File

@ -144,6 +144,8 @@ private:
// every half hour. // every half hour.
enum { LOG_FRAME_STATS_PERIOD = 30*60*60 }; enum { LOG_FRAME_STATS_PERIOD = 30*60*60 };
static const size_t MAX_LAYERS = 4096;
// We're reference counted, never destroy SurfaceFlinger directly // We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger(); virtual ~SurfaceFlinger();
@ -305,7 +307,7 @@ private:
status_t removeLayer(const sp<Layer>& layer); status_t removeLayer(const sp<Layer>& layer);
// add a layer to SurfaceFlinger // add a layer to SurfaceFlinger
void addClientLayer(const sp<Client>& client, status_t addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc, const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc); const sp<Layer>& lbc);