1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ANDROID_V4L2_CODEC2_PLUGIN_STORE_C2_VDA_BQ_BLOCK_POOL_H
6 #define ANDROID_V4L2_CODEC2_PLUGIN_STORE_C2_VDA_BQ_BLOCK_POOL_H
7 
8 #include <functional>
9 #include <map>
10 #include <optional>
11 
12 #include <C2BqBufferPriv.h>
13 #include <C2Buffer.h>
14 #include <C2PlatformSupport.h>
15 #include <base/callback_forward.h>
16 
17 namespace android {
18 
19 /**
20  * The BufferQueue-backed block pool design which supports to request arbitrary count of graphic
21  * buffers from IGBP, and use this buffer set among codec component and client.
22  *
23  * The block pool should restore the mapping table between slot indices and GraphicBuffer (or
24  * C2GraphicAllocation). When component requests a new buffer, the block pool calls dequeueBuffer
25  * to IGBP to obtain a valid slot index, and returns the corresponding buffer from map.
26  */
27 class C2VdaBqBlockPool : public C2BufferQueueBlockPool {
28 public:
29     C2VdaBqBlockPool(const std::shared_ptr<C2Allocator>& allocator, const local_id_t localId);
30 
31     ~C2VdaBqBlockPool() override = default;
32 
33     /**
34      * It's a trick here. Return C2PlatformAllocatorStore::BUFFERQUEUE instead of the ID of backing
35      * allocator for client's query. It's because in platform side this ID is recognized as
36      * BufferQueue-backed block pool which is only allowed to set surface.
37      */
getAllocatorId()38     C2Allocator::id_t getAllocatorId() const override {
39         return android::C2PlatformAllocatorStore::BUFFERQUEUE;
40     };
41 
getLocalId()42     local_id_t getLocalId() const override { return mLocalId; };
43 
44     /**
45      * Tries to dequeue a buffer from producer. If the producer is allowed allocation now, call
46      * requestBuffer of dequeued slot for allocating new buffer and storing the reference into
47      * |mSlotAllocations|.
48      *
49      * When the size of |mSlotAllocations| reaches the requested buffer count, set disallow
50      * allocation to producer. After that buffer set is started to be recycled by dequeue.
51      *
52      * \retval C2_BAD_STATE informs the caller producer is switched.
53      */
54     c2_status_t fetchGraphicBlock(uint32_t width, uint32_t height, uint32_t format,
55                                   C2MemoryUsage usage,
56                                   std::shared_ptr<C2GraphicBlock>* block /* nonnull */) override;
57 
58     void setRenderCallback(const C2BufferQueueBlockPool::OnRenderCallback& renderCallback =
59                                    C2BufferQueueBlockPool::OnRenderCallback()) override;
60     void configureProducer(const android::sp<HGraphicBufferProducer>& producer) override;
61 
62     /**
63      * Sends the request of arbitrary number of graphic buffers allocation. If producer is given,
64      * it will set maxDequeuedBufferCount with regard to the requested buffer count and allow
65      * allocation to producer.
66      *
67      * \note C2VdaBqBlockPool-specific function
68      * \note caller should release all buffer references obtained from fetchGraphicBlock() before
69      *       calling this function.
70      *
71      * \param bufferCount  the number of requested buffers
72      *
73      * \retval C2_OK        the operation was successful.
74      * \retval C2_NO_INIT   this class is not initialized, or producer is not assigned.
75      * \retval C2_BAD_VALUE |bufferCount| is not greater than zero.
76      * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected).
77      */
78     c2_status_t requestNewBufferSet(int32_t bufferCount, uint32_t width, uint32_t height,
79                                     uint32_t format, C2MemoryUsage usage);
80 
81     /**
82      * Set the callback that will be triggered when there is block available.
83      *
84      * \note C2VdaBqBlockPool-specific function
85      *
86      * \param cb  the callback function that will be triggered when there is block available.
87      *
88      * Return false if we don't support to notify the caller when a buffer is available.
89      *
90      */
91     bool setNotifyBlockAvailableCb(base::OnceClosure cb);
92 
93     std::optional<uint32_t> getBufferIdFromGraphicBlock(const C2Block2D& block);
94 
95 private:
96     friend struct C2VdaBqBlockPoolData;
97     class Impl;
98 
99     const local_id_t mLocalId;
100     std::shared_ptr<Impl> mImpl;
101 };
102 
103 }  // namespace android
104 #endif  // ANDROID_V4L2_CODEC2_PLUGIN_STORE_C2_VDA_BQ_BLOCK_POOL_H
105