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

Commit 2e979ed0 authored by Sungtak Lee's avatar Sungtak Lee
Browse files

C2BqBuffer: defer GraphicBuffer cache clearing after stop()

Also enable vendors to control the deferring behavior using
int32 property: "debug.codec2.bqpool_dealloc_after_stop"
 0         : no deferred clear
 any value : deferred clear(only on swcodec)

Bug: 322731059
Change-Id: I92cdb1bfcd7856646cb1baa659bf273344cd6e11
parent 8175aea2
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -521,7 +521,18 @@ Return<Status> Component::start() {

Return<Status> Component::stop() {
    InputBufferManager::unregisterFrameData(mListener);
    return static_cast<Status>(mComponent->stop());
    Status status = static_cast<Status>(mComponent->stop());
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->clearDeferredBlocks();
            }
        }
    }
    return status;
}

Return<Status> Component::reset() {
+12 −1
Original line number Diff line number Diff line
@@ -527,7 +527,18 @@ Return<Status> Component::start() {

Return<Status> Component::stop() {
    InputBufferManager::unregisterFrameData(mListener);
    return static_cast<Status>(mComponent->stop());
    Status status = static_cast<Status>(mComponent->stop());
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->clearDeferredBlocks();
            }
        }
    }
    return status;
}

Return<Status> Component::reset() {
+12 −1
Original line number Diff line number Diff line
@@ -523,7 +523,18 @@ Return<Status> Component::start() {

Return<Status> Component::stop() {
    InputBufferManager::unregisterFrameData(mListener);
    return static_cast<Status>(mComponent->stop());
    Status status = static_cast<Status>(mComponent->stop());
    {
        std::lock_guard<std::mutex> lock(mBlockPoolsMutex);
        for (auto it = mBlockPools.begin(); it != mBlockPools.end(); ++it) {
            if (it->second->getAllocatorId() == C2PlatformAllocatorStore::BUFFERQUEUE) {
                std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                        std::static_pointer_cast<C2BufferQueueBlockPool>(it->second);
                bqPool->clearDeferredBlocks();
            }
        }
    }
    return status;
}

Return<Status> Component::reset() {
+23 −3
Original line number Diff line number Diff line
@@ -478,13 +478,25 @@ static C2PooledBlockPool::BufferPoolVer GetBufferPoolVer() {

class _C2BlockPoolCache {
public:
    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {}
    _C2BlockPoolCache() : mBlockPoolSeqId(C2BlockPool::PLATFORM_START + 1) {
        mBqPoolDeferDeallocAfterStop = false;
#ifdef __ANDROID_APEX__
        bool stopHalBeforeSurface = ::android::base::GetBoolProperty(
                "debug.codec2.stop_hal_before_surface", false);
        if (!stopHalBeforeSurface) {
            mBqPoolDeferDeallocAfterStop =
                    ::android::base::GetIntProperty(
                            "debug.codec2.bqpool_dealloc_after_stop", 0) != 0;
        }
#endif
    }

private:
    c2_status_t _createBlockPool(
            C2PlatformAllocatorDesc &allocatorParam,
            std::vector<std::shared_ptr<const C2Component>> components,
            C2BlockPool::local_id_t poolId,
            bool deferDeallocAfterStop,
            std::shared_ptr<C2BlockPool> *pool) {
        std::shared_ptr<C2AllocatorStore> allocatorStore =
                GetCodec2PlatformAllocatorStore();
@@ -548,6 +560,11 @@ private:
                if (res == C2_OK) {
                    std::shared_ptr<C2BlockPool> ptr(
                            new C2BufferQueueBlockPool(allocator, poolId), deleter);
                    if (deferDeallocAfterStop) {
                        std::shared_ptr<C2BufferQueueBlockPool> bqPool =
                            std::static_pointer_cast<C2BufferQueueBlockPool>(ptr);
                        bqPool->setDeferDeallocationAfterStop();
                    }
                    *pool = ptr;
                    mBlockPools[poolId] = ptr;
                    mComponents[poolId].insert(
@@ -603,7 +620,8 @@ public:
            std::vector<std::shared_ptr<const C2Component>> components,
            std::shared_ptr<C2BlockPool> *pool) {
        std::unique_lock lock(mMutex);
        return _createBlockPool(allocator, components, mBlockPoolSeqId++, pool);
        return _createBlockPool(allocator, components, mBlockPoolSeqId++,
                                mBqPoolDeferDeallocAfterStop, pool);
    }


@@ -638,7 +656,7 @@ public:
            C2PlatformAllocatorDesc allocator;
            allocator.allocatorId = C2PlatformAllocatorStore::BUFFERQUEUE;
            return _createBlockPool(
                    allocator, {component}, blockPoolId, pool);
                    allocator, {component}, blockPoolId, mBqPoolDeferDeallocAfterStop, pool);
        }
        return C2_NOT_FOUND;
    }
@@ -651,6 +669,8 @@ private:

    std::map<C2BlockPool::local_id_t, std::weak_ptr<C2BlockPool>> mBlockPools;
    std::map<C2BlockPool::local_id_t, std::vector<std::weak_ptr<const C2Component>>> mComponents;

    bool mBqPoolDeferDeallocAfterStop;
};

static std::unique_ptr<_C2BlockPoolCache> sBlockPoolCache =
+42 −0
Original line number Diff line number Diff line
@@ -28,6 +28,24 @@ namespace android {
class GraphicBuffer;
}  // namespace android

/**
 * BufferQueue based BlockPool.
 *
 * This creates graphic blocks from BufferQueue. BufferQueue here is HIDL-ized IGBP.
 * HIDL-ized IGBP enables vendor HAL to call IGBP interfaces via HIDL over process boundary.
 * HIDL-ized IGBP is called as HGBP. HGBP had been used from multiple places in android,
 * but now this is the only place HGBP is still used.
 *
 * Initially there is no HGBP configured, in the case graphic blocks are allocated
 * from gralloc directly upon \fetchGraphicBlock() requests.
 *
 * HGBP can be configured as null as well, in the case graphic blocks are allocated
 * from gralloc directly upon \fetchGraphicBlock() requests.
 *
 * If a specific HGBP is configured, the HGBP acts as an allocator for creating graphic blocks.
 *
 * TODO: add more ducumentation(graphic block life-cycle, waitable object and workaounds)
 */
class C2BufferQueueBlockPool : public C2BlockPool {
public:
    C2BufferQueueBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
@@ -77,6 +95,8 @@ public:
     * is configured as nullptr, unique id which is bundled in native_handle is zero.
     *
     * \param producer      the IGBP, which will be used to fetch blocks
     *                      This could be null, in the case this blockpool will
     *                      allocate backed GraphicBuffer via allocator(gralloc).
     */
    virtual void configureProducer(const android::sp<HGraphicBufferProducer> &producer);

@@ -89,6 +109,8 @@ public:
     * is configured as nullptr, unique id which is bundled in native_handle is zero.
     *
     * \param producer      the IGBP, which will be used to fetch blocks
     *                      This could be null, in the case this blockpool will
     *                      allocate backed GraphicBuffer via allocator(gralloc).
     * \param syncMemory    Shared memory for synchronization of allocation & deallocation.
     * \param bqId          Id of IGBP
     * \param generationId  Generation Id for rendering output
@@ -110,6 +132,26 @@ public:
     */
    virtual void invalidate();

    /**
     * Defer deallocation of cached blocks.
     *
     * Deallocation of cached blocks will be deferred until
     * \clearDeferredBlocks() is called. Or a new block allocation is
     * requested by \fetchGraphicBlock().
     */
    void setDeferDeallocationAfterStop();


    /**
     * Clear deferred blocks.
     *
     * Deallocation of cached blocks can be deferred by
     * \setDeferDeallocationAfterStop().
     * clear(deallocate) those deferred cached blocks explicitly.
     * Use this interface, if the blockpool could be inactive indefinitely.
     */
    void clearDeferredBlocks();

private:
    const std::shared_ptr<C2Allocator> mAllocator;
    const local_id_t mLocalId;
Loading