blob: c510fca3147986c7876ab81e4d84f623a6249855 [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
Sungtak Leea714f112021-03-16 05:40:03 -070055class C2SurfaceSyncMemory;
56
Pawin Vongmasa36653902018-11-15 00:10:25 -080057/**
58 * Internal only interface for creating blocks by block pool/buffer passing implementations.
59 *
60 * \todo this must be hidden
61 */
62struct _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.
Sungtak Lee08515812019-06-05 11:16:32 -0700211 * - 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.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800220 *
221 * All these functions operate on _C2BlockPoolData, which can be obtained by
222 * calling GetGraphicBlockPoolData().
223 *
Pawin Vongmasa36653902018-11-15 00:10:25 -0800224 * 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()
Sungtak Lee08515812019-06-05 11:16:32 -0700233 * - Before queueBuffer() is called, DisplayBlockToBufferQueue() should be
234 * called to test eligibility. If it's not eligible, do not call
235 * queueBuffer().
Pawin Vongmasa36653902018-11-15 00:10:25 -0800236 *
Sungtak Lee08515812019-06-05 11:16:32 -0700237 * 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.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800245 *
Sungtak Lee08515812019-06-05 11:16:32 -0700246 * detachBuffer() - no-op.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800247 */
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(
Sungtak Lee08515812019-06-05 11:16:32 -0700266 const std::shared_ptr<const _C2BlockPoolData>& poolData,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800267 uint32_t* generation = nullptr,
268 uint64_t* bqId = nullptr,
269 int32_t* bqSlot = nullptr);
270
271 /**
Pawin Vongmasa36653902018-11-15 00:10:25 -0800272 * 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.
Sungtak Lee08515812019-06-05 11:16:32 -0700279 * \param owner block owner from client bufferqueue manager.
280 * If this is expired, the block is not owned by client
281 * anymore.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800282 * \param igbp \c IGraphicBufferProducer instance to be assigned to the
283 * block. This is not needed when the block is local.
Sungtak Leea714f112021-03-16 05:40:03 -0700284 * \param syncMem Memory block which will support synchronization
285 * between Framework and HAL.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800286 *
287 * \return The previous held status.
288 */
289 static
290 bool HoldBlockFromBufferQueue(
291 const std::shared_ptr<_C2BlockPoolData>& poolData,
Sungtak Lee08515812019-06-05 11:16:32 -0700292 const std::shared_ptr<int>& owner,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800293 const ::android::sp<::android::hardware::graphics::bufferqueue::
Sungtak Leea714f112021-03-16 05:40:03 -0700294 V2_0::IGraphicBufferProducer>& igbp = nullptr,
295 std::shared_ptr<C2SurfaceSyncMemory> syncMem = nullptr);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800296
297 /**
Sungtak Lee08515812019-06-05 11:16:32 -0700298 * Prepare a block to be transferred to other process. This blocks
299 * bufferqueue migration from happening. The block should be in held.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800300 *
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 *
Sungtak Lee08515812019-06-05 11:16:32 -0700306 * \return true if transfer is eligible, false otherwise.
Pawin Vongmasa36653902018-11-15 00:10:25 -0800307 */
308 static
Sungtak Lee08515812019-06-05 11:16:32 -0700309 bool BeginTransferBlockToClient(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800310 const std::shared_ptr<_C2BlockPoolData>& poolData);
311
Sungtak Lee08515812019-06-05 11:16:32 -0700312 /**
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,
Sungtak Leea714f112021-03-16 05:40:03 -0700366 std::shared_ptr<C2SurfaceSyncMemory>,
Sungtak Lee08515812019-06-05 11:16:32 -0700367 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);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800384};
385
386#endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
387