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