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:
@ -142,7 +142,8 @@ void Layer::onRemoved()
|
|||||||
|
|
||||||
sp<LayerBaseClient::Surface> Layer::createSurface() const
|
sp<LayerBaseClient::Surface> Layer::createSurface() const
|
||||||
{
|
{
|
||||||
return mSurface;
|
sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
|
||||||
|
return sur;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Layer::ditch()
|
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
|
// the layer is not on screen anymore. free as much resources as possible
|
||||||
mFreezeLock.clear();
|
mFreezeLock.clear();
|
||||||
|
|
||||||
// Free our own reference to ISurface
|
|
||||||
mSurface.clear();
|
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
mWidth = mHeight = 0;
|
mWidth = mHeight = 0;
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
@ -202,7 +200,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
|||||||
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
|
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
|
||||||
mNeedsDithering = layerRedsize > displayRedSize;
|
mNeedsDithering = layerRedsize > displayRedSize;
|
||||||
|
|
||||||
mSurface = new SurfaceLayer(mFlinger, this);
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,6 @@ private:
|
|||||||
ClientRef mUserClientRef;
|
ClientRef mUserClientRef;
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
sp<Surface> mSurface;
|
|
||||||
PixelFormat mFormat;
|
PixelFormat mFormat;
|
||||||
const GLExtensions& mGLExtensions;
|
const GLExtensions& mGLExtensions;
|
||||||
bool mNeedsBlending;
|
bool mNeedsBlending;
|
||||||
|
@ -540,7 +540,9 @@ int32_t LayerBaseClient::sIdentity = 1;
|
|||||||
|
|
||||||
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||||
const sp<Client>& client)
|
const sp<Client>& client)
|
||||||
: LayerBase(flinger, display), mClientRef(client),
|
: LayerBase(flinger, display),
|
||||||
|
mHasSurface(false),
|
||||||
|
mClientRef(client),
|
||||||
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -557,12 +559,13 @@ sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
|
|||||||
{
|
{
|
||||||
sp<Surface> s;
|
sp<Surface> s;
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
s = mClientSurface.promote();
|
|
||||||
if (s == 0) {
|
LOG_ALWAYS_FATAL_IF(mHasSurface,
|
||||||
|
"LayerBaseClient::getSurface() has already been called");
|
||||||
|
|
||||||
|
mHasSurface = true;
|
||||||
s = createSurface();
|
s = createSurface();
|
||||||
mClientSurface = s;
|
|
||||||
mClientSurfaceBinder = s->asBinder();
|
mClientSurfaceBinder = s->asBinder();
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
mutable wp<Surface> mClientSurface;
|
mutable bool mHasSurface;
|
||||||
wp<IBinder> mClientSurfaceBinder;
|
wp<IBinder> mClientSurfaceBinder;
|
||||||
const wp<Client> mClientRef;
|
const wp<Client> mClientRef;
|
||||||
// only read
|
// only read
|
||||||
|
Reference in New Issue
Block a user