1/*
2 * Copyright 2018, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_C2_VDA_BQ_BLOCK_POOL_H_
18#define ANDROID_C2_VDA_BQ_BLOCK_POOL_H_
19
20#include <functional>
21#include <map>
22
23#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
24
25#include <C2BqBufferPriv.h>
26#include <C2Buffer.h>
27
28/**
29 * The BufferQueue-backed block pool design which supports to request arbitrary count of graphic
30 * buffers from IGBP, and use this buffer set among codec component and client.
31 *
32 * The block pool should restore the mapping table between slot indices and GraphicBuffer (or
33 * C2GraphicAllocation). When component requests a new buffer, the block pool calls dequeueBuffer
34 * to IGBP to obtain a valid slot index, and returns the corresponding buffer from map.
35 *
36 * Buffers in the map should be canceled to IGBP on block pool destruction, or on resolution change
37 * request.
38 */
39class C2VdaBqBlockPool : public C2BufferQueueBlockPool {
40public:
41    C2VdaBqBlockPool(const std::shared_ptr<C2Allocator>& allocator, const local_id_t localId);
42
43    ~C2VdaBqBlockPool() override;
44
45    C2Allocator::id_t getAllocatorId() const override { return mAllocator->getId(); };
46
47    local_id_t getLocalId() const override { return mLocalId; };
48
49    /**
50     * Tries to dequeue a buffer from producer. If the dequeued slot is not in |mSlotBuffers| and
51     * BUFFER_NEEDS_REALLOCATION is returned, allocates new buffer from producer by requestBuffer
52     * and records the buffer and its slot index into |mSlotBuffers|.
53     *
54     * When the size of |mSlotBuffers| reaches the requested buffer count, set disallow allocation
55     * to producer. After that only slots with allocated buffer could be dequeued.
56     */
57    c2_status_t fetchGraphicBlock(uint32_t width, uint32_t height, uint32_t format,
58                                  C2MemoryUsage usage,
59                                  std::shared_ptr<C2GraphicBlock>* block /* nonnull */) override;
60
61    void configureProducer(const android::sp<android::HGraphicBufferProducer>& producer) override;
62
63    /**
64     * Sends the request of arbitrary number of graphic buffers allocation. If producer is given,
65     * it will set maxDequeuedBufferCount as the requested buffer count to producer.
66     *
67     * \note C2VdaBqBlockPool-specific function
68     *
69     * \param bufferCount  the number of requested buffers
70     */
71    c2_status_t requestNewBufferSet(int32_t bufferCount);
72
73private:
74    c2_status_t cancelAllBuffers();
75
76    const std::shared_ptr<C2Allocator> mAllocator;
77    const local_id_t mLocalId;
78
79    android::sp<android::HGraphicBufferProducer> mProducer;
80    uint64_t mProducerId;
81
82    // Function mutex to lock at the start of each API function call for protecting the
83    // synchronization of all member variables.
84    std::mutex mMutex;
85
86    std::map<int32_t, std::shared_ptr<C2GraphicAllocation>> mSlotAllocations;
87    size_t mMaxDequeuedBuffers;
88};
89
90#endif  // ANDROID_C2_VDA_BQ_BLOCK_POOL_H_
91