Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4a3149a authored by Igor Murashkin's avatar Igor Murashkin
Browse files

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
parent 3bc7b275
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include <utils/threads.h>

#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
                                         "mFrameAvailableListener"

namespace android {
// ----------------------------------------------------------------------------
+2 −2
Original line number Diff line number Diff line
@@ -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;
+2 −14
Original line number Diff line number Diff line
@@ -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();
}
+5 −2
Original line number Diff line number Diff line
@@ -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
Loading