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