OSDN Git Service

Change ConsumerBase's FrameAvailableListener to be a weak pointer
authorIgor Murashkin <iam@google.com>
Mon, 29 Oct 2012 20:36:11 +0000 (13:36 -0700)
committerIgor Murashkin <iam@google.com>
Mon, 5 Nov 2012 21:39:02 +0000 (13:39 -0800)
This prevents strong reference cycles when the listener implementation also
holds a strong pointer to the ConsumerBase

Bug: 7425644
Change-Id: I1514b13a32b18d421c902dddebec0765a989c55c

include/gui/ConsumerBase.h
include/gui/SurfaceTexture.h
libs/gui/ConsumerBase.cpp
services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/LayerBase.h

index ee5cb29..5ae5a19 100644 (file)
@@ -78,7 +78,7 @@ public:
 
     // setFrameAvailableListener sets the listener object that will be notified
     // when a new frame becomes available.
-    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+    void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
 
 private:
     ConsumerBase(const ConsumerBase&);
@@ -199,7 +199,7 @@ protected:
     // mFrameAvailableListener is the listener object that will be called when a
     // new frame becomes available. If it is not NULL it will be called from
     // queueBuffer.
-    sp<FrameAvailableListener> mFrameAvailableListener;
+    wp<FrameAvailableListener> mFrameAvailableListener;
 
     // The ConsumerBase has-a BufferQueue and is responsible for creating this object
     // if none is supplied
index 7c519ae..b498a5c 100644 (file)
@@ -33,6 +33,8 @@
 #include <utils/threads.h>
 
 #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
+#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
+                                         "mFrameAvailableListener"
 
 namespace android {
 // ----------------------------------------------------------------------------
index 624d7e0..2e7c424 100644 (file)
@@ -99,7 +99,7 @@ void ConsumerBase::onFrameAvailable() {
     sp<FrameAvailableListener> listener;
     { // scope for the lock
         Mutex::Autolock lock(mMutex);
-        listener = mFrameAvailableListener;
+        listener = mFrameAvailableListener.promote();
     }
 
     if (listener != NULL) {
@@ -148,7 +148,7 @@ void ConsumerBase::abandonLocked() {
 }
 
 void ConsumerBase::setFrameAvailableListener(
-        const sp<FrameAvailableListener>& listener) {
+        const wp<FrameAvailableListener>& listener) {
     CB_LOGV("setFrameAvailableListener");
     Mutex::Autolock lock(mMutex);
     mFrameAvailableListener = listener;
index 064f689..8092a8d 100644 (file)
@@ -82,25 +82,13 @@ void Layer::onFirstRef()
 {
     LayerBaseClient::onFirstRef();
 
-    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
-        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
-    private:
-        wp<Layer> mLayer;
-        virtual void onFrameAvailable() {
-            sp<Layer> that(mLayer.promote());
-            if (that != 0) {
-                that->onFrameQueued();
-            }
-        }
-    };
-
     // Creates a custom BufferQueue for SurfaceTexture to use
     sp<BufferQueue> bq = new SurfaceTextureLayer();
     mSurfaceTexture = new SurfaceTexture(mTextureName, true,
             GL_TEXTURE_EXTERNAL_OES, false, bq);
 
     mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
-    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
+    mSurfaceTexture->setFrameAvailableListener(this);
     mSurfaceTexture->setSynchronousMode(true);
 
 #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
@@ -118,7 +106,7 @@ Layer::~Layer()
     mFlinger->deleteTextureAsync(mTextureName);
 }
 
-void Layer::onFrameQueued() {
+void Layer::onFrameAvailable() {
     android_atomic_inc(&mQueuedFrames);
     mFlinger->signalLayerUpdate();
 }
index 6f75d8c..54099f4 100644 (file)
@@ -47,7 +47,8 @@ class GLExtensions;
 
 // ---------------------------------------------------------------------------
 
-class Layer : public LayerBaseClient
+class Layer : public LayerBaseClient,
+              public SurfaceTexture::FrameAvailableListener
 {
 public:
             Layer(SurfaceFlinger* flinger, const sp<Client>& client);
@@ -102,13 +103,15 @@ protected:
 
 private:
     friend class SurfaceTextureLayer;
-    void onFrameQueued();
     virtual sp<ISurface> createSurface();
     uint32_t getEffectiveUsage(uint32_t usage) const;
     bool isCropped() const;
     Rect computeBufferCrop() const;
     static bool getOpacityForFormat(uint32_t format);
 
+    // Interface implementation for SurfaceTexture::FrameAvailableListener
+    virtual void onFrameAvailable();
+
     // -----------------------------------------------------------------------
 
     // constants
index 00c4ffe..fd80946 100644 (file)
@@ -49,7 +49,7 @@ class SurfaceFlinger;
 
 // ---------------------------------------------------------------------------
 
-class LayerBase : public RefBase
+class LayerBase : virtual public RefBase
 {
     static int32_t sSequence;