1 /*
2 * Copyright 2017, 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 #define LOG_TAG "H2BGraphicBufferProducer"
18
19 #include <android-base/logging.h>
20
21 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
22 #include <gui/bufferqueue/1.0/B2HProducerListener.h>
23
24 #include <system/window.h>
25
26 namespace android {
27 namespace hardware {
28 namespace graphics {
29 namespace bufferqueue {
30 namespace V1_0 {
31 namespace utils {
32
33 using Status = HGraphicBufferProducer::Status;
34 using ::android::hardware::graphics::common::V1_0::Dataspace;
35 typedef ::android::hardware::media::V1_0::Rect HRect;
36 typedef ::android::hardware::media::V1_0::Region HRegion;
37
38 // Conversion functions
39
40 // native_handle_t helper functions.
41
42 /**
43 * \brief Take an fd and create a native handle containing only the given fd.
44 * The created handle will need to be deleted manually with
45 * `native_handle_delete()`.
46 *
47 * \param[in] fd The source file descriptor (of type `int`).
48 * \return The create `native_handle_t*` that contains the given \p fd. If the
49 * supplied \p fd is negative, the created native handle will contain no file
50 * descriptors.
51 *
52 * If the native handle cannot be created, the return value will be
53 * `nullptr`.
54 *
55 * This function does not duplicate the file descriptor.
56 */
native_handle_create_from_fd(int fd)57 inline native_handle_t* native_handle_create_from_fd(int fd) {
58 if (fd < 0) {
59 return native_handle_create(0, 0);
60 }
61 native_handle_t* nh = native_handle_create(1, 0);
62 if (nh == nullptr) {
63 return nullptr;
64 }
65 nh->data[0] = fd;
66 return nh;
67 }
68
69 /**
70 * \brief Extract a file descriptor from a native handle.
71 *
72 * \param[in] nh The source `native_handle_t*`.
73 * \param[in] index The index of the file descriptor in \p nh to read from. This
74 * input has the default value of `0`.
75 * \return The `index`-th file descriptor in \p nh. If \p nh does not have
76 * enough file descriptors, the returned value will be `-1`.
77 *
78 * This function does not duplicate the file descriptor.
79 */
native_handle_read_fd(native_handle_t const * nh,int index=0)80 inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) {
81 return ((nh == nullptr) || (nh->numFds == 0) ||
82 (nh->numFds <= index) || (index < 0)) ?
83 -1 : nh->data[index];
84 }
85
86 /**
87 * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
88 * calls.
89 *
90 * \param[in] t The source `Return<Status>`.
91 * \return The corresponding `status_t`.
92 *
93 * This function first check if \p t has a transport error. If it does, then the
94 * return value is the transport error code. Otherwise, the return value is
95 * converted from `Status` contained inside \p t.
96 *
97 * Note:
98 * - This `Status` is omx-specific. It is defined in `types.hal`.
99 * - The name of this function is not `convert`.
100 */
101 // convert: Return<Status> -> status_t
toStatusT(Return<Status> const & t)102 inline status_t toStatusT(Return<Status> const& t) {
103 return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
104 }
105
106 /**
107 * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
108 *
109 * \param[in] t The source `Return<void>`.
110 * \return The corresponding `status_t`.
111 */
112 // convert: Return<void> -> status_t
toStatusT(Return<void> const & t)113 inline status_t toStatusT(Return<void> const& t) {
114 return t.isOk() ? OK : UNKNOWN_ERROR;
115 }
116
117 /**
118 * \brief Wrap `GraphicBuffer` in `AnwBuffer`.
119 *
120 * \param[out] t The wrapper of type `AnwBuffer`.
121 * \param[in] l The source `GraphicBuffer`.
122 */
123 // wrap: GraphicBuffer -> AnwBuffer
wrapAs(AnwBuffer * t,GraphicBuffer const & l)124 inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) {
125 t->attr.width = l.getWidth();
126 t->attr.height = l.getHeight();
127 t->attr.stride = l.getStride();
128 t->attr.format = static_cast<PixelFormat>(l.getPixelFormat());
129 t->attr.layerCount = l.getLayerCount();
130 t->attr.usage = uint32_t(l.getUsage()); // FIXME: need 64-bits usage version
131 t->attr.id = l.getId();
132 t->attr.generationNumber = l.getGenerationNumber();
133 t->nativeHandle = hidl_handle(l.handle);
134 }
135
136 /**
137 * \brief Convert `AnwBuffer` to `GraphicBuffer`.
138 *
139 * \param[out] l The destination `GraphicBuffer`.
140 * \param[in] t The source `AnwBuffer`.
141 *
142 * This function will duplicate all file descriptors in \p t.
143 */
144 // convert: AnwBuffer -> GraphicBuffer
145 // Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten
convertTo(GraphicBuffer * l,AnwBuffer const & t)146 inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) {
147 native_handle_t* handle = t.nativeHandle == nullptr ?
148 nullptr : native_handle_clone(t.nativeHandle);
149
150 size_t const numInts = 12 +
151 static_cast<size_t>(handle ? handle->numInts : 0);
152 int32_t* ints = new int32_t[numInts];
153
154 size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0);
155 int* fds = new int[numFds];
156
157 ints[0] = 'GBFR';
158 ints[1] = static_cast<int32_t>(t.attr.width);
159 ints[2] = static_cast<int32_t>(t.attr.height);
160 ints[3] = static_cast<int32_t>(t.attr.stride);
161 ints[4] = static_cast<int32_t>(t.attr.format);
162 ints[5] = static_cast<int32_t>(t.attr.layerCount);
163 ints[6] = static_cast<int32_t>(t.attr.usage);
164 ints[7] = static_cast<int32_t>(t.attr.id >> 32);
165 ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF);
166 ints[9] = static_cast<int32_t>(t.attr.generationNumber);
167 ints[10] = 0;
168 ints[11] = 0;
169 if (handle) {
170 ints[10] = static_cast<int32_t>(handle->numFds);
171 ints[11] = static_cast<int32_t>(handle->numInts);
172 int* intsStart = handle->data + handle->numFds;
173 std::copy(handle->data, intsStart, fds);
174 std::copy(intsStart, intsStart + handle->numInts, &ints[12]);
175 }
176
177 void const* constBuffer = static_cast<void const*>(ints);
178 size_t size = numInts * sizeof(int32_t);
179 int const* constFds = static_cast<int const*>(fds);
180 status_t status = l->unflatten(constBuffer, size, constFds, numFds);
181
182 delete [] fds;
183 delete [] ints;
184 native_handle_delete(handle);
185 return status == NO_ERROR;
186 }
187
188 // Ref: frameworks/native/libs/ui/Fence.cpp
189
190 /**
191 * \brief Return the size of the non-fd buffer required to flatten a fence.
192 *
193 * \param[in] fence The input fence of type `hidl_handle`.
194 * \return The required size of the flat buffer.
195 *
196 * The current version of this function always returns 4, which is the number of
197 * bytes required to store the number of file descriptors contained in the fd
198 * part of the flat buffer.
199 */
getFenceFlattenedSize(hidl_handle const &)200 inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) {
201 return 4;
202 };
203
204 /**
205 * \brief Return the number of file descriptors contained in a fence.
206 *
207 * \param[in] fence The input fence of type `hidl_handle`.
208 * \return `0` if \p fence does not contain a valid file descriptor, or `1`
209 * otherwise.
210 */
getFenceFdCount(hidl_handle const & fence)211 inline size_t getFenceFdCount(hidl_handle const& fence) {
212 return native_handle_read_fd(fence) == -1 ? 0 : 1;
213 }
214
215 /**
216 * \brief Unflatten `Fence` to `hidl_handle`.
217 *
218 * \param[out] fence The destination `hidl_handle`.
219 * \param[out] nh The underlying native handle.
220 * \param[in,out] buffer The pointer to the flat non-fd buffer.
221 * \param[in,out] size The size of the flat non-fd buffer.
222 * \param[in,out] fds The pointer to the flat fd buffer.
223 * \param[in,out] numFds The size of the flat fd buffer.
224 * \return `NO_ERROR` on success; other value on failure.
225 *
226 * If the return value is `NO_ERROR`, \p nh will point to a newly created
227 * native handle, which needs to be deleted with `native_handle_delete()`
228 * afterwards.
229 */
unflattenFence(hidl_handle * fence,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)230 inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh,
231 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
232 if (size < 4) {
233 return NO_MEMORY;
234 }
235
236 uint32_t numFdsInHandle;
237 FlattenableUtils::read(buffer, size, numFdsInHandle);
238
239 if (numFdsInHandle > 1) {
240 return BAD_VALUE;
241 }
242
243 if (numFds < numFdsInHandle) {
244 return NO_MEMORY;
245 }
246
247 if (numFdsInHandle) {
248 *nh = native_handle_create_from_fd(*fds);
249 if (*nh == nullptr) {
250 return NO_MEMORY;
251 }
252 *fence = *nh;
253 ++fds;
254 --numFds;
255 } else {
256 *nh = nullptr;
257 *fence = hidl_handle();
258 }
259
260 return NO_ERROR;
261 }
262
263 /**
264 * \brief Flatten `hidl_handle` as `Fence`.
265 *
266 * \param[in] fence The source `hidl_handle`.
267 * \param[in,out] buffer The pointer to the flat non-fd buffer.
268 * \param[in,out] size The size of the flat non-fd buffer.
269 * \param[in,out] fds The pointer to the flat fd buffer.
270 * \param[in,out] numFds The size of the flat fd buffer.
271 * \return `NO_ERROR` on success; other value on failure.
272 */
flattenFence(hidl_handle const & fence,void * & buffer,size_t & size,int * & fds,size_t & numFds)273 inline status_t flattenFence(hidl_handle const& fence,
274 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
275 if (size < getFenceFlattenedSize(fence) ||
276 numFds < getFenceFdCount(fence)) {
277 return NO_MEMORY;
278 }
279 // Cast to uint32_t since the size of a size_t can vary between 32- and
280 // 64-bit processes
281 FlattenableUtils::write(buffer, size,
282 static_cast<uint32_t>(getFenceFdCount(fence)));
283 int fd = native_handle_read_fd(fence);
284 if (fd != -1) {
285 *fds = fd;
286 ++fds;
287 --numFds;
288 }
289 return NO_ERROR;
290 }
291
292 /**
293 * \brief Wrap `Fence` in `hidl_handle`.
294 *
295 * \param[out] t The wrapper of type `hidl_handle`.
296 * \param[out] nh The native handle pointed to by \p t.
297 * \param[in] l The source `Fence`.
298 *
299 * On success, \p nh will hold a newly created native handle, which must be
300 * deleted manually with `native_handle_delete()` afterwards.
301 */
302 // wrap: Fence -> hidl_handle
wrapAs(hidl_handle * t,native_handle_t ** nh,Fence const & l)303 inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) {
304 size_t const baseSize = l.getFlattenedSize();
305 std::unique_ptr<uint8_t[]> baseBuffer(
306 new (std::nothrow) uint8_t[baseSize]);
307 if (!baseBuffer) {
308 return false;
309 }
310
311 size_t const baseNumFds = l.getFdCount();
312 std::unique_ptr<int[]> baseFds(
313 new (std::nothrow) int[baseNumFds]);
314 if (!baseFds) {
315 return false;
316 }
317
318 void* buffer = static_cast<void*>(baseBuffer.get());
319 size_t size = baseSize;
320 int* fds = static_cast<int*>(baseFds.get());
321 size_t numFds = baseNumFds;
322 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
323 return false;
324 }
325
326 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
327 size = baseSize;
328 int const* constFds = static_cast<int const*>(baseFds.get());
329 numFds = baseNumFds;
330 if (unflattenFence(t, nh, constBuffer, size, constFds, numFds)
331 != NO_ERROR) {
332 return false;
333 }
334
335 return true;
336 }
337
338 /**
339 * \brief Convert `hidl_handle` to `Fence`.
340 *
341 * \param[out] l The destination `Fence`. `l` must not have been used
342 * (`l->isValid()` must return `false`) before this function is called.
343 * \param[in] t The source `hidl_handle`.
344 *
345 * If \p t contains a valid file descriptor, it will be duplicated.
346 */
347 // convert: hidl_handle -> Fence
convertTo(Fence * l,hidl_handle const & t)348 inline bool convertTo(Fence* l, hidl_handle const& t) {
349 int fd = native_handle_read_fd(t);
350 if (fd != -1) {
351 fd = dup(fd);
352 if (fd == -1) {
353 return false;
354 }
355 }
356 native_handle_t* nh = native_handle_create_from_fd(fd);
357 if (nh == nullptr) {
358 if (fd != -1) {
359 close(fd);
360 }
361 return false;
362 }
363
364 size_t const baseSize = getFenceFlattenedSize(t);
365 std::unique_ptr<uint8_t[]> baseBuffer(
366 new (std::nothrow) uint8_t[baseSize]);
367 if (!baseBuffer) {
368 native_handle_delete(nh);
369 return false;
370 }
371
372 size_t const baseNumFds = getFenceFdCount(t);
373 std::unique_ptr<int[]> baseFds(
374 new (std::nothrow) int[baseNumFds]);
375 if (!baseFds) {
376 native_handle_delete(nh);
377 return false;
378 }
379
380 void* buffer = static_cast<void*>(baseBuffer.get());
381 size_t size = baseSize;
382 int* fds = static_cast<int*>(baseFds.get());
383 size_t numFds = baseNumFds;
384 if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) {
385 native_handle_delete(nh);
386 return false;
387 }
388 native_handle_delete(nh);
389
390 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
391 size = baseSize;
392 int const* constFds = static_cast<int const*>(baseFds.get());
393 numFds = baseNumFds;
394 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
395 return false;
396 }
397
398 return true;
399 }
400
401 // Ref: frameworks/native/libs/ui/Region.cpp
402
403 /**
404 * \brief Unflatten `HRegion`.
405 *
406 * \param[out] t The destination `HRegion`.
407 * \param[in,out] buffer The pointer to the flat buffer.
408 * \param[in,out] size The size of the flat buffer.
409 * \return `NO_ERROR` on success; other value on failure.
410 */
unflatten(HRegion * t,void const * & buffer,size_t & size)411 inline status_t unflatten(HRegion* t, void const*& buffer, size_t& size) {
412 if (size < sizeof(uint32_t)) {
413 return NO_MEMORY;
414 }
415
416 uint32_t numRects = 0;
417 FlattenableUtils::read(buffer, size, numRects);
418 if (size < numRects * sizeof(HRect)) {
419 return NO_MEMORY;
420 }
421 if (numRects > (UINT32_MAX / sizeof(HRect))) {
422 return NO_MEMORY;
423 }
424
425 t->resize(numRects);
426 for (size_t r = 0; r < numRects; ++r) {
427 ::android::Rect rect(::android::Rect::EMPTY_RECT);
428 status_t status = rect.unflatten(buffer, size);
429 if (status != NO_ERROR) {
430 return status;
431 }
432 FlattenableUtils::advance(buffer, size, sizeof(rect));
433 (*t)[r] = HRect{
434 static_cast<int32_t>(rect.left),
435 static_cast<int32_t>(rect.top),
436 static_cast<int32_t>(rect.right),
437 static_cast<int32_t>(rect.bottom)};
438 }
439 return NO_ERROR;
440 }
441
442 // Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
443 // IGraphicBufferProducer::QueueBufferInput
444
445 /**
446 * \brief Return a lower bound on the size of the buffer required to flatten
447 * `HGraphicBufferProducer::QueueBufferInput`.
448 *
449 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`.
450 * \return A lower bound on the size of the flat buffer.
451 */
minFlattenedSize(HGraphicBufferProducer::QueueBufferInput const &)452 constexpr size_t minFlattenedSize(
453 HGraphicBufferProducer::QueueBufferInput const& /* t */) {
454 return sizeof(int64_t) + // timestamp
455 sizeof(int) + // isAutoTimestamp
456 sizeof(android_dataspace) + // dataSpace
457 sizeof(::android::Rect) + // crop
458 sizeof(int) + // scalingMode
459 sizeof(uint32_t) + // transform
460 sizeof(uint32_t) + // stickyTransform
461 sizeof(bool); // getFrameTimestamps
462 }
463
464 /**
465 * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`.
466 *
467 * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`.
468 * \param[out] nh The underlying native handle for `t->fence`.
469 * \param[in,out] buffer The pointer to the flat non-fd buffer.
470 * \param[in,out] size The size of the flat non-fd buffer.
471 * \param[in,out] fds The pointer to the flat fd buffer.
472 * \param[in,out] numFds The size of the flat fd buffer.
473 * \return `NO_ERROR` on success; other value on failure.
474 *
475 * If the return value is `NO_ERROR` and `t->fence` contains a valid file
476 * descriptor, \p nh will be a newly created native handle holding that file
477 * descriptor. \p nh needs to be deleted with `native_handle_delete()`
478 * afterwards.
479 */
unflatten(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)480 inline status_t unflatten(
481 HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh,
482 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) {
483 if (size < minFlattenedSize(*t)) {
484 return NO_MEMORY;
485 }
486
487 FlattenableUtils::read(buffer, size, t->timestamp);
488 int lIsAutoTimestamp;
489 FlattenableUtils::read(buffer, size, lIsAutoTimestamp);
490 t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp);
491 android_dataspace_t lDataSpace;
492 FlattenableUtils::read(buffer, size, lDataSpace);
493 t->dataSpace = static_cast<Dataspace>(lDataSpace);
494 ::android::Rect lCrop;
495 FlattenableUtils::read(buffer, size, lCrop);
496 t->crop = HRect{
497 static_cast<int32_t>(lCrop.left),
498 static_cast<int32_t>(lCrop.top),
499 static_cast<int32_t>(lCrop.right),
500 static_cast<int32_t>(lCrop.bottom)};
501 int lScalingMode;
502 FlattenableUtils::read(buffer, size, lScalingMode);
503 t->scalingMode = static_cast<int32_t>(lScalingMode);
504 FlattenableUtils::read(buffer, size, t->transform);
505 FlattenableUtils::read(buffer, size, t->stickyTransform);
506 FlattenableUtils::read(buffer, size, t->getFrameTimestamps);
507
508 status_t status = unflattenFence(&(t->fence), nh,
509 buffer, size, fds, numFds);
510 if (status != NO_ERROR) {
511 return status;
512 }
513 return unflatten(&(t->surfaceDamage), buffer, size);
514 }
515
516 /**
517 * \brief Wrap `IGraphicBufferProducer::QueueBufferInput` in
518 * `HGraphicBufferProducer::QueueBufferInput`.
519 *
520 * \param[out] t The wrapper of type
521 * `HGraphicBufferProducer::QueueBufferInput`.
522 * \param[out] nh The underlying native handle for `t->fence`.
523 * \param[in] l The source `IGraphicBufferProducer::QueueBufferInput`.
524 *
525 * If the return value is `true` and `t->fence` contains a valid file
526 * descriptor, \p nh will be a newly created native handle holding that file
527 * descriptor. \p nh needs to be deleted with `native_handle_delete()`
528 * afterwards.
529 */
wrapAs(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,BGraphicBufferProducer::QueueBufferInput const & l)530 inline bool wrapAs(
531 HGraphicBufferProducer::QueueBufferInput* t,
532 native_handle_t** nh,
533 BGraphicBufferProducer::QueueBufferInput const& l) {
534
535 size_t const baseSize = l.getFlattenedSize();
536 std::unique_ptr<uint8_t[]> baseBuffer(
537 new (std::nothrow) uint8_t[baseSize]);
538 if (!baseBuffer) {
539 return false;
540 }
541
542 size_t const baseNumFds = l.getFdCount();
543 std::unique_ptr<int[]> baseFds(
544 new (std::nothrow) int[baseNumFds]);
545 if (!baseFds) {
546 return false;
547 }
548
549 void* buffer = static_cast<void*>(baseBuffer.get());
550 size_t size = baseSize;
551 int* fds = baseFds.get();
552 size_t numFds = baseNumFds;
553 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) {
554 return false;
555 }
556
557 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
558 size = baseSize;
559 int const* constFds = static_cast<int const*>(baseFds.get());
560 numFds = baseNumFds;
561 if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) {
562 return false;
563 }
564
565 return true;
566 }
567
568 // Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot
569
570 /**
571 * \brief Return the size of the non-fd buffer required to flatten
572 * `FenceTimeSnapshot`.
573 *
574 * \param[in] t The input `FenceTimeSnapshot`.
575 * \return The required size of the flat buffer.
576 */
getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const & t)577 inline size_t getFlattenedSize(
578 HGraphicBufferProducer::FenceTimeSnapshot const& t) {
579 constexpr size_t min = sizeof(t.state);
580 switch (t.state) {
581 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
582 return min;
583 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
584 return min + getFenceFlattenedSize(t.fence);
585 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
586 return min + sizeof(
587 ::android::FenceTime::Snapshot::signalTime);
588 }
589 return 0;
590 }
591
592 /**
593 * \brief Return the number of file descriptors contained in
594 * `FenceTimeSnapshot`.
595 *
596 * \param[in] t The input `FenceTimeSnapshot`.
597 * \return The number of file descriptors contained in \p snapshot.
598 */
getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const & t)599 inline size_t getFdCount(
600 HGraphicBufferProducer::FenceTimeSnapshot const& t) {
601 return t.state ==
602 HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ?
603 getFenceFdCount(t.fence) : 0;
604 }
605
606 /**
607 * \brief Flatten `FenceTimeSnapshot`.
608 *
609 * \param[in] t The source `FenceTimeSnapshot`.
610 * \param[out] nh The cloned native handle, if necessary.
611 * \param[in,out] buffer The pointer to the flat non-fd buffer.
612 * \param[in,out] size The size of the flat non-fd buffer.
613 * \param[in,out] fds The pointer to the flat fd buffer.
614 * \param[in,out] numFds The size of the flat fd buffer.
615 * \return `NO_ERROR` on success; other value on failure.
616 *
617 * This function will duplicate the file descriptor in `t.fence` if `t.state ==
618 * FENCE`, in which case \p nh will be returned.
619 */
flatten(HGraphicBufferProducer::FenceTimeSnapshot const & t,native_handle_t ** nh,void * & buffer,size_t & size,int * & fds,size_t & numFds)620 inline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t,
621 native_handle_t** nh,
622 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
623 if (size < getFlattenedSize(t)) {
624 return NO_MEMORY;
625 }
626
627 *nh = nullptr;
628 switch (t.state) {
629 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY:
630 FlattenableUtils::write(buffer, size,
631 ::android::FenceTime::Snapshot::State::EMPTY);
632 return NO_ERROR;
633 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE:
634 FlattenableUtils::write(buffer, size,
635 ::android::FenceTime::Snapshot::State::FENCE);
636 *nh = t.fence.getNativeHandle() == nullptr ?
637 nullptr : native_handle_clone(t.fence);
638 return flattenFence(hidl_handle(*nh), buffer, size, fds, numFds);
639 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME:
640 FlattenableUtils::write(buffer, size,
641 ::android::FenceTime::Snapshot::State::SIGNAL_TIME);
642 FlattenableUtils::write(buffer, size, t.signalTimeNs);
643 return NO_ERROR;
644 }
645 return NO_ERROR;
646 }
647
648 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta
649
650 /**
651 * \brief Return a lower bound on the size of the non-fd buffer required to
652 * flatten `FrameEventsDelta`.
653 *
654 * \param[in] t The input `FrameEventsDelta`.
655 * \return A lower bound on the size of the flat buffer.
656 */
minFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const &)657 constexpr size_t minFlattenedSize(
658 HGraphicBufferProducer::FrameEventsDelta const& /* t */) {
659 return sizeof(uint64_t) + // mFrameNumber
660 sizeof(uint8_t) + // mIndex
661 sizeof(uint8_t) + // mAddPostCompositeCalled
662 sizeof(uint8_t) + // mAddRetireCalled
663 sizeof(uint8_t) + // mAddReleaseCalled
664 sizeof(nsecs_t) + // mPostedTime
665 sizeof(nsecs_t) + // mRequestedPresentTime
666 sizeof(nsecs_t) + // mLatchTime
667 sizeof(nsecs_t) + // mFirstRefreshStartTime
668 sizeof(nsecs_t); // mLastRefreshStartTime
669 }
670
671 /**
672 * \brief Return the size of the non-fd buffer required to flatten
673 * `FrameEventsDelta`.
674 *
675 * \param[in] t The input `FrameEventsDelta`.
676 * \return The required size of the flat buffer.
677 */
getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const & t)678 inline size_t getFlattenedSize(
679 HGraphicBufferProducer::FrameEventsDelta const& t) {
680 return minFlattenedSize(t) +
681 getFlattenedSize(t.gpuCompositionDoneFence) +
682 getFlattenedSize(t.displayPresentFence) +
683 getFlattenedSize(t.displayRetireFence) +
684 getFlattenedSize(t.releaseFence);
685 };
686
687 /**
688 * \brief Return the number of file descriptors contained in
689 * `FrameEventsDelta`.
690 *
691 * \param[in] t The input `FrameEventsDelta`.
692 * \return The number of file descriptors contained in \p t.
693 */
getFdCount(HGraphicBufferProducer::FrameEventsDelta const & t)694 inline size_t getFdCount(
695 HGraphicBufferProducer::FrameEventsDelta const& t) {
696 return getFdCount(t.gpuCompositionDoneFence) +
697 getFdCount(t.displayPresentFence) +
698 getFdCount(t.displayRetireFence) +
699 getFdCount(t.releaseFence);
700 };
701
702 /**
703 * \brief Flatten `FrameEventsDelta`.
704 *
705 * \param[in] t The source `FrameEventsDelta`.
706 * \param[out] nh The array of native handles that are cloned.
707 * \param[in,out] buffer The pointer to the flat non-fd buffer.
708 * \param[in,out] size The size of the flat non-fd buffer.
709 * \param[in,out] fds The pointer to the flat fd buffer.
710 * \param[in,out] numFds The size of the flat fd buffer.
711 * \return `NO_ERROR` on success; other value on failure.
712 *
713 * On success, this function will duplicate file descriptors contained in \p t.
714 * The cloned native handles will be stored in \p nh. These native handles will
715 * need to be closed by the caller.
716 */
717 // Ref: frameworks/native/libs/gui/FrameTimestamp.cpp:
718 // FrameEventsDelta::flatten
flatten(HGraphicBufferProducer::FrameEventsDelta const & t,std::vector<native_handle_t * > * nh,void * & buffer,size_t & size,int * & fds,size_t numFds)719 inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
720 std::vector<native_handle_t*>* nh,
721 void*& buffer, size_t& size, int*& fds, size_t numFds) {
722 // Check that t.index is within a valid range.
723 if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
724 || t.index > std::numeric_limits<uint8_t>::max()) {
725 return BAD_VALUE;
726 }
727
728 FlattenableUtils::write(buffer, size, t.frameNumber);
729
730 // These are static_cast to uint8_t for alignment.
731 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index));
732 FlattenableUtils::write(
733 buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled));
734 FlattenableUtils::write(
735 buffer, size, static_cast<uint8_t>(t.addRetireCalled));
736 FlattenableUtils::write(
737 buffer, size, static_cast<uint8_t>(t.addReleaseCalled));
738
739 FlattenableUtils::write(buffer, size, t.postedTimeNs);
740 FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs);
741 FlattenableUtils::write(buffer, size, t.latchTimeNs);
742 FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs);
743 FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs);
744 FlattenableUtils::write(buffer, size, t.dequeueReadyTime);
745
746 // Fences
747 HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4];
748 tSnapshot[0] = &t.gpuCompositionDoneFence;
749 tSnapshot[1] = &t.displayPresentFence;
750 tSnapshot[2] = &t.displayRetireFence;
751 tSnapshot[3] = &t.releaseFence;
752 nh->resize(4);
753 for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) {
754 status_t status = flatten(
755 *(tSnapshot[snapshotIndex]),
756 &((*nh)[snapshotIndex]),
757 buffer, size, fds, numFds);
758 if (status != NO_ERROR) {
759 while (snapshotIndex > 0) {
760 --snapshotIndex;
761 native_handle_close((*nh)[snapshotIndex]);
762 native_handle_delete((*nh)[snapshotIndex]);
763 (*nh)[snapshotIndex] = nullptr;
764 }
765 return status;
766 }
767 }
768 return NO_ERROR;
769 }
770
771 // Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta
772
773 /**
774 * \brief Return the size of the non-fd buffer required to flatten
775 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
776 *
777 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
778 * \return The required size of the flat buffer.
779 */
getFlattenedSize(HGraphicBufferProducer::FrameEventHistoryDelta const & t)780 inline size_t getFlattenedSize(
781 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
782 size_t size = 4 + // mDeltas.size()
783 sizeof(t.compositorTiming);
784 for (size_t i = 0; i < t.deltas.size(); ++i) {
785 size += getFlattenedSize(t.deltas[i]);
786 }
787 return size;
788 }
789
790 /**
791 * \brief Return the number of file descriptors contained in
792 * `HGraphicBufferProducer::FrameEventHistoryDelta`.
793 *
794 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`.
795 * \return The number of file descriptors contained in \p t.
796 */
getFdCount(HGraphicBufferProducer::FrameEventHistoryDelta const & t)797 inline size_t getFdCount(
798 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
799 size_t numFds = 0;
800 for (size_t i = 0; i < t.deltas.size(); ++i) {
801 numFds += getFdCount(t.deltas[i]);
802 }
803 return numFds;
804 }
805
806 /**
807 * \brief Flatten `FrameEventHistoryDelta`.
808 *
809 * \param[in] t The source `FrameEventHistoryDelta`.
810 * \param[out] nh The array of arrays of cloned native handles.
811 * \param[in,out] buffer The pointer to the flat non-fd buffer.
812 * \param[in,out] size The size of the flat non-fd buffer.
813 * \param[in,out] fds The pointer to the flat fd buffer.
814 * \param[in,out] numFds The size of the flat fd buffer.
815 * \return `NO_ERROR` on success; other value on failure.
816 *
817 * On success, this function will duplicate file descriptors contained in \p t.
818 * The cloned native handles will be stored in \p nh. Before making the call, \p
819 * nh should have enough space to store `n` pointers to arrays of native
820 * handles, where `n` is the length of `t.deltas`, and each `nh[i]` should have
821 * enough space to store `4` native handles.
822 */
flatten(HGraphicBufferProducer::FrameEventHistoryDelta const & t,std::vector<std::vector<native_handle_t * >> * nh,void * & buffer,size_t & size,int * & fds,size_t & numFds)823 inline status_t flatten(
824 HGraphicBufferProducer::FrameEventHistoryDelta const& t,
825 std::vector<std::vector<native_handle_t*> >* nh,
826 void*& buffer, size_t& size, int*& fds, size_t& numFds) {
827 if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
828 return BAD_VALUE;
829 }
830 if (size < getFlattenedSize(t)) {
831 return NO_MEMORY;
832 }
833
834 FlattenableUtils::write(buffer, size, t.compositorTiming);
835
836 FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size()));
837 nh->resize(t.deltas.size());
838 for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) {
839 status_t status = flatten(
840 t.deltas[deltaIndex], &((*nh)[deltaIndex]),
841 buffer, size, fds, numFds);
842 if (status != NO_ERROR) {
843 while (deltaIndex > 0) {
844 --deltaIndex;
845 for (size_t snapshotIndex = 0;
846 snapshotIndex < 4; ++snapshotIndex) {
847 native_handle_close((*nh)[deltaIndex][snapshotIndex]);
848 native_handle_delete((*nh)[deltaIndex][snapshotIndex]);
849 (*nh)[deltaIndex][snapshotIndex] = nullptr;
850 }
851 }
852 return status;
853 }
854 }
855 return NO_ERROR;
856 }
857
858 /**
859 * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to
860 * `::android::FrameEventHistoryDelta`.
861 *
862 * \param[out] l The destination `::android::FrameEventHistoryDelta`.
863 * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`.
864 *
865 * This function will duplicate all file descriptors contained in \p t.
866 */
convertTo(::android::FrameEventHistoryDelta * l,HGraphicBufferProducer::FrameEventHistoryDelta const & t)867 inline bool convertTo(
868 ::android::FrameEventHistoryDelta* l,
869 HGraphicBufferProducer::FrameEventHistoryDelta const& t) {
870
871 size_t const baseSize = getFlattenedSize(t);
872 std::unique_ptr<uint8_t[]> baseBuffer(
873 new (std::nothrow) uint8_t[baseSize]);
874 if (!baseBuffer) {
875 return false;
876 }
877
878 size_t const baseNumFds = getFdCount(t);
879 std::unique_ptr<int[]> baseFds(
880 new (std::nothrow) int[baseNumFds]);
881 if (!baseFds) {
882 return false;
883 }
884
885 void* buffer = static_cast<void*>(baseBuffer.get());
886 size_t size = baseSize;
887 int* fds = static_cast<int*>(baseFds.get());
888 size_t numFds = baseNumFds;
889 std::vector<std::vector<native_handle_t*> > nhAA;
890 if (flatten(t, &nhAA, buffer, size, fds, numFds) != NO_ERROR) {
891 return false;
892 }
893
894 void const* constBuffer = static_cast<void const*>(baseBuffer.get());
895 size = baseSize;
896 int const* constFds = static_cast<int const*>(baseFds.get());
897 numFds = baseNumFds;
898 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) {
899 for (auto nhA : nhAA) {
900 for (auto nh : nhA) {
901 if (nh != nullptr) {
902 native_handle_close(nh);
903 native_handle_delete(nh);
904 }
905 }
906 }
907 return false;
908 }
909
910 for (auto nhA : nhAA) {
911 for (auto nh : nhA) {
912 if (nh != nullptr) {
913 native_handle_delete(nh);
914 }
915 }
916 }
917 return true;
918 }
919
920 // Ref: frameworks/native/libs/gui/IGraphicBufferProducer.cpp:
921 // IGraphicBufferProducer::QueueBufferOutput
922
923 /**
924 * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to
925 * `IGraphicBufferProducer::QueueBufferOutput`.
926 *
927 * \param[out] l The destination `IGraphicBufferProducer::QueueBufferOutput`.
928 * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`.
929 *
930 * This function will duplicate all file descriptors contained in \p t.
931 */
932 // convert: HGraphicBufferProducer::QueueBufferOutput ->
933 // IGraphicBufferProducer::QueueBufferOutput
convertTo(BGraphicBufferProducer::QueueBufferOutput * l,HGraphicBufferProducer::QueueBufferOutput const & t)934 inline bool convertTo(
935 BGraphicBufferProducer::QueueBufferOutput* l,
936 HGraphicBufferProducer::QueueBufferOutput const& t) {
937 if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) {
938 return false;
939 }
940 l->width = t.width;
941 l->height = t.height;
942 l->transformHint = t.transformHint;
943 l->numPendingBuffers = t.numPendingBuffers;
944 l->nextFrameNumber = t.nextFrameNumber;
945 l->bufferReplaced = t.bufferReplaced;
946 return true;
947 }
948
949 /**
950 * \brief Convert `IGraphicBufferProducer::DisconnectMode` to
951 * `HGraphicBufferProducer::DisconnectMode`.
952 *
953 * \param[in] l The source `IGraphicBufferProducer::DisconnectMode`.
954 * \return The corresponding `HGraphicBufferProducer::DisconnectMode`.
955 */
toHDisconnectMode(BGraphicBufferProducer::DisconnectMode l)956 inline HGraphicBufferProducer::DisconnectMode toHDisconnectMode(
957 BGraphicBufferProducer::DisconnectMode l) {
958 switch (l) {
959 case BGraphicBufferProducer::DisconnectMode::Api:
960 return HGraphicBufferProducer::DisconnectMode::API;
961 case BGraphicBufferProducer::DisconnectMode::AllLocal:
962 return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL;
963 }
964 return HGraphicBufferProducer::DisconnectMode::API;
965 }
966
967 // H2BGraphicBufferProducer
968
requestBuffer(int slot,sp<GraphicBuffer> * buf)969 status_t H2BGraphicBufferProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
970 *buf = new GraphicBuffer();
971 status_t fnStatus;
972 status_t transStatus = toStatusT(mBase->requestBuffer(
973 static_cast<int32_t>(slot),
974 [&fnStatus, &buf] (Status status, AnwBuffer const& buffer) {
975 fnStatus = toStatusT(status);
976 if (!convertTo(buf->get(), buffer)) {
977 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
978 }
979 }));
980 return transStatus == NO_ERROR ? fnStatus : transStatus;
981 }
982
setMaxDequeuedBufferCount(int maxDequeuedBuffers)983 status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
984 int maxDequeuedBuffers) {
985 return toStatusT(mBase->setMaxDequeuedBufferCount(
986 static_cast<int32_t>(maxDequeuedBuffers)));
987 }
988
setAsyncMode(bool async)989 status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
990 return toStatusT(mBase->setAsyncMode(async));
991 }
992
993 // FIXME: usage bits truncated -- needs a 64-bits usage version
dequeueBuffer(int * slot,sp<Fence> * fence,uint32_t w,uint32_t h,::android::PixelFormat format,uint64_t usage,uint64_t * outBufferAge,FrameEventHistoryDelta * outTimestamps)994 status_t H2BGraphicBufferProducer::dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,
995 uint32_t h, ::android::PixelFormat format,
996 uint64_t usage, uint64_t* outBufferAge,
997 FrameEventHistoryDelta* outTimestamps) {
998 *fence = new Fence();
999 status_t fnStatus;
1000 status_t transStatus = toStatusT(mBase->dequeueBuffer(
1001 w, h, static_cast<PixelFormat>(format), uint32_t(usage),
1002 outTimestamps != nullptr,
1003 [&fnStatus, slot, fence, outTimestamps] (
1004 Status status,
1005 int32_t tSlot,
1006 hidl_handle const& tFence,
1007 HGraphicBufferProducer::FrameEventHistoryDelta const& tTs) {
1008 fnStatus = toStatusT(status);
1009 *slot = tSlot;
1010 if (!convertTo(fence->get(), tFence)) {
1011 ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
1012 "Invalid output fence");
1013 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1014 }
1015 if (outTimestamps && !convertTo(outTimestamps, tTs)) {
1016 ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
1017 "Invalid output timestamps");
1018 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1019 }
1020 }));
1021 if (outBufferAge) {
1022 // Since the HAL version doesn't return the buffer age, set it to 0:
1023 *outBufferAge = 0;
1024 }
1025 return transStatus == NO_ERROR ? fnStatus : transStatus;
1026 }
1027
detachBuffer(int slot)1028 status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
1029 return toStatusT(mBase->detachBuffer(static_cast<int>(slot)));
1030 }
1031
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)1032 status_t H2BGraphicBufferProducer::detachNextBuffer(
1033 sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
1034 *outBuffer = new GraphicBuffer();
1035 *outFence = new Fence();
1036 status_t fnStatus;
1037 status_t transStatus = toStatusT(mBase->detachNextBuffer(
1038 [&fnStatus, outBuffer, outFence] (
1039 Status status,
1040 AnwBuffer const& tBuffer,
1041 hidl_handle const& tFence) {
1042 fnStatus = toStatusT(status);
1043 if (!convertTo(outFence->get(), tFence)) {
1044 ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
1045 "Invalid output fence");
1046 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1047 }
1048 if (!convertTo(outBuffer->get(), tBuffer)) {
1049 ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
1050 "Invalid output buffer");
1051 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1052 }
1053 }));
1054 return transStatus == NO_ERROR ? fnStatus : transStatus;
1055 }
1056
attachBuffer(int * outSlot,const sp<GraphicBuffer> & buffer)1057 status_t H2BGraphicBufferProducer::attachBuffer(
1058 int* outSlot, const sp<GraphicBuffer>& buffer) {
1059 AnwBuffer tBuffer;
1060 wrapAs(&tBuffer, *buffer);
1061 status_t fnStatus;
1062 status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
1063 [&fnStatus, outSlot] (Status status, int32_t slot) {
1064 fnStatus = toStatusT(status);
1065 *outSlot = slot;
1066 }));
1067 return transStatus == NO_ERROR ? fnStatus : transStatus;
1068 }
1069
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)1070 status_t H2BGraphicBufferProducer::queueBuffer(
1071 int slot,
1072 const QueueBufferInput& input,
1073 QueueBufferOutput* output) {
1074 HGraphicBufferProducer::QueueBufferInput tInput;
1075 native_handle_t* nh;
1076 if (!wrapAs(&tInput, &nh, input)) {
1077 ALOGE("H2BGraphicBufferProducer::queueBuffer - "
1078 "Invalid input");
1079 return BAD_VALUE;
1080 }
1081 status_t fnStatus;
1082 status_t transStatus = toStatusT(mBase->queueBuffer(slot, tInput,
1083 [&fnStatus, output] (
1084 Status status,
1085 HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
1086 fnStatus = toStatusT(status);
1087 if (!convertTo(output, tOutput)) {
1088 ALOGE("H2BGraphicBufferProducer::queueBuffer - "
1089 "Invalid output");
1090 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1091 }
1092 }));
1093 native_handle_delete(nh);
1094 return transStatus == NO_ERROR ? fnStatus : transStatus;
1095 }
1096
cancelBuffer(int slot,const sp<Fence> & fence)1097 status_t H2BGraphicBufferProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
1098 hidl_handle tFence;
1099 native_handle_t* nh = nullptr;
1100 if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
1101 ALOGE("H2BGraphicBufferProducer::cancelBuffer - "
1102 "Invalid input fence");
1103 return BAD_VALUE;
1104 }
1105
1106 status_t status = toStatusT(mBase->cancelBuffer(
1107 static_cast<int32_t>(slot), tFence));
1108 native_handle_delete(nh);
1109 return status;
1110 }
1111
query(int what,int * value)1112 int H2BGraphicBufferProducer::query(int what, int* value) {
1113 int result;
1114 status_t transStatus = toStatusT(mBase->query(
1115 static_cast<int32_t>(what),
1116 [&result, value] (int32_t tResult, int32_t tValue) {
1117 result = static_cast<int>(tResult);
1118 *value = static_cast<int>(tValue);
1119 }));
1120 return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
1121 }
1122
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1123 status_t H2BGraphicBufferProducer::connect(
1124 const sp<IProducerListener>& listener, int api,
1125 bool producerControlledByApp, QueueBufferOutput* output) {
1126 sp<HProducerListener> tListener = listener == nullptr ?
1127 nullptr : new B2HProducerListener(listener);
1128 status_t fnStatus;
1129 status_t transStatus = toStatusT(mBase->connect(
1130 tListener, static_cast<int32_t>(api), producerControlledByApp,
1131 [&fnStatus, output] (
1132 Status status,
1133 HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
1134 fnStatus = toStatusT(status);
1135 if (!convertTo(output, tOutput)) {
1136 ALOGE("H2BGraphicBufferProducer::connect - "
1137 "Invalid output");
1138 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1139 }
1140 }));
1141 return transStatus == NO_ERROR ? fnStatus : transStatus;
1142 }
1143
disconnect(int api,DisconnectMode mode)1144 status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
1145 return toStatusT(mBase->disconnect(
1146 static_cast<int32_t>(api), toHDisconnectMode(mode)));
1147 }
1148
setSidebandStream(const sp<NativeHandle> & stream)1149 status_t H2BGraphicBufferProducer::setSidebandStream(
1150 const sp<NativeHandle>& stream) {
1151 return toStatusT(mBase->setSidebandStream(stream == nullptr ? nullptr : stream->handle()));
1152 }
1153
1154 // FIXME: usage bits truncated -- needs a 64-bits usage version
allocateBuffers(uint32_t width,uint32_t height,::android::PixelFormat format,uint64_t usage)1155 void H2BGraphicBufferProducer::allocateBuffers(uint32_t width, uint32_t height,
1156 ::android::PixelFormat format, uint64_t usage) {
1157 mBase->allocateBuffers(
1158 width, height, static_cast<PixelFormat>(format), uint32_t(usage));
1159 }
1160
allowAllocation(bool allow)1161 status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
1162 return toStatusT(mBase->allowAllocation(allow));
1163 }
1164
setGenerationNumber(uint32_t generationNumber)1165 status_t H2BGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) {
1166 return toStatusT(mBase->setGenerationNumber(generationNumber));
1167 }
1168
getConsumerName() const1169 String8 H2BGraphicBufferProducer::getConsumerName() const {
1170 String8 lName;
1171 mBase->getConsumerName([&lName] (hidl_string const& name) {
1172 lName = name.c_str();
1173 });
1174 return lName;
1175 }
1176
setSharedBufferMode(bool sharedBufferMode)1177 status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
1178 return toStatusT(mBase->setSharedBufferMode(sharedBufferMode));
1179 }
1180
setAutoRefresh(bool autoRefresh)1181 status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
1182 return toStatusT(mBase->setAutoRefresh(autoRefresh));
1183 }
1184
setDequeueTimeout(nsecs_t timeout)1185 status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
1186 return toStatusT(mBase->setDequeueTimeout(static_cast<int64_t>(timeout)));
1187 }
1188
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1189 status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
1190 sp<GraphicBuffer>* outBuffer,
1191 sp<Fence>* outFence,
1192 float outTransformMatrix[16]) {
1193 status_t fnStatus;
1194 status_t transStatus = toStatusT(mBase->getLastQueuedBuffer(
1195 [&fnStatus, outBuffer, outFence, &outTransformMatrix] (
1196 Status status,
1197 AnwBuffer const& buffer,
1198 hidl_handle const& fence,
1199 hidl_array<float, 16> const& transformMatrix) {
1200 fnStatus = toStatusT(status);
1201 *outBuffer = new GraphicBuffer();
1202 if (!convertTo(outBuffer->get(), buffer)) {
1203 ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
1204 "Invalid output buffer");
1205 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1206 }
1207 *outFence = new Fence();
1208 if (!convertTo(outFence->get(), fence)) {
1209 ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
1210 "Invalid output fence");
1211 fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1212 }
1213 std::copy(transformMatrix.data(),
1214 transformMatrix.data() + 16,
1215 outTransformMatrix);
1216 }));
1217 return transStatus == NO_ERROR ? fnStatus : transStatus;
1218 }
1219
getFrameTimestamps(FrameEventHistoryDelta * outDelta)1220 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
1221 mBase->getFrameTimestamps([outDelta] (
1222 HGraphicBufferProducer::FrameEventHistoryDelta const& tDelta) {
1223 convertTo(outDelta, tDelta);
1224 });
1225 }
1226
getUniqueId(uint64_t * outId) const1227 status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
1228 status_t fnStatus;
1229 status_t transStatus = toStatusT(mBase->getUniqueId(
1230 [&fnStatus, outId] (Status status, uint64_t id) {
1231 fnStatus = toStatusT(status);
1232 *outId = id;
1233 }));
1234 return transStatus == NO_ERROR ? fnStatus : transStatus;
1235 }
1236
getConsumerUsage(uint64_t * outUsage) const1237 status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t* outUsage) const {
1238 ALOGW("getConsumerUsage is not fully supported");
1239 int result;
1240 status_t transStatus = toStatusT(mBase->query(
1241 NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1242 [&result, outUsage] (int32_t tResult, int32_t tValue) {
1243 result = static_cast<int>(tResult);
1244 *outUsage = static_cast<uint64_t>(tValue);
1245 }));
1246 return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
1247 }
1248
1249 } // namespace utils
1250 } // namespace V1_0
1251 } // namespace bufferqueue
1252 } // namespace graphics
1253 } // namespace hardware
1254 } // namespace android
1255