fix a surface leak in SurfaceFlinger
SF kept a strong reference to ISurface until the window manager removed the surface from the screen. This fell appart when running standalone tests, that is when the window manager wasn't involved. When the window manager is around, it would clean-up surfaces even when an application died. with this change, SF is able to do its own cleanup without relying on the window manager. the change is very simple, we simply don't keep a reference to ISurface and make sure no more than one of them can be created. Change-Id: I61f2d7473bf8d4aa651549a846c34cdbb0d0c85a
This commit is contained in:
parent
395d332627
commit
a1f47b90ab
|
@ -142,7 +142,8 @@ void Layer::onRemoved()
|
|||
|
||||
sp<LayerBaseClient::Surface> Layer::createSurface() const
|
||||
{
|
||||
return mSurface;
|
||||
sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
|
||||
return sur;
|
||||
}
|
||||
|
||||
status_t Layer::ditch()
|
||||
|
@ -152,9 +153,6 @@ status_t Layer::ditch()
|
|||
// the layer is not on screen anymore. free as much resources as possible
|
||||
mFreezeLock.clear();
|
||||
|
||||
// Free our own reference to ISurface
|
||||
mSurface.clear();
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
mWidth = mHeight = 0;
|
||||
return NO_ERROR;
|
||||
|
@ -202,7 +200,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
|||
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
|
||||
mNeedsDithering = layerRedsize > displayRedSize;
|
||||
|
||||
mSurface = new SurfaceLayer(mFlinger, this);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,7 +213,6 @@ private:
|
|||
ClientRef mUserClientRef;
|
||||
|
||||
// constants
|
||||
sp<Surface> mSurface;
|
||||
PixelFormat mFormat;
|
||||
const GLExtensions& mGLExtensions;
|
||||
bool mNeedsBlending;
|
||||
|
|
|
@ -540,7 +540,9 @@ int32_t LayerBaseClient::sIdentity = 1;
|
|||
|
||||
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||
const sp<Client>& client)
|
||||
: LayerBase(flinger, display), mClientRef(client),
|
||||
: LayerBase(flinger, display),
|
||||
mHasSurface(false),
|
||||
mClientRef(client),
|
||||
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
||||
{
|
||||
}
|
||||
|
@ -557,12 +559,13 @@ sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
|
|||
{
|
||||
sp<Surface> s;
|
||||
Mutex::Autolock _l(mLock);
|
||||
s = mClientSurface.promote();
|
||||
if (s == 0) {
|
||||
s = createSurface();
|
||||
mClientSurface = s;
|
||||
mClientSurfaceBinder = s->asBinder();
|
||||
}
|
||||
|
||||
LOG_ALWAYS_FATAL_IF(mHasSurface,
|
||||
"LayerBaseClient::getSurface() has already been called");
|
||||
|
||||
mHasSurface = true;
|
||||
s = createSurface();
|
||||
mClientSurfaceBinder = s->asBinder();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,7 @@ protected:
|
|||
|
||||
private:
|
||||
mutable Mutex mLock;
|
||||
mutable wp<Surface> mClientSurface;
|
||||
mutable bool mHasSurface;
|
||||
wp<IBinder> mClientSurfaceBinder;
|
||||
const wp<Client> mClientRef;
|
||||
// only read
|
||||
|
|
Loading…
Reference in New Issue