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