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:
parent
3bc7b27571
commit
a4a3149a36
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -49,7 +49,7 @@ class SurfaceFlinger;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
class LayerBase : public RefBase
|
class LayerBase : virtual public RefBase
|
||||||
{
|
{
|
||||||
static int32_t sSequence;
|
static int32_t sSequence;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue