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