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