// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//#define LOG_NDEBUG 0
#define LOG_TAG "C2VdaBqBlockPool"

#include <v4l2_codec2/plugin_store/C2VdaBqBlockPool.h>

#include <errno.h>
#include <string.h>

#include <chrono>
#include <mutex>
#include <set>
#include <sstream>
#include <thread>

#include <C2AllocatorGralloc.h>
#include <C2BlockInternal.h>
#include <C2SurfaceSyncObj.h>
#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h>
#include <base/callback.h>
#include <log/log.h>
#include <ui/BufferQueueDefs.h>

#include <v4l2_codec2/plugin_store/DmabufHelpers.h>
#include <v4l2_codec2/plugin_store/H2BGraphicBufferProducer.h>
#include <v4l2_codec2/plugin_store/V4L2AllocatorId.h>

namespace android {
namespace {

// The wait time for acquire fence in milliseconds. The normal display is 60Hz,
// which period is 16ms. We choose 2x period as timeout.
constexpr int kFenceWaitTimeMs = 32;

// The default maximum dequeued buffer count of IGBP. Currently we don't use
// this value to restrict the count of allocated buffers, so we choose a huge
// enough value here.
constexpr int kMaxDequeuedBufferCount = 32u;

}  // namespace

using namespace std::chrono_literals;

// Type for IGBP slot index.
using slot_t = int32_t;

using ::android::BufferQueueDefs::BUFFER_NEEDS_REALLOCATION;
using ::android::BufferQueueDefs::NUM_BUFFER_SLOTS;
using ::android::hardware::Return;
using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0::IProducerListener;

static c2_status_t asC2Error(status_t err) {
    switch (err) {
    case OK:
        return C2_OK;
    case NO_INIT:
        return C2_NO_INIT;
    case BAD_VALUE:
        return C2_BAD_VALUE;
    case TIMED_OUT:
        return C2_TIMED_OUT;
    case WOULD_BLOCK:
        return C2_BLOCKING;
    case NO_MEMORY:
        return C2_NO_MEMORY;
    }
    return C2_CORRUPTED;
}

// Convert GraphicBuffer to C2GraphicAllocation and wrap producer id and slot index.
std::shared_ptr<C2GraphicAllocation> ConvertGraphicBuffer2C2Allocation(
        sp<GraphicBuffer> graphicBuffer, const uint64_t igbpId, const slot_t slot,
        C2Allocator* const allocator) {
    ALOGV("%s(idbpId=0x%" PRIx64 ", slot=%d)", __func__, igbpId, slot);

    C2Handle* c2Handle = WrapNativeCodec2GrallocHandle(
            graphicBuffer->handle, graphicBuffer->width, graphicBuffer->height,
            graphicBuffer->format, graphicBuffer->usage, graphicBuffer->stride,
            graphicBuffer->getGenerationNumber(), igbpId, slot);
    if (!c2Handle) {
        ALOGE("WrapNativeCodec2GrallocHandle() failed");
        return nullptr;
    }

    std::shared_ptr<C2GraphicAllocation> allocation;
    const auto err = allocator->priorGraphicAllocation(c2Handle, &allocation);
    if (err != C2_OK) {
        ALOGE("C2Allocator::priorGraphicAllocation() failed: %d", err);
        native_handle_close(c2Handle);
        native_handle_delete(c2Handle);
        return nullptr;
    }

    return allocation;
}

// This class is used to notify the listener when a certain event happens.
class EventNotifier : public virtual android::RefBase {
public:
    class Listener {
    public:
        virtual ~Listener() = default;

        // Called by EventNotifier when a certain event happens.
        virtual void onEventNotified() = 0;
    };

    explicit EventNotifier(std::weak_ptr<Listener> listener) : mListener(std::move(listener)) {}
    virtual ~EventNotifier() = default;

protected:
    void notify() {
        ALOGV("%s()", __func__);
        std::shared_ptr<Listener> listener = mListener.lock();
        if (listener) {
            listener->onEventNotified();
        }
    }

    std::weak_ptr<Listener> mListener;
};

// Notifies the listener when the connected IGBP releases buffers.
class BufferReleasedNotifier : public EventNotifier, public HProducerListener {
public:
    using EventNotifier::EventNotifier;
    ~BufferReleasedNotifier() override = default;

    // HProducerListener implementation
    Return<void> onBuffersReleased(uint32_t count) override {
        ALOGV("%s(%u)", __func__, count);
        if (count > 0) {
            notify();
        }
        return {};
    }
};

// IGBP expects its user (e.g. C2VdaBqBlockPool) to keep the mapping from dequeued slot index to
// graphic buffers. Also, C2VdaBqBlockPool guaratees to fetch N fixed set of buffers with buffer
// identifier. So this class stores the mapping from slot index to buffers and the mapping from
// buffer unique ID to buffers.
// This class also implements functionalities for buffer migration when surface switching. Buffers
// are owned by either component (i.e. local buffers) or CCodec framework (i.e. remote buffers).
// When switching surface, the ccodec framework migrates remote buffers to the new surfaces. Then
// C2VdaBqBlockPool migrates local buffers. However, some buffers might be lost during migration.
// We assume that there are enough buffers migrated to the new surface to continue the playback.
// After |NUM_BUFFER_SLOTS| amount of buffers are dequeued from new surface, all buffers should
// be dequeued at least once. Then we treat the missing buffer as lost, and attach these bufers to
// the new surface.
class TrackedGraphicBuffers {
public:
    using value_type = std::tuple<slot_t, unique_id_t, std::shared_ptr<C2GraphicAllocation>>;

    TrackedGraphicBuffers() = default;
    ~TrackedGraphicBuffers() = default;

    void reset() {
        mSlotId2GraphicBuffer.clear();
        mSlotId2PoolData.clear();
        mAllocationsRegistered.clear();
        mAllocationsToBeMigrated.clear();
        mMigrateLostBufferCounter = 0;
        mGenerationToBeMigrated = 0;
    }

    void registerUniqueId(unique_id_t uniqueId, std::shared_ptr<C2GraphicAllocation> allocation) {
        ALOGV("%s(uniqueId=%u)", __func__, uniqueId);
        ALOG_ASSERT(allocation != nullptr);

        mAllocationsRegistered[uniqueId] = std::move(allocation);
    }

    std::shared_ptr<C2GraphicAllocation> getRegisteredAllocation(unique_id_t uniqueId) {
        const auto iter = mAllocationsRegistered.find(uniqueId);
        ALOG_ASSERT(iter != mAllocationsRegistered.end());

        return iter->second;
    }

    bool hasUniqueId(unique_id_t uniqueId) const {
        return mAllocationsRegistered.find(uniqueId) != mAllocationsRegistered.end() ||
               mAllocationsToBeMigrated.find(uniqueId) != mAllocationsToBeMigrated.end();
    }

    void updateSlotBuffer(slot_t slotId, unique_id_t uniqueId, sp<GraphicBuffer> slotBuffer) {
        ALOGV("%s(slotId=%d)", __func__, slotId);
        ALOG_ASSERT(slotBuffer != nullptr);

        mSlotId2GraphicBuffer[slotId] = std::make_pair(uniqueId, std::move(slotBuffer));
    }

    std::pair<unique_id_t, sp<GraphicBuffer>> getSlotBuffer(slot_t slotId) const {
        const auto iter = mSlotId2GraphicBuffer.find(slotId);
        ALOG_ASSERT(iter != mSlotId2GraphicBuffer.end());

        return iter->second;
    }

    bool hasSlotId(slot_t slotId) const {
        return mSlotId2GraphicBuffer.find(slotId) != mSlotId2GraphicBuffer.end();
    }

    void updatePoolData(slot_t slotId, std::weak_ptr<C2BufferQueueBlockPoolData> poolData) {
        ALOGV("%s(slotId=%d)", __func__, slotId);
        ALOG_ASSERT(hasSlotId(slotId));

        mSlotId2PoolData[slotId] = std::move(poolData);
    }

    bool migrateLocalBuffers(H2BGraphicBufferProducer* const producer, uint64_t producerId,
                             uint32_t generation, uint64_t usage) {
        ALOGV("%s(producerId=%" PRIx64 ", generation=%u, usage=%" PRIx64 ")", __func__, producerId,
              generation, usage);

        mGenerationToBeMigrated = generation;
        mUsageToBeMigrated = usage;

        // Move all buffers to mAllocationsToBeMigrated.
        for (auto& pair : mAllocationsRegistered) {
            if (!mAllocationsToBeMigrated.insert(pair).second) {
                ALOGE("%s() duplicated uniqueId=%u", __func__, pair.first);
                return false;
            }
        }
        mAllocationsRegistered.clear();

        ALOGV("%s(producerId=%" PRIx64 ", generation=%u, usage=%" PRIx64 ") before %s", __func__,
              producerId, generation, usage, debugString().c_str());

        // Migrate local buffers.
        std::map<slot_t, std::pair<unique_id_t, sp<GraphicBuffer>>> newSlotId2GraphicBuffer;
        std::map<slot_t, std::weak_ptr<C2BufferQueueBlockPoolData>> newSlotId2PoolData;
        for (const auto& pair : mSlotId2PoolData) {
            auto oldSlot = pair.first;
            auto poolData = pair.second.lock();
            if (!poolData) {
                continue;
            }

            unique_id_t uniqueId;
            sp<GraphicBuffer> slotBuffer;
            std::shared_ptr<C2SurfaceSyncMemory> syncMem;
            std::tie(uniqueId, slotBuffer) = getSlotBuffer(oldSlot);
            slot_t newSlot = poolData->migrate(producer->getBase(), mGenerationToBeMigrated,
                                               mUsageToBeMigrated, producerId, slotBuffer,
                                               slotBuffer->getGenerationNumber(),
                                               syncMem);
            if (newSlot < 0) {
                ALOGW("%s() Failed to migrate local buffer: uniqueId=%u, oldSlot=%d", __func__,
                      uniqueId, oldSlot);
                continue;
            }

            ALOGV("%s() migrated buffer: uniqueId=%u, oldSlot=%d, newSlot=%d", __func__, uniqueId,
                  oldSlot, newSlot);
            newSlotId2GraphicBuffer[newSlot] = std::make_pair(uniqueId, std::move(slotBuffer));
            newSlotId2PoolData[newSlot] = std::move(poolData);

            if (!moveBufferToRegistered(uniqueId)) {
                ALOGE("%s() failed to move buffer to registered, uniqueId=%u", __func__, uniqueId);
                return false;
            }
        }
        mSlotId2GraphicBuffer = std::move(newSlotId2GraphicBuffer);
        mSlotId2PoolData = std::move(newSlotId2PoolData);

        // Choose a big enough number to ensure all buffer should be dequeued at least once.
        mMigrateLostBufferCounter = NUM_BUFFER_SLOTS;
        ALOGD("%s() migrated %zu local buffers", __func__, mAllocationsRegistered.size());
        return true;
    }

    bool needMigrateLostBuffers() const {
        return mMigrateLostBufferCounter == 0 && !mAllocationsToBeMigrated.empty();
    }

    status_t migrateLostBuffer(C2Allocator* const allocator,
                               H2BGraphicBufferProducer* const producer, const uint64_t producerId,
                               slot_t* newSlot) {
        ALOGV("%s() %s", __func__, debugString().c_str());

        if (!needMigrateLostBuffers()) {
            return NO_INIT;
        }

        auto iter = mAllocationsToBeMigrated.begin();
        const unique_id_t uniqueId = iter->first;
        const C2Handle* c2Handle = iter->second->handle();

        // Convert C2GraphicAllocation to GraphicBuffer, and update generation and usage.
        uint32_t width, height, format, stride, igbpSlot, generation;
        uint64_t usage, igbpId;
        _UnwrapNativeCodec2GrallocMetadata(c2Handle, &width, &height, &format, &usage, &stride,
                                           &generation, &igbpId, &igbpSlot);
        native_handle_t* grallocHandle = UnwrapNativeCodec2GrallocHandle(c2Handle);
        sp<GraphicBuffer> graphicBuffer =
                new GraphicBuffer(grallocHandle, GraphicBuffer::CLONE_HANDLE, width, height, format,
                                  1, mUsageToBeMigrated, stride);
        native_handle_delete(grallocHandle);
        if (graphicBuffer->initCheck() != android::NO_ERROR) {
            ALOGE("Failed to create GraphicBuffer: %d", graphicBuffer->initCheck());
            return false;
        }
        graphicBuffer->setGenerationNumber(mGenerationToBeMigrated);

        // Attach GraphicBuffer to producer.
        const auto attachStatus = producer->attachBuffer(graphicBuffer, newSlot);
        if (attachStatus == TIMED_OUT || attachStatus == INVALID_OPERATION) {
            ALOGV("%s(): No free slot yet.", __func__);
            return TIMED_OUT;
        }
        if (attachStatus != OK) {
            ALOGE("%s(): Failed to attach buffer to new producer: %d", __func__, attachStatus);
            return attachStatus;
        }
        ALOGD("%s(), migrated lost buffer uniqueId=%u to slot=%d", __func__, uniqueId, *newSlot);
        updateSlotBuffer(*newSlot, uniqueId, graphicBuffer);

        // Wrap the new GraphicBuffer to C2GraphicAllocation and register it.
        std::shared_ptr<C2GraphicAllocation> allocation =
                ConvertGraphicBuffer2C2Allocation(graphicBuffer, producerId, *newSlot, allocator);
        if (!allocation) {
            return UNKNOWN_ERROR;
        }
        registerUniqueId(uniqueId, std::move(allocation));

        // Note: C2ArcProtectedGraphicAllocator releases the protected buffers if all the
        // corrresponding C2GraphicAllocations are released. To prevent the protected buffer is
        // released and then allocated again, we release the old C2GraphicAllocation after the new
        // one has been created.
        mAllocationsToBeMigrated.erase(iter);

        return OK;
    }

    void onBufferDequeued(slot_t slotId) {
        ALOGV("%s(slotId=%d)", __func__, slotId);
        unique_id_t uniqueId;
        std::tie(uniqueId, std::ignore) = getSlotBuffer(slotId);

        moveBufferToRegistered(uniqueId);
        if (mMigrateLostBufferCounter > 0) {
            --mMigrateLostBufferCounter;
        }
    }

    size_t size() const { return mAllocationsRegistered.size() + mAllocationsToBeMigrated.size(); }

    std::string debugString() const {
        std::stringstream ss;
        ss << "tracked size: " << size() << std::endl;
        ss << "  registered uniqueIds: ";
        for (const auto& pair : mAllocationsRegistered) {
            ss << pair.first << ", ";
        }
        ss << std::endl;
        ss << "  to-be-migrated uniqueIds: ";
        for (const auto& pair : mAllocationsToBeMigrated) {
            ss << pair.first << ", ";
        }
        ss << std::endl;
        ss << "  Count down for lost buffer migration: " << mMigrateLostBufferCounter;
        return ss.str();
    }

private:
    bool moveBufferToRegistered(unique_id_t uniqueId) {
        ALOGV("%s(uniqueId=%u)", __func__, uniqueId);
        auto iter = mAllocationsToBeMigrated.find(uniqueId);
        if (iter == mAllocationsToBeMigrated.end()) {
            return false;
        }
        if (!mAllocationsRegistered.insert(*iter).second) {
            ALOGE("%s() duplicated uniqueId=%u", __func__, uniqueId);
            return false;
        }
        mAllocationsToBeMigrated.erase(iter);

        return true;
    }

    // Mapping from IGBP slots to the corresponding graphic buffers.
    std::map<slot_t, std::pair<unique_id_t, sp<GraphicBuffer>>> mSlotId2GraphicBuffer;

    // Mapping from IGBP slots to the corresponding pool data.
    std::map<slot_t, std::weak_ptr<C2BufferQueueBlockPoolData>> mSlotId2PoolData;

    // Track the buffers registered at the current producer.
    std::map<unique_id_t, std::shared_ptr<C2GraphicAllocation>> mAllocationsRegistered;

    // Track the buffers that should be migrated to the current producer.
    std::map<unique_id_t, std::shared_ptr<C2GraphicAllocation>> mAllocationsToBeMigrated;

    // The counter for migrating lost buffers. Count down when a buffer is
    // dequeued from IGBP. When it goes to 0, then we treat the remaining
    // buffers at |mAllocationsToBeMigrated| lost, and migrate them to
    // current IGBP.
    size_t mMigrateLostBufferCounter = 0;

    // The generation and usage of the current IGBP, used to migrate buffers.
    uint32_t mGenerationToBeMigrated = 0;
    uint64_t mUsageToBeMigrated = 0;
};

class C2VdaBqBlockPool::Impl : public std::enable_shared_from_this<C2VdaBqBlockPool::Impl>,
                               public EventNotifier::Listener {
public:
    using HGraphicBufferProducer = C2VdaBqBlockPool::HGraphicBufferProducer;

    explicit Impl(const std::shared_ptr<C2Allocator>& allocator);
    // TODO: should we detach buffers on producer if any on destructor?
    ~Impl() = default;

    // EventNotifier::Listener implementation.
    void onEventNotified() override;

    c2_status_t fetchGraphicBlock(uint32_t width, uint32_t height, uint32_t format,
                                  C2MemoryUsage usage,
                                  std::shared_ptr<C2GraphicBlock>* block /* nonnull */);
    void setRenderCallback(const C2BufferQueueBlockPool::OnRenderCallback& renderCallback);
    void configureProducer(const sp<HGraphicBufferProducer>& producer);
    c2_status_t requestNewBufferSet(int32_t bufferCount, uint32_t width, uint32_t height,
                                    uint32_t format, C2MemoryUsage usage);
    bool setNotifyBlockAvailableCb(::base::OnceClosure cb);
    std::optional<unique_id_t> getBufferIdFromGraphicBlock(const C2Block2D& block);

private:
    // Requested buffer formats.
    struct BufferFormat {
        BufferFormat(uint32_t width, uint32_t height, uint32_t pixelFormat,
                     C2AndroidMemoryUsage androidUsage)
              : mWidth(width), mHeight(height), mPixelFormat(pixelFormat), mUsage(androidUsage) {}
        BufferFormat() = default;

        uint32_t mWidth = 0;
        uint32_t mHeight = 0;
        uint32_t mPixelFormat = 0;
        C2AndroidMemoryUsage mUsage = C2MemoryUsage(0);
    };

    status_t getFreeSlotLocked(uint32_t width, uint32_t height, uint32_t format,
                               C2MemoryUsage usage, slot_t* slot, sp<Fence>* fence);

    // Queries the generation and usage flags from the given producer by dequeuing and requesting a
    // buffer (the buffer is then detached and freed).
    status_t queryGenerationAndUsageLocked(uint32_t width, uint32_t height, uint32_t pixelFormat,
                                           C2AndroidMemoryUsage androidUsage, uint32_t* generation,
                                           uint64_t* usage);

    // Wait the fence. If any error occurs, cancel the buffer back to the producer.
    status_t waitFence(slot_t slot, sp<Fence> fence);

    // Call mProducer's allowAllocation if needed.
    status_t allowAllocation(bool allow);

    const std::shared_ptr<C2Allocator> mAllocator;

    std::unique_ptr<H2BGraphicBufferProducer> mProducer;
    uint64_t mProducerId = 0;
    bool mAllowAllocation = false;

    C2BufferQueueBlockPool::OnRenderCallback mRenderCallback;

    // Function mutex to lock at the start of each API function call for protecting the
    // synchronization of all member variables.
    std::mutex mMutex;

    TrackedGraphicBuffers mTrackedGraphicBuffers;

    // Number of buffers requested on requestNewBufferSet() call.
    size_t mBuffersRequested = 0u;
    // Currently requested buffer formats.
    BufferFormat mBufferFormat;

    // Listener for buffer release events.
    sp<EventNotifier> mFetchBufferNotifier;

    std::mutex mBufferReleaseMutex;
    // Set to true when the buffer release event is triggered after dequeueing buffer from IGBP
    // times out. Reset when fetching new slot times out, or |mNotifyBlockAvailableCb| is executed.
    bool mBufferReleasedAfterTimedOut GUARDED_BY(mBufferReleaseMutex) = false;
    // The callback to notify the caller the buffer is available.
    ::base::OnceClosure mNotifyBlockAvailableCb GUARDED_BY(mBufferReleaseMutex);

    // Set to true if any error occurs at previous configureProducer().
    bool mConfigureProducerError = false;
};

C2VdaBqBlockPool::Impl::Impl(const std::shared_ptr<C2Allocator>& allocator)
      : mAllocator(allocator) {}

c2_status_t C2VdaBqBlockPool::Impl::fetchGraphicBlock(
        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
        std::shared_ptr<C2GraphicBlock>* block /* nonnull */) {
    ALOGV("%s(%ux%u)", __func__, width, height);
    std::lock_guard<std::mutex> lock(mMutex);

    if (width != mBufferFormat.mWidth || height != mBufferFormat.mHeight ||
        format != mBufferFormat.mPixelFormat || usage.expected != mBufferFormat.mUsage.expected) {
        ALOGE("%s(): buffer format (%ux%u, format=%u, usage=%" PRIx64
              ") is different from requested format (%ux%u, format=%u, usage=%" PRIx64 ")",
              __func__, width, height, format, usage.expected, mBufferFormat.mWidth,
              mBufferFormat.mHeight, mBufferFormat.mPixelFormat, mBufferFormat.mUsage.expected);
        return C2_BAD_VALUE;
    }
    if (mConfigureProducerError || !mProducer) {
        ALOGE("%s(): error occurred at previous configureProducer()", __func__);
        return C2_CORRUPTED;
    }

    slot_t slot;
    sp<Fence> fence = new Fence();
    const auto status = getFreeSlotLocked(width, height, format, usage, &slot, &fence);
    if (status != OK) {
        return asC2Error(status);
    }

    unique_id_t uniqueId;
    sp<GraphicBuffer> slotBuffer;
    std::tie(uniqueId, slotBuffer) = mTrackedGraphicBuffers.getSlotBuffer(slot);
    ALOGV("%s(): dequeued slot=%d uniqueId=%u", __func__, slot, uniqueId);

    if (!mTrackedGraphicBuffers.hasUniqueId(uniqueId)) {
        if (mTrackedGraphicBuffers.size() >= mBuffersRequested) {
            // The dequeued slot has a pre-allocated buffer whose size and format is as same as
            // currently requested (but was not dequeued during allocation cycle). Just detach it to
            // free this slot. And try dequeueBuffer again.
            ALOGD("dequeued a new slot %d but already allocated enough buffers. Detach it.", slot);

            if (mProducer->detachBuffer(slot) != OK) {
                return C2_CORRUPTED;
            }

            const auto allocationStatus = allowAllocation(false);
            if (allocationStatus != OK) {
                return asC2Error(allocationStatus);
            }
            return C2_TIMED_OUT;
        }

        std::shared_ptr<C2GraphicAllocation> allocation =
                ConvertGraphicBuffer2C2Allocation(slotBuffer, mProducerId, slot, mAllocator.get());
        if (!allocation) {
            return C2_CORRUPTED;
        }
        mTrackedGraphicBuffers.registerUniqueId(uniqueId, std::move(allocation));

        ALOGV("%s(): mTrackedGraphicBuffers.size=%zu", __func__, mTrackedGraphicBuffers.size());
        if (mTrackedGraphicBuffers.size() == mBuffersRequested) {
            ALOGV("Tracked IGBP slots: %s", mTrackedGraphicBuffers.debugString().c_str());
            // Already allocated enough buffers, set allowAllocation to false to restrict the
            // eligible slots to allocated ones for future dequeue.
            const auto allocationStatus = allowAllocation(false);
            if (allocationStatus != OK) {
                return asC2Error(allocationStatus);
            }
        }
    }

    std::shared_ptr<C2SurfaceSyncMemory> syncMem;
    std::shared_ptr<C2GraphicAllocation> allocation =
            mTrackedGraphicBuffers.getRegisteredAllocation(uniqueId);
    auto poolData = std::make_shared<C2BufferQueueBlockPoolData>(
            slotBuffer->getGenerationNumber(), mProducerId, slot,
            mProducer->getBase(), syncMem, 0);
    mTrackedGraphicBuffers.updatePoolData(slot, poolData);
    *block = _C2BlockFactory::CreateGraphicBlock(std::move(allocation), std::move(poolData));
    if (*block == nullptr) {
        ALOGE("failed to create GraphicBlock: no memory");
        return C2_NO_MEMORY;
    }

    // Wait for acquire fence at the last point of returning buffer.
    if (fence) {
        const auto fenceStatus = waitFence(slot, fence);
        if (fenceStatus != OK) {
            return asC2Error(fenceStatus);
        }

        if (mRenderCallback) {
            nsecs_t signalTime = fence->getSignalTime();
            if (signalTime >= 0 && signalTime < INT64_MAX) {
                mRenderCallback(mProducerId, slot, signalTime);
            } else {
                ALOGV("got fence signal time of %" PRId64 " nsec", signalTime);
            }
        }
    }

    return C2_OK;
}

status_t C2VdaBqBlockPool::Impl::getFreeSlotLocked(uint32_t width, uint32_t height, uint32_t format,
                                                   C2MemoryUsage usage, slot_t* slot,
                                                   sp<Fence>* fence) {
    if (mTrackedGraphicBuffers.needMigrateLostBuffers()) {
        slot_t newSlot;
        if (mTrackedGraphicBuffers.migrateLostBuffer(mAllocator.get(), mProducer.get(), mProducerId,
                                                     &newSlot) == OK) {
            ALOGV("%s(): migrated buffer: slot=%d", __func__, newSlot);
            *slot = newSlot;
            return OK;
        }
    }

    // Dequeue a free slot from IGBP.
    ALOGV("%s(): try to dequeue free slot from IGBP.", __func__);
    const auto dequeueStatus = mProducer->dequeueBuffer(width, height, format, usage, slot, fence);
    if (dequeueStatus == TIMED_OUT) {
        std::lock_guard<std::mutex> lock(mBufferReleaseMutex);
        mBufferReleasedAfterTimedOut = false;
    }
    if (dequeueStatus != OK && dequeueStatus != BUFFER_NEEDS_REALLOCATION) {
        return dequeueStatus;
    }

    // Call requestBuffer to update GraphicBuffer for the slot and obtain the reference.
    if (!mTrackedGraphicBuffers.hasSlotId(*slot) || dequeueStatus == BUFFER_NEEDS_REALLOCATION) {
        sp<GraphicBuffer> slotBuffer = new GraphicBuffer();
        const auto requestStatus = mProducer->requestBuffer(*slot, &slotBuffer);
        if (requestStatus != OK) {
            mProducer->cancelBuffer(*slot, *fence);
            return requestStatus;
        }

        const auto uniqueId = getDmabufId(slotBuffer->handle->data[0]);
        if (!uniqueId) {
            ALOGE("%s(): failed to get uniqueId of GraphicBuffer from slot=%d", __func__, *slot);
            return UNKNOWN_ERROR;
        }
        mTrackedGraphicBuffers.updateSlotBuffer(*slot, *uniqueId, std::move(slotBuffer));
    }

    ALOGV("%s(%ux%u): dequeued slot=%d", __func__, mBufferFormat.mWidth, mBufferFormat.mHeight,
          *slot);
    mTrackedGraphicBuffers.onBufferDequeued(*slot);
    return OK;
}

void C2VdaBqBlockPool::Impl::onEventNotified() {
    ALOGV("%s()", __func__);
    ::base::OnceClosure outputCb;
    {
        std::lock_guard<std::mutex> lock(mBufferReleaseMutex);

        mBufferReleasedAfterTimedOut = true;
        if (mNotifyBlockAvailableCb) {
            mBufferReleasedAfterTimedOut = false;
            outputCb = std::move(mNotifyBlockAvailableCb);
        }
    }

    // Calling the callback outside the lock to avoid the deadlock.
    if (outputCb) {
        std::move(outputCb).Run();
    }
}

status_t C2VdaBqBlockPool::Impl::queryGenerationAndUsageLocked(uint32_t width, uint32_t height,
                                                               uint32_t pixelFormat,
                                                               C2AndroidMemoryUsage androidUsage,
                                                               uint32_t* generation,
                                                               uint64_t* usage) {
    ALOGV("%s()", __func__);

    sp<Fence> fence = new Fence();
    slot_t slot;
    const auto dequeueStatus =
            mProducer->dequeueBuffer(width, height, pixelFormat, androidUsage, &slot, &fence);
    if (dequeueStatus != OK && dequeueStatus != BUFFER_NEEDS_REALLOCATION) {
        return dequeueStatus;
    }

    // Call requestBuffer to allocate buffer for the slot and obtain the reference.
    // Get generation number here.
    sp<GraphicBuffer> slotBuffer = new GraphicBuffer();
    const auto requestStatus = mProducer->requestBuffer(slot, &slotBuffer);

    // Detach and delete the temporary buffer.
    const auto detachStatus = mProducer->detachBuffer(slot);
    if (detachStatus != OK) {
        return detachStatus;
    }

    // Check requestBuffer return flag.
    if (requestStatus != OK) {
        return requestStatus;
    }

    // Get generation number and usage from the slot buffer.
    *usage = slotBuffer->getUsage();
    *generation = slotBuffer->getGenerationNumber();
    ALOGV("Obtained from temp buffer: generation = %u, usage = %" PRIu64 "", *generation, *usage);
    return OK;
}

status_t C2VdaBqBlockPool::Impl::waitFence(slot_t slot, sp<Fence> fence) {
    const auto fenceStatus = fence->wait(kFenceWaitTimeMs);
    if (fenceStatus == OK) {
        return OK;
    }

    const auto cancelStatus = mProducer->cancelBuffer(slot, fence);
    if (cancelStatus != OK) {
        ALOGE("%s(): failed to cancelBuffer(slot=%d)", __func__, slot);
        return cancelStatus;
    }

    if (fenceStatus == -ETIME) {  // fence wait timed out
        ALOGV("%s(): buffer (slot=%d) fence wait timed out", __func__, slot);
        return TIMED_OUT;
    }
    ALOGE("buffer fence wait error: %d", fenceStatus);
    return fenceStatus;
}

void C2VdaBqBlockPool::Impl::setRenderCallback(
        const C2BufferQueueBlockPool::OnRenderCallback& renderCallback) {
    ALOGV("setRenderCallback");
    std::lock_guard<std::mutex> lock(mMutex);
    mRenderCallback = renderCallback;
}

c2_status_t C2VdaBqBlockPool::Impl::requestNewBufferSet(int32_t bufferCount, uint32_t width,
                                                        uint32_t height, uint32_t format,
                                                        C2MemoryUsage usage) {
    ALOGV("%s(bufferCount=%d, size=%ux%u, format=0x%x, usage=%" PRIu64 ")", __func__, bufferCount,
          width, height, format, usage.expected);

    if (bufferCount <= 0) {
        ALOGE("Invalid requested buffer count = %d", bufferCount);
        return C2_BAD_VALUE;
    }

    std::lock_guard<std::mutex> lock(mMutex);
    if (!mProducer) {
        ALOGD("No HGraphicBufferProducer is configured...");
        return C2_NO_INIT;
    }
    if (mBuffersRequested == static_cast<size_t>(bufferCount) && mBufferFormat.mWidth == width &&
        mBufferFormat.mHeight == height && mBufferFormat.mPixelFormat == format &&
        mBufferFormat.mUsage.expected == usage.expected) {
        ALOGD("%s() Request the same format and amount of buffers, skip", __func__);
        return C2_OK;
    }

    const auto status = allowAllocation(true);
    if (status != OK) {
        return asC2Error(status);
    }

    // Release all remained slot buffer references here. CCodec should either cancel or queue its
    // owned buffers from this set before the next resolution change.
    mTrackedGraphicBuffers.reset();

    mBuffersRequested = static_cast<size_t>(bufferCount);

    // Store buffer formats for future usage.
    mBufferFormat = BufferFormat(width, height, format, C2AndroidMemoryUsage(usage));

    return C2_OK;
}

void C2VdaBqBlockPool::Impl::configureProducer(const sp<HGraphicBufferProducer>& producer) {
    ALOGV("%s(producer=%p)", __func__, producer.get());

    std::lock_guard<std::mutex> lock(mMutex);
    if (producer == nullptr) {
        ALOGI("input producer is nullptr...");

        mProducer = nullptr;
        mProducerId = 0;
        mTrackedGraphicBuffers.reset();
        return;
    }

    auto newProducer = std::make_unique<H2BGraphicBufferProducer>(producer);
    uint64_t newProducerId;
    if (newProducer->getUniqueId(&newProducerId) != OK) {
        ALOGE("%s(): failed to get IGBP ID", __func__);
        mConfigureProducerError = true;
        return;
    }
    if (newProducerId == mProducerId) {
        ALOGI("%s(): configure the same producer, ignore", __func__);
        return;
    }

    ALOGI("Producer (Surface) is going to switch... ( 0x%" PRIx64 " -> 0x%" PRIx64 " )",
          mProducerId, newProducerId);
    mProducer = std::move(newProducer);
    mProducerId = newProducerId;
    mConfigureProducerError = false;
    mAllowAllocation = false;

    // Set allowAllocation to new producer.
    if (allowAllocation(true) != OK) {
        ALOGE("%s(): failed to allowAllocation(true)", __func__);
        mConfigureProducerError = true;
        return;
    }
    if (mProducer->setDequeueTimeout(0) != OK) {
        ALOGE("%s(): failed to setDequeueTimeout(0)", __func__);
        mConfigureProducerError = true;
        return;
    }
    if (mProducer->setMaxDequeuedBufferCount(kMaxDequeuedBufferCount) != OK) {
        ALOGE("%s(): failed to setMaxDequeuedBufferCount(%d)", __func__, kMaxDequeuedBufferCount);
        mConfigureProducerError = true;
        return;
    }

    // Migrate existing buffers to the new producer.
    if (mTrackedGraphicBuffers.size() > 0) {
        uint32_t newGeneration = 0;
        uint64_t newUsage = 0;
        const status_t err = queryGenerationAndUsageLocked(
                mBufferFormat.mWidth, mBufferFormat.mHeight, mBufferFormat.mPixelFormat,
                mBufferFormat.mUsage, &newGeneration, &newUsage);
        if (err != OK) {
            ALOGE("failed to query generation and usage: %d", err);
            mConfigureProducerError = true;
            return;
        }

        if (!mTrackedGraphicBuffers.migrateLocalBuffers(mProducer.get(), mProducerId, newGeneration,
                                                        newUsage)) {
            ALOGE("%s(): failed to migrateLocalBuffers()", __func__);
            mConfigureProducerError = true;
            return;
        }

        if (mTrackedGraphicBuffers.size() == mBuffersRequested) {
            if (allowAllocation(false) != OK) {
                ALOGE("%s(): failed to allowAllocation(false)", __func__);
                mConfigureProducerError = true;
                return;
            }
        }
    }

    // hack(b/146409777): Try to connect ARC-specific listener first.
    sp<BufferReleasedNotifier> listener = new BufferReleasedNotifier(weak_from_this());
    if (mProducer->connect(listener, 'ARC\0', false) == OK) {
        ALOGI("connected to ARC-specific IGBP listener.");
        mFetchBufferNotifier = listener;
    }

    // There might be free buffers at the new producer, notify the client if needed.
    onEventNotified();
}

bool C2VdaBqBlockPool::Impl::setNotifyBlockAvailableCb(::base::OnceClosure cb) {
    ALOGV("%s()", __func__);
    if (mFetchBufferNotifier == nullptr) {
        return false;
    }

    ::base::OnceClosure outputCb;
    {
        std::lock_guard<std::mutex> lock(mBufferReleaseMutex);

        // If there is any buffer released after dequeueBuffer() timed out, then we could notify the
        // caller directly.
        if (mBufferReleasedAfterTimedOut) {
            mBufferReleasedAfterTimedOut = false;
            outputCb = std::move(cb);
        } else {
            mNotifyBlockAvailableCb = std::move(cb);
        }
    }

    // Calling the callback outside the lock to avoid the deadlock.
    if (outputCb) {
        std::move(outputCb).Run();
    }
    return true;
}

std::optional<unique_id_t> C2VdaBqBlockPool::Impl::getBufferIdFromGraphicBlock(
        const C2Block2D& block) {
    return getDmabufId(block.handle()->data[0]);
}

status_t C2VdaBqBlockPool::Impl::allowAllocation(bool allow) {
    ALOGV("%s(%d)", __func__, allow);

    if (!mProducer) {
        ALOGW("%s() mProducer is not initiailzed", __func__);
        return NO_INIT;
    }
    if (mAllowAllocation == allow) {
        return OK;
    }

    const auto status = mProducer->allowAllocation(allow);
    if (status == OK) {
        mAllowAllocation = allow;
    }
    return status;
}

C2VdaBqBlockPool::C2VdaBqBlockPool(const std::shared_ptr<C2Allocator>& allocator,
                                   const local_id_t localId)
      : C2BufferQueueBlockPool(allocator, localId), mLocalId(localId), mImpl(new Impl(allocator)) {}

c2_status_t C2VdaBqBlockPool::fetchGraphicBlock(
        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
        std::shared_ptr<C2GraphicBlock>* block /* nonnull */) {
    if (mImpl) {
        return mImpl->fetchGraphicBlock(width, height, format, usage, block);
    }
    return C2_NO_INIT;
}

void C2VdaBqBlockPool::setRenderCallback(
        const C2BufferQueueBlockPool::OnRenderCallback& renderCallback) {
    if (mImpl) {
        mImpl->setRenderCallback(renderCallback);
    }
}

c2_status_t C2VdaBqBlockPool::requestNewBufferSet(int32_t bufferCount, uint32_t width,
                                                  uint32_t height, uint32_t format,
                                                  C2MemoryUsage usage) {
    if (mImpl) {
        return mImpl->requestNewBufferSet(bufferCount, width, height, format, usage);
    }
    return C2_NO_INIT;
}

void C2VdaBqBlockPool::configureProducer(const sp<HGraphicBufferProducer>& producer) {
    if (mImpl) {
        mImpl->configureProducer(producer);
    }
}

bool C2VdaBqBlockPool::setNotifyBlockAvailableCb(::base::OnceClosure cb) {
    if (mImpl) {
        return mImpl->setNotifyBlockAvailableCb(std::move(cb));
    }
    return false;
}

std::optional<unique_id_t> C2VdaBqBlockPool::getBufferIdFromGraphicBlock(const C2Block2D& block) {
    if (mImpl) {
        return mImpl->getBufferIdFromGraphicBlock(block);
    }
    return std::nullopt;
}

}  // namespace android
