• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace android {
25 namespace hardware {
26 namespace graphics {
27 namespace bufferqueue {
28 namespace V1_0 {
29 namespace utils {
30 
31 using Status = HGraphicBufferProducer::Status;
32 using ::android::hardware::graphics::common::V1_0::Dataspace;
33 typedef ::android::hardware::media::V1_0::Rect HRect;
34 typedef ::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  */
native_handle_create_from_fd(int fd)55 inline 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  */
native_handle_read_fd(native_handle_t const * nh,int index=0)78 inline 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
toStatusT(Return<Status> const & t)100 inline 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
toStatusT(Return<void> const & t)111 inline 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
wrapAs(AnwBuffer * t,GraphicBuffer const & l)122 inline 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();
128     t->attr.usage = l.getUsage();
129     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
convertTo(GraphicBuffer * l,AnwBuffer const & t)144 inline 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  */
getFenceFlattenedSize(hidl_handle const &)198 inline 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  */
getFenceFdCount(hidl_handle const & fence)209 inline 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  */
unflattenFence(hidl_handle * fence,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)228 inline 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  */
flattenFence(hidl_handle const & fence,void * & buffer,size_t & size,int * & fds,size_t & numFds)271 inline 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
wrapAs(hidl_handle * t,native_handle_t ** nh,Fence const & l)301 inline 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
convertTo(Fence * l,hidl_handle const & t)346 inline 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  */
unflatten(HRegion * t,void const * & buffer,size_t & size)409 inline 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  */
minFlattenedSize(HGraphicBufferProducer::QueueBufferInput const &)450 constexpr 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  */
unflatten(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,void const * & buffer,size_t & size,int const * & fds,size_t & numFds)478 inline 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  */
wrapAs(HGraphicBufferProducer::QueueBufferInput * t,native_handle_t ** nh,BGraphicBufferProducer::QueueBufferInput const & l)528 inline 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  */
getFlattenedSize(HGraphicBufferProducer::FenceTimeSnapshot const & t)575 inline 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  */
getFdCount(HGraphicBufferProducer::FenceTimeSnapshot const & t)597 inline 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  */
flatten(HGraphicBufferProducer::FenceTimeSnapshot const & t,native_handle_t ** nh,void * & buffer,size_t & size,int * & fds,size_t & numFds)618 inline 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  */
minFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const &)655 constexpr 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  */
getFlattenedSize(HGraphicBufferProducer::FrameEventsDelta const & t)676 inline 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  */
getFdCount(HGraphicBufferProducer::FrameEventsDelta const & t)692 inline 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
flatten(HGraphicBufferProducer::FrameEventsDelta const & t,std::vector<native_handle_t * > * nh,void * & buffer,size_t & size,int * & fds,size_t numFds)717 inline 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  */
getFlattenedSize(HGraphicBufferProducer::FrameEventHistoryDelta const & t)778 inline 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  */
getFdCount(HGraphicBufferProducer::FrameEventHistoryDelta const & t)795 inline 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  */
flatten(HGraphicBufferProducer::FrameEventHistoryDelta const & t,std::vector<std::vector<native_handle_t * >> * nh,void * & buffer,size_t & size,int * & fds,size_t & numFds)821 inline 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  */
convertTo(::android::FrameEventHistoryDelta * l,HGraphicBufferProducer::FrameEventHistoryDelta const & t)865 inline 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
convertTo(BGraphicBufferProducer::QueueBufferOutput * l,HGraphicBufferProducer::QueueBufferOutput const & t)932 inline 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  */
toHDisconnectMode(BGraphicBufferProducer::DisconnectMode l)954 inline 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 
requestBuffer(int slot,sp<GraphicBuffer> * buf)967 status_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 
setMaxDequeuedBufferCount(int maxDequeuedBuffers)981 status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
982         int maxDequeuedBuffers) {
983     return toStatusT(mBase->setMaxDequeuedBufferCount(
984             static_cast<int32_t>(maxDequeuedBuffers)));
985 }
986 
setAsyncMode(bool async)987 status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
988     return toStatusT(mBase->setAsyncMode(async));
989 }
990 
dequeueBuffer(int * slot,sp<Fence> * fence,uint32_t w,uint32_t h,::android::PixelFormat format,uint32_t usage,FrameEventHistoryDelta * outTimestamps)991 status_t H2BGraphicBufferProducer::dequeueBuffer(
992         int* slot, sp<Fence>* fence,
993         uint32_t w, uint32_t h, ::android::PixelFormat format,
994         uint32_t usage, FrameEventHistoryDelta* outTimestamps) {
995     *fence = new Fence();
996     status_t fnStatus;
997     status_t transStatus = toStatusT(mBase->dequeueBuffer(
998             w, h, static_cast<PixelFormat>(format), usage,
999             outTimestamps != nullptr,
1000             [&fnStatus, slot, fence, outTimestamps] (
1001                     Status status,
1002                     int32_t tSlot,
1003                     hidl_handle const& tFence,
1004                     HGraphicBufferProducer::FrameEventHistoryDelta const& tTs) {
1005                 fnStatus = toStatusT(status);
1006                 *slot = tSlot;
1007                 if (!convertTo(fence->get(), tFence)) {
1008                     ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
1009                             "Invalid output fence");
1010                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1011                 }
1012                 if (outTimestamps && !convertTo(outTimestamps, tTs)) {
1013                     ALOGE("H2BGraphicBufferProducer::dequeueBuffer - "
1014                             "Invalid output timestamps");
1015                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1016                 }
1017             }));
1018     return transStatus == NO_ERROR ? fnStatus : transStatus;
1019 }
1020 
detachBuffer(int slot)1021 status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
1022     return toStatusT(mBase->detachBuffer(static_cast<int>(slot)));
1023 }
1024 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence)1025 status_t H2BGraphicBufferProducer::detachNextBuffer(
1026         sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
1027     *outBuffer = new GraphicBuffer();
1028     *outFence = new Fence();
1029     status_t fnStatus;
1030     status_t transStatus = toStatusT(mBase->detachNextBuffer(
1031             [&fnStatus, outBuffer, outFence] (
1032                     Status status,
1033                     AnwBuffer const& tBuffer,
1034                     hidl_handle const& tFence) {
1035                 fnStatus = toStatusT(status);
1036                 if (!convertTo(outFence->get(), tFence)) {
1037                     ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
1038                             "Invalid output fence");
1039                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1040                 }
1041                 if (!convertTo(outBuffer->get(), tBuffer)) {
1042                     ALOGE("H2BGraphicBufferProducer::detachNextBuffer - "
1043                             "Invalid output buffer");
1044                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1045                 }
1046             }));
1047     return transStatus == NO_ERROR ? fnStatus : transStatus;
1048 }
1049 
attachBuffer(int * outSlot,const sp<GraphicBuffer> & buffer)1050 status_t H2BGraphicBufferProducer::attachBuffer(
1051         int* outSlot, const sp<GraphicBuffer>& buffer) {
1052     AnwBuffer tBuffer;
1053     wrapAs(&tBuffer, *buffer);
1054     status_t fnStatus;
1055     status_t transStatus = toStatusT(mBase->attachBuffer(tBuffer,
1056             [&fnStatus, outSlot] (Status status, int32_t slot) {
1057                 fnStatus = toStatusT(status);
1058                 *outSlot = slot;
1059             }));
1060     return transStatus == NO_ERROR ? fnStatus : transStatus;
1061 }
1062 
queueBuffer(int slot,const QueueBufferInput & input,QueueBufferOutput * output)1063 status_t H2BGraphicBufferProducer::queueBuffer(
1064         int slot,
1065         const QueueBufferInput& input,
1066         QueueBufferOutput* output) {
1067     HGraphicBufferProducer::QueueBufferInput tInput;
1068     native_handle_t* nh;
1069     if (!wrapAs(&tInput, &nh, input)) {
1070         ALOGE("H2BGraphicBufferProducer::queueBuffer - "
1071                 "Invalid input");
1072         return BAD_VALUE;
1073     }
1074     status_t fnStatus;
1075     status_t transStatus = toStatusT(mBase->queueBuffer(slot, tInput,
1076             [&fnStatus, output] (
1077                     Status status,
1078                     HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
1079                 fnStatus = toStatusT(status);
1080                 if (!convertTo(output, tOutput)) {
1081                     ALOGE("H2BGraphicBufferProducer::queueBuffer - "
1082                             "Invalid output");
1083                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1084                 }
1085             }));
1086     native_handle_delete(nh);
1087     return transStatus == NO_ERROR ? fnStatus : transStatus;
1088 }
1089 
cancelBuffer(int slot,const sp<Fence> & fence)1090 status_t H2BGraphicBufferProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
1091     hidl_handle tFence;
1092     native_handle_t* nh = nullptr;
1093     if ((fence == nullptr) || !wrapAs(&tFence, &nh, *fence)) {
1094         ALOGE("H2BGraphicBufferProducer::cancelBuffer - "
1095                 "Invalid input fence");
1096         return BAD_VALUE;
1097     }
1098 
1099     status_t status = toStatusT(mBase->cancelBuffer(
1100             static_cast<int32_t>(slot), tFence));
1101     native_handle_delete(nh);
1102     return status;
1103 }
1104 
query(int what,int * value)1105 int H2BGraphicBufferProducer::query(int what, int* value) {
1106     int result;
1107     status_t transStatus = toStatusT(mBase->query(
1108             static_cast<int32_t>(what),
1109             [&result, value] (int32_t tResult, int32_t tValue) {
1110                 result = static_cast<int>(tResult);
1111                 *value = static_cast<int>(tValue);
1112             }));
1113     return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
1114 }
1115 
connect(const sp<IProducerListener> & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)1116 status_t H2BGraphicBufferProducer::connect(
1117         const sp<IProducerListener>& listener, int api,
1118         bool producerControlledByApp, QueueBufferOutput* output) {
1119     sp<HProducerListener> tListener = listener == nullptr ?
1120             nullptr : new B2HProducerListener(listener);
1121     status_t fnStatus;
1122     status_t transStatus = toStatusT(mBase->connect(
1123             tListener, static_cast<int32_t>(api), producerControlledByApp,
1124             [&fnStatus, output] (
1125                     Status status,
1126                     HGraphicBufferProducer::QueueBufferOutput const& tOutput) {
1127                 fnStatus = toStatusT(status);
1128                 if (!convertTo(output, tOutput)) {
1129                     ALOGE("H2BGraphicBufferProducer::connect - "
1130                             "Invalid output");
1131                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1132                 }
1133             }));
1134     return transStatus == NO_ERROR ? fnStatus : transStatus;
1135 }
1136 
disconnect(int api,DisconnectMode mode)1137 status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
1138     return toStatusT(mBase->disconnect(
1139             static_cast<int32_t>(api), toHDisconnectMode(mode)));
1140 }
1141 
setSidebandStream(const sp<NativeHandle> & stream)1142 status_t H2BGraphicBufferProducer::setSidebandStream(
1143         const sp<NativeHandle>& stream) {
1144     return toStatusT(mBase->setSidebandStream(stream == nullptr ? nullptr : stream->handle()));
1145 }
1146 
allocateBuffers(uint32_t width,uint32_t height,::android::PixelFormat format,uint32_t usage)1147 void H2BGraphicBufferProducer::allocateBuffers(uint32_t width, uint32_t height,
1148         ::android::PixelFormat format, uint32_t usage) {
1149     mBase->allocateBuffers(
1150             width, height, static_cast<PixelFormat>(format), usage);
1151 }
1152 
allowAllocation(bool allow)1153 status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
1154     return toStatusT(mBase->allowAllocation(allow));
1155 }
1156 
setGenerationNumber(uint32_t generationNumber)1157 status_t H2BGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) {
1158     return toStatusT(mBase->setGenerationNumber(generationNumber));
1159 }
1160 
getConsumerName() const1161 String8 H2BGraphicBufferProducer::getConsumerName() const {
1162     String8 lName;
1163     mBase->getConsumerName([&lName] (hidl_string const& name) {
1164                 lName = name.c_str();
1165             });
1166     return lName;
1167 }
1168 
setSharedBufferMode(bool sharedBufferMode)1169 status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
1170     return toStatusT(mBase->setSharedBufferMode(sharedBufferMode));
1171 }
1172 
setAutoRefresh(bool autoRefresh)1173 status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
1174     return toStatusT(mBase->setAutoRefresh(autoRefresh));
1175 }
1176 
setDequeueTimeout(nsecs_t timeout)1177 status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
1178     return toStatusT(mBase->setDequeueTimeout(static_cast<int64_t>(timeout)));
1179 }
1180 
getLastQueuedBuffer(sp<GraphicBuffer> * outBuffer,sp<Fence> * outFence,float outTransformMatrix[16])1181 status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
1182         sp<GraphicBuffer>* outBuffer,
1183         sp<Fence>* outFence,
1184         float outTransformMatrix[16]) {
1185     status_t fnStatus;
1186     status_t transStatus = toStatusT(mBase->getLastQueuedBuffer(
1187             [&fnStatus, outBuffer, outFence, &outTransformMatrix] (
1188                     Status status,
1189                     AnwBuffer const& buffer,
1190                     hidl_handle const& fence,
1191                     hidl_array<float, 16> const& transformMatrix) {
1192                 fnStatus = toStatusT(status);
1193                 *outBuffer = new GraphicBuffer();
1194                 if (!convertTo(outBuffer->get(), buffer)) {
1195                     ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
1196                             "Invalid output buffer");
1197                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1198                 }
1199                 *outFence = new Fence();
1200                 if (!convertTo(outFence->get(), fence)) {
1201                     ALOGE("H2BGraphicBufferProducer::getLastQueuedBuffer - "
1202                             "Invalid output fence");
1203                     fnStatus = fnStatus == NO_ERROR ? BAD_VALUE : fnStatus;
1204                 }
1205                 std::copy(transformMatrix.data(),
1206                         transformMatrix.data() + 16,
1207                         outTransformMatrix);
1208             }));
1209     return transStatus == NO_ERROR ? fnStatus : transStatus;
1210 }
1211 
getFrameTimestamps(FrameEventHistoryDelta * outDelta)1212 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) {
1213     mBase->getFrameTimestamps([outDelta] (
1214             HGraphicBufferProducer::FrameEventHistoryDelta const& tDelta) {
1215                 convertTo(outDelta, tDelta);
1216             });
1217 }
1218 
getUniqueId(uint64_t * outId) const1219 status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
1220     status_t fnStatus;
1221     status_t transStatus = toStatusT(mBase->getUniqueId(
1222             [&fnStatus, outId] (Status status, uint64_t id) {
1223                 fnStatus = toStatusT(status);
1224                 *outId = id;
1225             }));
1226     return transStatus == NO_ERROR ? fnStatus : transStatus;
1227 }
1228 
1229 }  // namespace utils
1230 }  // namespace V1_0
1231 }  // namespace bufferqueue
1232 }  // namespace graphics
1233 }  // namespace hardware
1234 }  // namespace android
1235