OSDN Git Service

fix a surface leak in SurfaceFlinger
authorMathias Agopian <mathias@google.com>
Wed, 16 Feb 2011 03:01:06 +0000 (19:01 -0800)
committerMathias Agopian <mathias@google.com>
Wed, 16 Feb 2011 23:31:07 +0000 (15:31 -0800)
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

services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/LayerBase.cpp
services/surfaceflinger/LayerBase.h

index fde8e67..0f7d639 100644 (file)
@@ -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;
 }
 
index d9a8be3..2b38414 100644 (file)
@@ -213,7 +213,6 @@ private:
     ClientRef mUserClientRef;
 
     // constants
-    sp<Surface> mSurface;
     PixelFormat mFormat;
     const GLExtensions& mGLExtensions;
     bool mNeedsBlending;
index 86057f8..6025ed4 100644 (file)
@@ -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;
 }
 
index 184edd7..bfe92e6 100644 (file)
@@ -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