Change ConsumerBase's FrameAvailableListener to be a weak pointer

This prevents strong reference cycles when the listener implementation also
holds a strong pointer to the ConsumerBase

Bug: 7425644
Change-Id: I1514b13a32b18d421c902dddebec0765a989c55c
This commit is contained in:
Igor Murashkin 2012-10-29 13:36:11 -07:00
parent 3bc7b27571
commit a4a3149a36
6 changed files with 14 additions and 21 deletions

View File

@ -78,7 +78,7 @@ public:
// setFrameAvailableListener sets the listener object that will be notified // setFrameAvailableListener sets the listener object that will be notified
// when a new frame becomes available. // when a new frame becomes available.
void setFrameAvailableListener(const sp<FrameAvailableListener>& listener); void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
private: private:
ConsumerBase(const ConsumerBase&); ConsumerBase(const ConsumerBase&);
@ -199,7 +199,7 @@ protected:
// mFrameAvailableListener is the listener object that will be called when a // 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 // new frame becomes available. If it is not NULL it will be called from
// queueBuffer. // queueBuffer.
sp<FrameAvailableListener> mFrameAvailableListener; wp<FrameAvailableListener> mFrameAvailableListener;
// The ConsumerBase has-a BufferQueue and is responsible for creating this object // The ConsumerBase has-a BufferQueue and is responsible for creating this object
// if none is supplied // if none is supplied

View File

@ -33,6 +33,8 @@
#include <utils/threads.h> #include <utils/threads.h>
#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture" #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
"mFrameAvailableListener"
namespace android { namespace android {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -99,7 +99,7 @@ void ConsumerBase::onFrameAvailable() {
sp<FrameAvailableListener> listener; sp<FrameAvailableListener> listener;
{ // scope for the lock { // scope for the lock
Mutex::Autolock lock(mMutex); Mutex::Autolock lock(mMutex);
listener = mFrameAvailableListener; listener = mFrameAvailableListener.promote();
} }
if (listener != NULL) { if (listener != NULL) {
@ -148,7 +148,7 @@ void ConsumerBase::abandonLocked() {
} }
void ConsumerBase::setFrameAvailableListener( void ConsumerBase::setFrameAvailableListener(
const sp<FrameAvailableListener>& listener) { const wp<FrameAvailableListener>& listener) {
CB_LOGV("setFrameAvailableListener"); CB_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mMutex); Mutex::Autolock lock(mMutex);
mFrameAvailableListener = listener; mFrameAvailableListener = listener;

View File

@ -82,25 +82,13 @@ void Layer::onFirstRef()
{ {
LayerBaseClient::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 // Creates a custom BufferQueue for SurfaceTexture to use
sp<BufferQueue> bq = new SurfaceTextureLayer(); sp<BufferQueue> bq = new SurfaceTextureLayer();
mSurfaceTexture = new SurfaceTexture(mTextureName, true, mSurfaceTexture = new SurfaceTexture(mTextureName, true,
GL_TEXTURE_EXTERNAL_OES, false, bq); GL_TEXTURE_EXTERNAL_OES, false, bq);
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); mSurfaceTexture->setFrameAvailableListener(this);
mSurfaceTexture->setSynchronousMode(true); mSurfaceTexture->setSynchronousMode(true);
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING #ifdef TARGET_DISABLE_TRIPLE_BUFFERING
@ -118,7 +106,7 @@ Layer::~Layer()
mFlinger->deleteTextureAsync(mTextureName); mFlinger->deleteTextureAsync(mTextureName);
} }
void Layer::onFrameQueued() { void Layer::onFrameAvailable() {
android_atomic_inc(&mQueuedFrames); android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate(); mFlinger->signalLayerUpdate();
} }

View File

@ -47,7 +47,8 @@ class GLExtensions;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class Layer : public LayerBaseClient class Layer : public LayerBaseClient,
public SurfaceTexture::FrameAvailableListener
{ {
public: public:
Layer(SurfaceFlinger* flinger, const sp<Client>& client); Layer(SurfaceFlinger* flinger, const sp<Client>& client);
@ -102,13 +103,15 @@ protected:
private: private:
friend class SurfaceTextureLayer; friend class SurfaceTextureLayer;
void onFrameQueued();
virtual sp<ISurface> createSurface(); virtual sp<ISurface> createSurface();
uint32_t getEffectiveUsage(uint32_t usage) const; uint32_t getEffectiveUsage(uint32_t usage) const;
bool isCropped() const; bool isCropped() const;
Rect computeBufferCrop() const; Rect computeBufferCrop() const;
static bool getOpacityForFormat(uint32_t format); static bool getOpacityForFormat(uint32_t format);
// Interface implementation for SurfaceTexture::FrameAvailableListener
virtual void onFrameAvailable();
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// constants // constants

View File

@ -49,7 +49,7 @@ class SurfaceFlinger;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class LayerBase : public RefBase class LayerBase : virtual public RefBase
{ {
static int32_t sSequence; static int32_t sSequence;