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