@@ -1082,8 +1082,12 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
10821082
10831083status_t SurfaceFlinger::purgatorizeLayer_l (const sp<LayerBase>& layerBase)
10841084{
1085- // remove the layer from the main list (through a transaction).
1085+ // First add the layer to the purgatory list, which makes sure it won't
1086+ // go away, then remove it from the main list (through a transaction).
10861087 ssize_t err = removeLayer_l (layerBase);
1088+ if (err >= 0 ) {
1089+ mLayerPurgatory .add (layerBase);
1090+ }
10871091
10881092 layerBase->onRemoved ();
10891093
@@ -1354,6 +1358,19 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
13541358 * to use the purgatory.
13551359 */
13561360 status_t err = flinger->removeLayer_l (l);
1361+ if (err == NAME_NOT_FOUND) {
1362+ // The surface wasn't in the current list, which means it was
1363+ // removed already, which means it is in the purgatory,
1364+ // and need to be removed from there.
1365+ // This needs to happen from the main thread since its dtor
1366+ // must run from there (b/c of OpenGL ES). Additionally, we
1367+ // can't really acquire our internal lock from
1368+ // destroySurface() -- see postMessage() below.
1369+ ssize_t idx = flinger->mLayerPurgatory .remove (l);
1370+ LOGE_IF (idx < 0 ,
1371+ " layer=%p is not in the purgatory list" , l.get ());
1372+ }
1373+
13571374 LOGE_IF (err<0 && err != NAME_NOT_FOUND,
13581375 " error removing layer=%p (%s)" , l.get (), strerror (-err));
13591376 return true ;
@@ -1469,8 +1486,13 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
14691486 result.append (buffer);
14701487 }
14711488
1489+ /*
1490+ * Dump the visible layer list
1491+ */
14721492 const LayerVector& currentLayers = mCurrentState .layersSortedByZ ;
14731493 const size_t count = currentLayers.size ();
1494+ snprintf (buffer, SIZE, " Visible layers (count = %d)\n " , count);
1495+ result.append (buffer);
14741496 for (size_t i=0 ; i<count ; i++) {
14751497 const sp<LayerBase>& layer (currentLayers[i]);
14761498 layer->dump (result, buffer, SIZE);
@@ -1480,6 +1502,24 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
14801502 layer->visibleRegionScreen .dump (result, " visibleRegionScreen" );
14811503 }
14821504
1505+ /*
1506+ * Dump the layers in the purgatory
1507+ */
1508+
1509+ const size_t purgatorySize = mLayerPurgatory .size ();
1510+ snprintf (buffer, SIZE, " Purgatory state (%d entries)\n " , purgatorySize);
1511+ result.append (buffer);
1512+ for (size_t i=0 ; i<purgatorySize ; i++) {
1513+ const sp<LayerBase>& layer (mLayerPurgatory .itemAt (i));
1514+ layer->shortDump (result, buffer, SIZE);
1515+ }
1516+
1517+ /*
1518+ * Dump SurfaceFlinger global state
1519+ */
1520+
1521+ snprintf (buffer, SIZE, " SurfaceFlinger global state\n " );
1522+ result.append (buffer);
14831523 mWormholeRegion .dump (result, " WormholeRegion" );
14841524 const DisplayHardware& hw (graphicPlane (0 ).displayHardware ());
14851525 snprintf (buffer, SIZE,
@@ -1505,6 +1545,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
15051545 result.append (buffer);
15061546 }
15071547
1548+ /*
1549+ * Dump gralloc state
1550+ */
15081551 const GraphicBufferAllocator& alloc (GraphicBufferAllocator::get ());
15091552 alloc.dump (result);
15101553
0 commit comments