• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
18 #define ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
19 
20 #include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h>
21 
22 #include <C2Buffer.h>
23 
24 // Note: HIDL-BufferPool and AIDL-BufferPool are not compatible
25 namespace android::hardware::media::bufferpool {
26 
27 // BuffePool Data for HIDL-BufferPool
28 struct BufferPoolData;
29 
30 }
31 namespace aidl::android::hardware::media::bufferpool2 {
32 
33 // BuffePool Data for AIDL-BufferPool
34 struct BufferPoolData;
35 
36 }
37 
38 using bufferpool_BufferPoolData = android::hardware::media::bufferpool::BufferPoolData;
39 using bufferpool2_BufferPoolData = aidl::android::hardware::media::bufferpool2::BufferPoolData;
40 
41 /**
42  * Stores informations from C2BlockPool implementations which are required by C2Block.
43  */
44 struct C2_HIDE _C2BlockPoolData {
45     enum type_t : int {
46         TYPE_BUFFERPOOL = 0,
47         TYPE_BUFFERQUEUE,
48         TYPE_BUFFERPOOL2, // AIDL-BufferPool
49     };
50 
51     virtual type_t getType() const = 0;
52 
53 protected:
54     _C2BlockPoolData() = default;
55 
56     virtual ~_C2BlockPoolData() = default;
57 };
58 
59 struct C2BufferQueueBlockPoolData;
60 
61 class C2SurfaceSyncMemory;
62 
63 /**
64  * Internal only interface for creating blocks by block pool/buffer passing implementations.
65  *
66  * \todo this must be hidden
67  */
68 struct _C2BlockFactory {
69     /**
70      * Create a linear block from an allocation for an allotted range.
71      *
72      * \param alloc parent allocation
73      * \param data  blockpool data
74      * \param offset allotted range offset
75      * \param size  allotted size
76      *
77      * \return shared pointer to the linear block. nullptr if there was not enough memory to
78      *         create this block.
79      */
80     static
81     std::shared_ptr<C2LinearBlock> CreateLinearBlock(
82             const std::shared_ptr<C2LinearAllocation> &alloc,
83             const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
84             size_t offset = 0,
85             size_t size = ~(size_t)0);
86 
87     /**
88      * Create a graphic block from an allocation for an allotted section.
89      *
90      * \param alloc parent allocation
91      * \param data  blockpool data
92      * \param crop  allotted crop region
93      *
94      * \return shared pointer to the graphic block. nullptr if there was not enough memory to
95      *         create this block.
96      */
97     static
98     std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
99             const std::shared_ptr<C2GraphicAllocation> &alloc,
100             const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
101             const C2Rect &allottedCrop = C2Rect(~0u, ~0u));
102 
103     /**
104      * Return a block pool data from 1D block.
105      *
106      * \param shared pointer to the 1D block which is already created.
107      */
108     static
109     std::shared_ptr<_C2BlockPoolData> GetLinearBlockPoolData(
110             const C2Block1D& block);
111 
112     /**
113      * Return a block pool data from 2D block.
114      *
115      * \param shared pointer to the 2D block which is already created.
116      */
117     static
118     std::shared_ptr<_C2BlockPoolData> GetGraphicBlockPoolData(
119             const C2Block2D& block);
120 
121     /**
122      * Create a linear block from the received native handle.
123      *
124      * \param handle    native handle to a linear block
125      *
126      * \return shared pointer to the linear block. nullptr if there was not enough memory to
127      *         create this block.
128      */
129     static
130     std::shared_ptr<C2LinearBlock> CreateLinearBlock(
131             const C2Handle *handle);
132 
133     /**
134      * Create a graphic block from the received native handle.
135      *
136      * \param handle    native handle to a graphic block
137      *
138      * \return shared pointer to the graphic block. nullptr if there was not enough memory to
139      *         create this block.
140      */
141     static
142     std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
143             const C2Handle *handle);
144 
145     // HIDL-BufferPool
146     /**
147      * Create a linear block from the received bufferpool data.
148      *
149      * \param data  bufferpool data to a linear block
150      *
151      * \return shared pointer to the linear block. nullptr if there was not enough memory to
152      *         create this block.
153      */
154     static
155     std::shared_ptr<C2LinearBlock> CreateLinearBlock(
156             const C2Handle *handle,
157             const std::shared_ptr<bufferpool_BufferPoolData> &data);
158 
159     /**
160      * Create a graphic block from the received bufferpool data.
161      *
162      * \param data  bufferpool data to a graphic block
163      *
164      * \return shared pointer to the graphic block. nullptr if there was not enough memory to
165      *         create this block.
166      */
167     static
168     std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
169             const C2Handle *handle,
170             const std::shared_ptr<bufferpool_BufferPoolData> &data);
171 
172     /**
173      * Get bufferpool data from the blockpool data.
174      *
175      * \param poolData          blockpool data
176      * \param bufferPoolData    pointer to bufferpool data where the bufferpool
177      *                          data is stored.
178      *
179      * \return {\code true} when there is valid bufferpool data, {\code false} otherwise.
180      */
181     static
182     bool GetBufferPoolData(
183             const std::shared_ptr<const _C2BlockPoolData> &poolData,
184             std::shared_ptr<bufferpool_BufferPoolData> *bufferPoolData);
185 
186     // AIDL-BufferPool
187     /**
188      * Create a linear block from the received bufferpool data.
189      *
190      * \param data  bufferpool data to a linear block
191      *
192      * \return shared pointer to the linear block. nullptr if there was not enough memory to
193      *         create this block.
194      */
195     static
196     std::shared_ptr<C2LinearBlock> CreateLinearBlock(
197             const C2Handle *handle,
198             const std::shared_ptr<bufferpool2_BufferPoolData> &data);
199 
200     /**
201      * Create a graphic block from the received bufferpool data.
202      *
203      * \param data  bufferpool data to a graphic block
204      *
205      * \return shared pointer to the graphic block. nullptr if there was not enough memory to
206      *         create this block.
207      */
208     static
209     std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
210             const C2Handle *handle,
211             const std::shared_ptr<bufferpool2_BufferPoolData> &data);
212 
213     /**
214      * Get bufferpool data from the blockpool data.
215      *
216      * \param poolData          blockpool data
217      * \param bufferPoolData    pointer to bufferpool data where the bufferpool
218      *                          data is stored.
219      *
220      * \return {\code true} when there is valid bufferpool data, {\code false} otherwise.
221      */
222     static
223     bool GetBufferPoolData(
224             const std::shared_ptr<const _C2BlockPoolData> &poolData,
225             std::shared_ptr<bufferpool2_BufferPoolData> *bufferPoolData);
226 
227     /*
228      * Life Cycle Management of BufferQueue-Based Blocks
229      * =================================================
230      *
231      * A block that is created by a bufferqueue-based blockpool requires some
232      * special treatment when it is destroyed. In particular, if the block
233      * corresponds to a held (dequeued/attached) GraphicBuffer in a slot of a
234      * bufferqueue, its destruction should trigger a call to
235      * IGraphicBufferProducer::cancelBuffer(). On the other hand, if the
236      * GraphicBuffer is not held, i.e., if it has been queued or detached,
237      * cancelBuffer() should not be called upon the destruction of the block.
238      *
239      * _C2BlockPoolData created by a bufferqueue-based blockpool includes two
240      * main pieces of information:
241      *   - "held" status: Whether cancelBuffer() should be called upon
242      *     destruction of the block.
243      *   - bufferqueue assignment: The quadruple (igbp, generation, bqId,
244      *     bqSlot), where igbp is the IGraphicBufferProducer instance of the
245      *     bufferqueue, generation is the latest generation number, of the
246      *     bufferqueue, bqId is the globally unique id of the bufferqueue, and
247      *     bqSlot is the slot in the bufferqueue.
248      *
249      * igbp is the instance of IGraphicBufferProducer on which cancelBuffer()
250      * will be called if "held" status is true when the block is destroyed.
251      * (bqSlot is an input to cancelBuffer().) However, only generation, bqId
252      * and bqSlot are retained when a block is transferred from one process to
253      * another. It is the responsibility of both the sending and receiving
254      * processes to maintain consistency of "held" status and igbp. Below are
255      * functions provided for this purpose:
256      *
257      *   - GetBufferQueueData(): Returns generation, bqId and bqSlot.
258      *   - HoldBlockFromBufferQueue(): Sets "held" status to true.
259      *   - BeginTransferBlockToClient()/EndTransferBlockToClient():
260      *     Clear "held" status to false if transfer was successful,
261      *     otherwise "held" status remains true.
262      *   - BeginAttachBlockToBufferQueue()/EndAttachBlockToBufferQueue():
263      *     The will keep "held" status true if attach was eligible.
264      *     Otherwise, "held" status is cleared to false. In that case,
265      *     ownership of buffer should be transferred to bufferqueue.
266      *   - DisplayBlockToBufferQueue()
267      *     This will clear "held" status to false.
268      *
269      * All these functions operate on _C2BlockPoolData, which can be obtained by
270      * calling GetGraphicBlockPoolData().
271      *
272      * Maintaining Consistency with IGraphicBufferProducer Operations
273      * ==============================================================
274      *
275      * dequeueBuffer()
276      *   - This function is called by the blockpool. It should not be called
277      *     manually. The blockpool will automatically generate the correct
278      *     information for _C2BlockPoolData, with "held" status set to true.
279      *
280      * queueBuffer()
281      *   - Before queueBuffer() is called, DisplayBlockToBufferQueue() should be
282      *     called to test eligibility. If it's not eligible, do not call
283      *     queueBuffer().
284      *
285      * attachBuffer() - remote migration only.
286      *   - Local migration on blockpool side will be done automatically by
287      *     blockpool.
288      *   - Before attachBuffer(), BeginAttachBlockToBufferQueue() should be called
289      *     to test eligibility.
290      *   - After attachBuffer() is called, EndAttachBlockToBufferQueue() should
291      *     be called. This will set "held" status to true. If it returned
292      *     false, cancelBuffer() should be called.
293      *
294      * detachBuffer() - no-op.
295      */
296 
297     /**
298      * Get bufferqueue data from the blockpool data.
299      *
300      * Calling this function with \p generation set to nullptr will return
301      * whether the block comes from a bufferqueue-based blockpool, but will not
302      * fill in the values for \p generation, \p bqId or \p bqSlot.
303      *
304      * \param[in]  poolData   blockpool data.
305      * \param[out] generation Generation number attached to the buffer.
306      * \param[out] bqId       Id of the bufferqueue owning the buffer (block).
307      * \param[out] bqSlot     Slot number of the buffer.
308      *
309      * \return \c true when there is valid bufferqueue data;
310      *         \c false otherwise.
311      */
312     static
313     bool GetBufferQueueData(
314             const std::shared_ptr<const _C2BlockPoolData>& poolData,
315             uint32_t* generation = nullptr,
316             uint64_t* bqId = nullptr,
317             int32_t* bqSlot = nullptr);
318 
319     /**
320      * Hold a block from the designated bufferqueue. This causes the destruction
321      * of the block to trigger a call to cancelBuffer().
322      *
323      * This function assumes that \p poolData comes from a bufferqueue-based
324      * block. It does not check if that is the case.
325      *
326      * \param poolData blockpool data associated to the block.
327      * \param owner    block owner from client bufferqueue manager.
328      *                 If this is expired, the block is not owned by client
329      *                 anymore.
330      * \param igbp     \c IGraphicBufferProducer instance to be assigned to the
331      *                 block. This is not needed when the block is local.
332      * \param syncMem  Memory block which will support synchronization
333      *                 between Framework and HAL.
334      *
335      * \return The previous held status.
336      */
337     static
338     bool HoldBlockFromBufferQueue(
339             const std::shared_ptr<_C2BlockPoolData>& poolData,
340             const std::shared_ptr<int>& owner,
341             const ::android::sp<::android::hardware::graphics::bufferqueue::
342                                 V2_0::IGraphicBufferProducer>& igbp = nullptr,
343             std::shared_ptr<C2SurfaceSyncMemory> syncMem = nullptr);
344 
345     /**
346      * Prepare a block to be transferred to other process. This blocks
347      * bufferqueue migration from happening. The block should be in held.
348      *
349      * This function assumes that \p poolData comes from a bufferqueue-based
350      * block. It does not check if that is the case.
351      *
352      * \param poolData blockpool data associated to the block.
353      *
354      * \return true if transfer is eligible, false otherwise.
355      */
356     static
357     bool BeginTransferBlockToClient(
358             const std::shared_ptr<_C2BlockPoolData>& poolData);
359 
360     /**
361      * Called after transferring the specified block is finished. Make sure
362      * that BeginTransferBlockToClient() was called before this call.
363      *
364      * This will unblock bufferqueue migration. If transfer result was
365      * successful, this causes the destruction of the block not to trigger a
366      * call to cancelBuffer().
367      * This function assumes that \p poolData comes from a bufferqueue-based
368      * block. It does not check if that is the case.
369      *
370      * \param poolData blockpool data associated to the block.
371      *
372      * \return true if transfer began before, false otherwise.
373      */
374     static
375     bool EndTransferBlockToClient(
376             const std::shared_ptr<_C2BlockPoolData>& poolData,
377             bool transferred);
378 
379     /**
380      * Prepare a block to be migrated to another bufferqueue. This blocks
381      * rendering until migration has been finished.  The block should be in
382      * held.
383      *
384      * This function assumes that \p poolData comes from a bufferqueue-based
385      * block. It does not check if that is the case.
386      *
387      * \param poolData blockpool data associated to the block.
388      *
389      * \return true if migration is eligible, false otherwise.
390      */
391     static
392     bool BeginAttachBlockToBufferQueue(
393             const std::shared_ptr<_C2BlockPoolData>& poolData);
394 
395     /**
396      * Called after migration of the specified block is finished. Make sure
397      * that BeginAttachBlockToBufferQueue() was called before this call.
398      *
399      * This will unblock rendering. if redering is tried during migration,
400      * this returns false. In that case, cancelBuffer() should be called.
401      * This function assumes that \p poolData comes from a bufferqueue-based
402      * block. It does not check if that is the case.
403      *
404      * \param poolData blockpool data associated to the block.
405      *
406      * \return true if migration is eligible, false otherwise.
407      */
408     static
409     bool EndAttachBlockToBufferQueue(
410             const std::shared_ptr<_C2BlockPoolData>& poolData,
411             const std::shared_ptr<int>& owner,
412             const ::android::sp<::android::hardware::graphics::bufferqueue::
413                                 V2_0::IGraphicBufferProducer>& igbp,
414             std::shared_ptr<C2SurfaceSyncMemory>,
415             uint32_t generation,
416             uint64_t bqId,
417             int32_t bqSlot);
418 
419     /**
420      * Indicates a block to be rendered very soon.
421      *
422      * This function assumes that \p poolData comes from a bufferqueue-based
423      * block. It does not check if that is the case.
424      *
425      * \param poolData blockpool data associated to the block.
426      *
427      * \return true if migration is eligible, false otherwise.
428      */
429     static
430     bool DisplayBlockToBufferQueue(
431             const std::shared_ptr<_C2BlockPoolData>& poolData);
432 };
433 
434 #endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
435 
436