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 */ 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 */ 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 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 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 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 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 */ 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 */ 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 */ 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 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 983 status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount( 984 int maxDequeuedBuffers) { 985 return toStatusT(mBase->setMaxDequeuedBufferCount( 986 static_cast<int32_t>(maxDequeuedBuffers))); 987 } 988 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 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 1028 status_t H2BGraphicBufferProducer::detachBuffer(int slot) { 1029 return toStatusT(mBase->detachBuffer(static_cast<int>(slot))); 1030 } 1031 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 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 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 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 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 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 1144 status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) { 1145 return toStatusT(mBase->disconnect( 1146 static_cast<int32_t>(api), toHDisconnectMode(mode))); 1147 } 1148 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 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 1161 status_t H2BGraphicBufferProducer::allowAllocation(bool allow) { 1162 return toStatusT(mBase->allowAllocation(allow)); 1163 } 1164 1165 status_t H2BGraphicBufferProducer::setGenerationNumber(uint32_t generationNumber) { 1166 return toStatusT(mBase->setGenerationNumber(generationNumber)); 1167 } 1168 1169 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 1177 status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) { 1178 return toStatusT(mBase->setSharedBufferMode(sharedBufferMode)); 1179 } 1180 1181 status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) { 1182 return toStatusT(mBase->setAutoRefresh(autoRefresh)); 1183 } 1184 1185 status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) { 1186 return toStatusT(mBase->setDequeueTimeout(static_cast<int64_t>(timeout))); 1187 } 1188 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 1220 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) { 1221 mBase->getFrameTimestamps([outDelta] ( 1222 HGraphicBufferProducer::FrameEventHistoryDelta const& tDelta) { 1223 convertTo(outDelta, tDelta); 1224 }); 1225 } 1226 1227 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 1237 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