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