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

Commit e392cff3 authored by Sungtak Lee's avatar Sungtak Lee
Browse files

C2BqBuffer: Do not cancel buffer after IGBP is no longer used

Since C2BqBuffer holds IGBP, cancelBuffer() can be called regardless of
IGBP's life-cycle. Do not cancel buffer after IGBP is no longer used
from the BlockPool.

Bug: 227121136
Change-Id: I8092808513365db3c85e250c360469e77d71cabc
parent b5085dfe
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -129,8 +129,9 @@ public:
    // Create a local BlockPoolData.
    C2BufferQueueBlockPoolData(
            uint32_t generation, uint64_t bqId, int32_t bqSlot,
            const std::shared_ptr<int> &owner,
            const android::sp<HGraphicBufferProducer>& producer,
            std::shared_ptr<C2SurfaceSyncMemory>, int noUse);
            std::shared_ptr<C2SurfaceSyncMemory>);

    virtual ~C2BufferQueueBlockPoolData() override;

+27 −9
Original line number Diff line number Diff line
@@ -542,7 +542,7 @@ private:
                        std::make_shared<C2BufferQueueBlockPoolData>(
                                slotBuffer->getGenerationNumber(),
                                mProducerId, slot,
                                mProducer, mSyncMem, 0);
                                mIgbpValidityToken, mProducer, mSyncMem);
                mPoolDatas[slot] = poolData;
                *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
                return C2_OK;
@@ -572,10 +572,11 @@ public:
    Impl(const std::shared_ptr<C2Allocator> &allocator)
        : mInit(C2_OK), mProducerId(0), mGeneration(0),
          mConsumerUsage(0), mDqFailure(0), mLastDqTs(0),
          mLastDqLogTs(0), mAllocator(allocator) {
          mLastDqLogTs(0), mAllocator(allocator), mIgbpValidityToken(std::make_shared<int>(0)) {
    }

    ~Impl() {
        mIgbpValidityToken.reset();
        for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
            mBuffers[i].clear();
        }
@@ -618,7 +619,7 @@ public:
            }
            std::shared_ptr<C2BufferQueueBlockPoolData> poolData =
                    std::make_shared<C2BufferQueueBlockPoolData>(
                            0, (uint64_t)0, ~0, nullptr, nullptr, 0);
                            0, (uint64_t)0, ~0, nullptr, nullptr, nullptr);
            *block = _C2BlockFactory::CreateGraphicBlock(alloc, poolData);
            ALOGV("allocated a buffer successfully");

@@ -694,8 +695,7 @@ public:
                mProducer = nullptr;
                mProducerId = 0;
                mGeneration = 0;
                ALOGW("invalid producer producer(%d), generation(%d)",
                      (bool)producer, bqInformation);
                ALOGD("configuring null producer: igbp_information(%d)", bqInformation);
            }
            oldMem = mSyncMem; // preven destruction while locked.
            mSyncMem = c2SyncMem;
@@ -720,6 +720,10 @@ public:
                        }
                    }
                }
            } else {
                // old buffers should not be cancelled since the associated IGBP
                // is no longer valid.
                mIgbpValidityToken = std::make_shared<int>(0);
            }
            for (int i = 0; i < NUM_BUFFER_SLOTS; ++i) {
                mBuffers[i] = buffers[i];
@@ -761,6 +765,20 @@ private:
    std::weak_ptr<C2BufferQueueBlockPoolData> mPoolDatas[NUM_BUFFER_SLOTS];

    std::shared_ptr<C2SurfaceSyncMemory> mSyncMem;

    // IGBP invalidation notification token.
    // The buffers(C2BufferQueueBlockPoolData) has the reference to the IGBP where
    // they belong in order to call IGBP::cancelBuffer() when they are of no use.
    //
    // In certain cases, IGBP is no longer used by this class(actually MediaCodec)
    // any more and the situation needs to be addressed quickly. In order to
    // achieve those, std::shared_ptr<> is used as a token for quick IGBP invalidation
    // notification from the buffers.
    //
    // The buffer side will have the reference of the token as std::weak_ptr<>.
    // if the token has been expired, the buffers will not call IGBP::cancelBuffer()
    // when they are no longer used.
    std::shared_ptr<int> mIgbpValidityToken;
};

C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(
@@ -776,14 +794,14 @@ C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(

C2BufferQueueBlockPoolData::C2BufferQueueBlockPoolData(
        uint32_t generation, uint64_t bqId, int32_t bqSlot,
        const std::shared_ptr<int>& owner,
        const android::sp<HGraphicBufferProducer>& producer,
        std::shared_ptr<C2SurfaceSyncMemory> syncMem, int noUse) :
        std::shared_ptr<C2SurfaceSyncMemory> syncMem) :
        mLocal(true), mHeld(true),
        mGeneration(generation), mBqId(bqId), mBqSlot(bqSlot),
        mCurrentGeneration(generation), mCurrentBqId(bqId),
        mTransfer(false), mAttach(false), mDisplay(false),
        mIgbp(producer), mSyncMem(syncMem) {
            (void)noUse;
        mOwner(owner), mIgbp(producer), mSyncMem(syncMem) {
}

C2BufferQueueBlockPoolData::~C2BufferQueueBlockPoolData() {
@@ -792,7 +810,7 @@ C2BufferQueueBlockPoolData::~C2BufferQueueBlockPoolData() {
    }

    if (mLocal) {
        if (mGeneration == mCurrentGeneration && mBqId == mCurrentBqId) {
        if (mGeneration == mCurrentGeneration && mBqId == mCurrentBqId && !mOwner.expired()) {
            C2SyncVariables *syncVar = mSyncMem ? mSyncMem->mem() : nullptr;
            if (syncVar) {
                syncVar->lock();