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