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  */
39 class C2VdaBqBlockPool : public C2BufferQueueBlockPool {
40 public:
41     C2VdaBqBlockPool(const std::shared_ptr<C2Allocator>& allocator, const local_id_t localId);
42 
43     ~C2VdaBqBlockPool() override;
44 
getAllocatorId()45     C2Allocator::id_t getAllocatorId() const override { return mAllocator->getId(); };
46 
getLocalId()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 
73 private:
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