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