Conversion.h revision fa7e967494cde81d93fba94103796f65b9e1202f
1/* 2 * Copyright 2016, 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#ifndef ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H 18#define ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H 19 20#include <vector> 21#include <list> 22 23#include <unistd.h> 24 25#include <hidl/MQDescriptor.h> 26#include <hidl/Status.h> 27#include <hidlmemory/mapping.h> 28 29#include <binder/Binder.h> 30#include <binder/Status.h> 31#include <ui/FenceTime.h> 32#include <cutils/native_handle.h> 33#include <gui/IGraphicBufferProducer.h> 34 35#include <media/OMXFenceParcelable.h> 36#include <media/OMXBuffer.h> 37#include <media/hardware/VideoAPI.h> 38 39#include <android/hidl/memory/1.0/IMemory.h> 40#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> 41#include <android/hardware/media/omx/1.0/types.h> 42#include <android/hardware/media/omx/1.0/IOmx.h> 43#include <android/hardware/media/omx/1.0/IOmxNode.h> 44#include <android/hardware/media/omx/1.0/IOmxBufferSource.h> 45#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h> 46#include <android/hardware/media/omx/1.0/IOmxObserver.h> 47 48#include <android/IGraphicBufferSource.h> 49#include <android/IOMXBufferSource.h> 50 51namespace android { 52namespace hardware { 53namespace media { 54namespace omx { 55namespace V1_0 { 56namespace implementation { 57 58using ::android::hardware::hidl_array; 59using ::android::hardware::hidl_string; 60using ::android::hardware::hidl_vec; 61using ::android::hardware::hidl_handle; 62using ::android::hardware::Return; 63using ::android::hardware::Void; 64using ::android::sp; 65 66using ::android::String8; 67using ::android::OMXFenceParcelable; 68 69using ::android::hardware::media::omx::V1_0::Message; 70using ::android::omx_message; 71 72using ::android::hardware::media::omx::V1_0::ColorAspects; 73using ::android::hardware::media::V1_0::Rect; 74using ::android::hardware::media::V1_0::Region; 75 76using ::android::hardware::graphics::common::V1_0::Dataspace; 77 78using ::android::hardware::graphics::common::V1_0::PixelFormat; 79 80using ::android::OMXBuffer; 81 82using ::android::hardware::media::V1_0::AnwBuffer; 83using ::android::GraphicBuffer; 84 85using ::android::hardware::media::omx::V1_0::IOmx; 86using ::android::IOMX; 87 88using ::android::hardware::media::omx::V1_0::IOmxNode; 89using ::android::IOMXNode; 90 91using ::android::hardware::media::omx::V1_0::IOmxObserver; 92using ::android::IOMXObserver; 93 94using ::android::hardware::media::omx::V1_0::IOmxBufferSource; 95using ::android::IOMXBufferSource; 96 97typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer 98 HGraphicBufferProducer; 99typedef ::android::IGraphicBufferProducer 100 BGraphicBufferProducer; 101 102// native_handle_t helper functions. 103 104/** 105 * \brief Take an fd and create a native handle containing only the given fd. 106 * The created handle will need to be deleted manually with 107 * `native_handle_delete()`. 108 * 109 * \param[in] fd The source file descriptor (of type `int`). 110 * \return The create `native_handle_t*` that contains the given \p fd. If the 111 * supplied \p fd is negative, the created native handle will contain no file 112 * descriptors. 113 * 114 * If the native handle cannot be created, the return value will be 115 * `nullptr`. 116 * 117 * This function does not duplicate the file descriptor. 118 */ 119inline native_handle_t* native_handle_create_from_fd(int fd) { 120 if (fd < 0) { 121 return native_handle_create(0, 0); 122 } 123 native_handle_t* nh = native_handle_create(1, 0); 124 if (nh == nullptr) { 125 return nullptr; 126 } 127 nh->data[0] = fd; 128 return nh; 129} 130 131/** 132 * \brief Extract a file descriptor from a native handle. 133 * 134 * \param[in] nh The source `native_handle_t*`. 135 * \param[in] index The index of the file descriptor in \p nh to read from. This 136 * input has the default value of `0`. 137 * \return The `index`-th file descriptor in \p nh. If \p nh does not have 138 * enough file descriptors, the returned value will be `-1`. 139 * 140 * This function does not duplicate the file descriptor. 141 */ 142inline int native_handle_read_fd(native_handle_t const* nh, int index = 0) { 143 return ((nh == nullptr) || (nh->numFds == 0) || 144 (nh->numFds <= index) || (index < 0)) ? 145 -1 : nh->data[index]; 146} 147 148/** 149 * Conversion functions 150 * ==================== 151 * 152 * There are two main directions of conversion: 153 * - `inTargetType(...)`: Create a wrapper whose lifetime depends on the 154 * input. The wrapper has type `TargetType`. 155 * - `toTargetType(...)`: Create a standalone object of type `TargetType` that 156 * corresponds to the input. The lifetime of the output does not depend on the 157 * lifetime of the input. 158 * - `wrapIn(TargetType*, ...)`: Same as `inTargetType()`, but for `TargetType` 159 * that cannot be copied and/or moved efficiently, or when there are multiple 160 * output arguments. 161 * - `convertTo(TargetType*, ...)`: Same as `toTargetType()`, but for 162 * `TargetType` that cannot be copied and/or moved efficiently, or when there 163 * are multiple output arguments. 164 * 165 * `wrapIn()` and `convertTo()` functions will take output arguments before 166 * input arguments. Some of these functions might return a value to indicate 167 * success or error. 168 * 169 * In converting or wrapping something as a Treble type that contains a 170 * `hidl_handle`, `native_handle_t*` will need to be created and returned as 171 * an additional output argument, hence only `wrapIn()` or `convertTo()` would 172 * be available. The caller must call `native_handle_delete()` to deallocate the 173 * returned native handle when it is no longer needed. 174 * 175 * For types that contain file descriptors, `inTargetType()` and `wrapAs()` do 176 * not perform duplication of file descriptors, while `toTargetType()` and 177 * `convertTo()` do. 178 */ 179 180/** 181 * \brief Convert `Return<void>` to `binder::Status`. 182 * 183 * \param[in] t The source `Return<void>`. 184 * \return The corresponding `binder::Status`. 185 */ 186// convert: Return<void> -> ::android::binder::Status 187inline ::android::binder::Status toBinderStatus( 188 Return<void> const& t) { 189 return ::android::binder::Status::fromExceptionCode( 190 t.isOk() ? OK : UNKNOWN_ERROR, 191 t.description().c_str()); 192} 193 194/** 195 * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder 196 * calls. 197 * 198 * \param[in] t The source `Return<Status>`. 199 * \return The corresponding `status_t`. 200 * 201 * This function first check if \p t has a transport error. If it does, then the 202 * return value is the transport error code. Otherwise, the return value is 203 * converted from `Status` contained inside \p t. 204 * 205 * Note: 206 * - This `Status` is omx-specific. It is defined in `types.hal`. 207 * - The name of this function is not `convert`. 208 */ 209// convert: Status -> status_t 210inline status_t toStatusT(Return<Status> const& t) { 211 return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR; 212} 213 214/** 215 * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls. 216 * 217 * \param[in] t The source `Return<void>`. 218 * \return The corresponding `status_t`. 219 */ 220// convert: Return<void> -> status_t 221inline status_t toStatusT(Return<void> const& t) { 222 return t.isOk() ? OK : UNKNOWN_ERROR; 223} 224 225/** 226 * \brief Convert `Status` to `status_t`. This is for legacy binder calls. 227 * 228 * \param[in] t The source `Status`. 229 * \return the corresponding `status_t`. 230 */ 231// convert: Status -> status_t 232inline status_t toStatusT(Status const& t) { 233 return static_cast<status_t>(t); 234} 235 236/** 237 * \brief Convert `status_t` to `Status`. 238 * 239 * \param[in] l The source `status_t`. 240 * \return The corresponding `Status`. 241 */ 242// convert: status_t -> Status 243inline Status toStatus(status_t l) { 244 return static_cast<Status>(l); 245} 246 247/** 248 * \brief Wrap `native_handle_t*` in `hidl_handle`. 249 * 250 * \param[in] nh The source `native_handle_t*`. 251 * \return The `hidl_handle` that points to \p nh. 252 */ 253// wrap: native_handle_t* -> hidl_handle 254inline hidl_handle inHidlHandle(native_handle_t const* nh) { 255 return hidl_handle(nh); 256} 257 258/** 259 * \brief Wrap an `omx_message` and construct the corresponding `Message`. 260 * 261 * \param[out] t The wrapper of type `Message`. 262 * \param[out] nh The native_handle_t referred to by `t->fence`. 263 * \param[in] l The source `omx_message`. 264 * \return `true` if the wrapping is successful; `false` otherwise. 265 * 266 * Upon success, \p nh will be created to hold the file descriptor stored in 267 * `l.fenceFd`, and `t->fence` will point to \p nh. \p nh will need to be 268 * destroyed manually by `native_handle_delete()` when \p t is no longer needed. 269 * 270 * Upon failure, \p nh will not be created and will not need to be deleted. \p t 271 * will be invalid. 272 */ 273// wrap, omx_message -> Message, native_handle_t* 274inline bool wrapAs(Message* t, native_handle_t** nh, omx_message const& l) { 275 *nh = native_handle_create_from_fd(l.fenceFd); 276 if (!*nh) { 277 return false; 278 } 279 t->fence = *nh; 280 switch (l.type) { 281 case omx_message::EVENT: 282 t->type = Message::Type::EVENT; 283 t->data.eventData.event = uint32_t(l.u.event_data.event); 284 t->data.eventData.data1 = l.u.event_data.data1; 285 t->data.eventData.data2 = l.u.event_data.data2; 286 t->data.eventData.data3 = l.u.event_data.data3; 287 t->data.eventData.data4 = l.u.event_data.data4; 288 break; 289 case omx_message::EMPTY_BUFFER_DONE: 290 t->type = Message::Type::EMPTY_BUFFER_DONE; 291 t->data.bufferData.buffer = l.u.buffer_data.buffer; 292 break; 293 case omx_message::FILL_BUFFER_DONE: 294 t->type = Message::Type::FILL_BUFFER_DONE; 295 t->data.extendedBufferData.buffer = l.u.extended_buffer_data.buffer; 296 t->data.extendedBufferData.rangeOffset = 297 l.u.extended_buffer_data.range_offset; 298 t->data.extendedBufferData.rangeLength = 299 l.u.extended_buffer_data.range_length; 300 t->data.extendedBufferData.flags = l.u.extended_buffer_data.flags; 301 t->data.extendedBufferData.timestampUs = 302 l.u.extended_buffer_data.timestamp; 303 break; 304 case omx_message::FRAME_RENDERED: 305 t->type = Message::Type::FRAME_RENDERED; 306 t->data.renderData.timestampUs = l.u.render_data.timestamp; 307 t->data.renderData.systemTimeNs = l.u.render_data.nanoTime; 308 break; 309 default: 310 native_handle_delete(*nh); 311 return false; 312 } 313 return true; 314} 315 316/** 317 * \brief Wrap a `Message` inside an `omx_message`. 318 * 319 * \param[out] l The wrapper of type `omx_message`. 320 * \param[in] t The source `Message`. 321 * \return `true` if the wrapping is successful; `false` otherwise. 322 */ 323// wrap: Message -> omx_message 324inline bool wrapAs(omx_message* l, Message const& t) { 325 l->fenceFd = native_handle_read_fd(t.fence); 326 switch (t.type) { 327 case Message::Type::EVENT: 328 l->type = omx_message::EVENT; 329 l->u.event_data.event = OMX_EVENTTYPE(t.data.eventData.event); 330 l->u.event_data.data1 = t.data.eventData.data1; 331 l->u.event_data.data2 = t.data.eventData.data2; 332 l->u.event_data.data3 = t.data.eventData.data3; 333 l->u.event_data.data4 = t.data.eventData.data4; 334 break; 335 case Message::Type::EMPTY_BUFFER_DONE: 336 l->type = omx_message::EMPTY_BUFFER_DONE; 337 l->u.buffer_data.buffer = t.data.bufferData.buffer; 338 break; 339 case Message::Type::FILL_BUFFER_DONE: 340 l->type = omx_message::FILL_BUFFER_DONE; 341 l->u.extended_buffer_data.buffer = t.data.extendedBufferData.buffer; 342 l->u.extended_buffer_data.range_offset = 343 t.data.extendedBufferData.rangeOffset; 344 l->u.extended_buffer_data.range_length = 345 t.data.extendedBufferData.rangeLength; 346 l->u.extended_buffer_data.flags = t.data.extendedBufferData.flags; 347 l->u.extended_buffer_data.timestamp = 348 t.data.extendedBufferData.timestampUs; 349 break; 350 case Message::Type::FRAME_RENDERED: 351 l->type = omx_message::FRAME_RENDERED; 352 l->u.render_data.timestamp = t.data.renderData.timestampUs; 353 l->u.render_data.nanoTime = t.data.renderData.systemTimeNs; 354 break; 355 default: 356 return false; 357 } 358 return true; 359} 360 361/** 362 * \brief Similar to `wrapTo(omx_message*, Message const&)`, but the output will 363 * have an extended lifetime. 364 * 365 * \param[out] l The output `omx_message`. 366 * \param[in] t The source `Message`. 367 * \return `true` if the conversion is successful; `false` otherwise. 368 * 369 * This function calls `wrapto()`, then attempts to duplicate the file 370 * descriptor for the fence if it is not `-1`. If duplication fails, `false` 371 * will be returned. 372 */ 373// convert: Message -> omx_message 374inline bool convertTo(omx_message* l, Message const& t) { 375 if (!wrapAs(l, t)) { 376 return false; 377 } 378 if (l->fenceFd == -1) { 379 return true; 380 } 381 l->fenceFd = dup(l->fenceFd); 382 return l->fenceFd != -1; 383} 384 385/** 386 * \brief Wrap an `OMXFenceParcelable` inside a `hidl_handle`. 387 * 388 * \param[out] t The wrapper of type `hidl_handle`. 389 * \param[out] nh The native handle created to hold the file descriptor inside 390 * \p l. 391 * \param[in] l The source `OMXFenceParcelable`, which essentially contains one 392 * file descriptor. 393 * \return `true` if \p t and \p nh are successfully created to wrap around \p 394 * l; `false` otherwise. 395 * 396 * On success, \p nh needs to be deleted by the caller with 397 * `native_handle_delete()` after \p t and \p nh are no longer needed. 398 * 399 * On failure, \p nh will not need to be deleted, and \p t will hold an invalid 400 * value. 401 */ 402// wrap: OMXFenceParcelable -> hidl_handle, native_handle_t* 403inline bool wrapAs(hidl_handle* t, native_handle_t** nh, 404 OMXFenceParcelable const& l) { 405 *nh = native_handle_create_from_fd(l.get()); 406 if (!*nh) { 407 return false; 408 } 409 *t = *nh; 410 return true; 411} 412 413/** 414 * \brief Wrap a `hidl_handle` inside an `OMXFenceParcelable`. 415 * 416 * \param[out] l The wrapper of type `OMXFenceParcelable`. 417 * \param[in] t The source `hidl_handle`. 418 */ 419// wrap: hidl_handle -> OMXFenceParcelable 420inline void wrapAs(OMXFenceParcelable* l, hidl_handle const& t) { 421 l->mFenceFd = native_handle_read_fd(t); 422} 423 424/** 425 * \brief Convert a `hidl_handle` to `OMXFenceParcelable`. If `hidl_handle` 426 * contains file descriptors, the first file descriptor will be duplicated and 427 * stored in the output `OMXFenceParcelable`. 428 * 429 * \param[out] l The output `OMXFenceParcelable`. 430 * \param[in] t The input `hidl_handle`. 431 * \return `false` if \p t contains a valid file descriptor but duplication 432 * fails; `true` otherwise. 433 */ 434// convert: hidl_handle -> OMXFenceParcelable 435inline bool convertTo(OMXFenceParcelable* l, hidl_handle const& t) { 436 int fd = native_handle_read_fd(t); 437 if (fd != -1) { 438 fd = dup(fd); 439 if (fd == -1) { 440 return false; 441 } 442 } 443 l->mFenceFd = fd; 444 return true; 445} 446 447/** 448 * \brief Convert `::android::ColorAspects` to `ColorAspects`. 449 * 450 * \param[in] l The source `::android::ColorAspects`. 451 * \return The corresponding `ColorAspects`. 452 */ 453// convert: ::android::ColorAspects -> ColorAspects 454inline ColorAspects toHardwareColorAspects(::android::ColorAspects const& l) { 455 return ColorAspects{ 456 static_cast<ColorAspects::Range>(l.mRange), 457 static_cast<ColorAspects::Primaries>(l.mPrimaries), 458 static_cast<ColorAspects::Transfer>(l.mTransfer), 459 static_cast<ColorAspects::MatrixCoeffs>(l.mMatrixCoeffs)}; 460} 461 462/** 463 * \brief Convert `int32_t` to `ColorAspects`. 464 * 465 * \param[in] l The source `int32_t`. 466 * \return The corresponding `ColorAspects`. 467 */ 468// convert: int32_t -> ColorAspects 469inline ColorAspects toHardwareColorAspects(int32_t l) { 470 return ColorAspects{ 471 static_cast<ColorAspects::Range>((l >> 24) & 0xFF), 472 static_cast<ColorAspects::Primaries>((l >> 16) & 0xFF), 473 static_cast<ColorAspects::Transfer>(l & 0xFF), 474 static_cast<ColorAspects::MatrixCoeffs>((l >> 8) & 0xFF)}; 475} 476 477/** 478 * \brief Convert `ColorAspects` to `::android::ColorAspects`. 479 * 480 * \param[in] t The source `ColorAspects`. 481 * \return The corresponding `::android::ColorAspects`. 482 */ 483// convert: ColorAspects -> ::android::ColorAspects 484inline int32_t toCompactColorAspects(ColorAspects const& t) { 485 return static_cast<int32_t>( 486 (static_cast<uint32_t>(t.range) << 24) | 487 (static_cast<uint32_t>(t.primaries) << 16) | 488 (static_cast<uint32_t>(t.transfer)) | 489 (static_cast<uint32_t>(t.matrixCoeffs) << 8)); 490} 491 492/** 493 * \brief Convert `int32_t` to `Dataspace`. 494 * 495 * \param[in] l The source `int32_t`. 496 * \result The corresponding `Dataspace`. 497 */ 498// convert: int32_t -> Dataspace 499inline Dataspace toHardwareDataspace(int32_t l) { 500 return static_cast<Dataspace>(l); 501} 502 503/** 504 * \brief Convert `Dataspace` to `int32_t`. 505 * 506 * \param[in] t The source `Dataspace`. 507 * \result The corresponding `int32_t`. 508 */ 509// convert: Dataspace -> int32_t 510inline int32_t toRawDataspace(Dataspace const& t) { 511 return static_cast<int32_t>(t); 512} 513 514/** 515 * \brief Wrap an opaque buffer inside a `hidl_vec<uint8_t>`. 516 * 517 * \param[in] l The pointer to the beginning of the opaque buffer. 518 * \param[in] size The size of the buffer. 519 * \return A `hidl_vec<uint8_t>` that points to the buffer. 520 */ 521// wrap: void*, size_t -> hidl_vec<uint8_t> 522inline hidl_vec<uint8_t> inHidlBytes(void const* l, size_t size) { 523 hidl_vec<uint8_t> t; 524 t.setToExternal(static_cast<uint8_t*>(const_cast<void*>(l)), size, false); 525 return t; 526} 527 528/** 529 * \brief Create a `hidl_vec<uint8_t>` that is a copy of an opaque buffer. 530 * 531 * \param[in] l The pointer to the beginning of the opaque buffer. 532 * \param[in] size The size of the buffer. 533 * \return A `hidl_vec<uint8_t>` that is a copy of the input buffer. 534 */ 535// convert: void*, size_t -> hidl_vec<uint8_t> 536inline hidl_vec<uint8_t> toHidlBytes(void const* l, size_t size) { 537 hidl_vec<uint8_t> t; 538 t.resize(size); 539 uint8_t const* src = static_cast<uint8_t const*>(l); 540 std::copy(src, src + size, t.data()); 541 return t; 542} 543 544/** 545 * \brief Wrap `GraphicBuffer` in `AnwBuffer`. 546 * 547 * \param[out] t The wrapper of type `AnwBuffer`. 548 * \param[in] l The source `GraphicBuffer`. 549 */ 550// wrap: GraphicBuffer -> AnwBuffer 551inline void wrapAs(AnwBuffer* t, GraphicBuffer const& l) { 552 t->attr.width = l.getWidth(); 553 t->attr.height = l.getHeight(); 554 t->attr.stride = l.getStride(); 555 t->attr.format = static_cast<PixelFormat>(l.getPixelFormat()); 556 t->attr.layerCount = l.getLayerCount(); 557 t->attr.usage = l.getUsage(); 558 t->attr.id = l.getId(); 559 t->attr.generationNumber = l.getGenerationNumber(); 560 t->nativeHandle = hidl_handle(l.handle); 561} 562 563/** 564 * \brief Convert `AnwBuffer` to `GraphicBuffer`. 565 * 566 * \param[out] l The destination `GraphicBuffer`. 567 * \param[in] t The source `AnwBuffer`. 568 * 569 * This function will duplicate all file descriptors in \p t. 570 */ 571// convert: AnwBuffer -> GraphicBuffer 572// Ref: frameworks/native/libs/ui/GraphicBuffer.cpp: GraphicBuffer::flatten 573inline bool convertTo(GraphicBuffer* l, AnwBuffer const& t) { 574 native_handle_t* handle = t.nativeHandle == nullptr ? 575 nullptr : native_handle_clone(t.nativeHandle); 576 577 size_t const numInts = 12 + (handle ? handle->numInts : 0); 578 int32_t* ints = new int32_t[numInts]; 579 580 size_t numFds = static_cast<size_t>(handle ? handle->numFds : 0); 581 int* fds = new int[numFds]; 582 583 ints[0] = 'GBFR'; 584 ints[1] = static_cast<int32_t>(t.attr.width); 585 ints[2] = static_cast<int32_t>(t.attr.height); 586 ints[3] = static_cast<int32_t>(t.attr.stride); 587 ints[4] = static_cast<int32_t>(t.attr.format); 588 ints[5] = static_cast<int32_t>(t.attr.layerCount); 589 ints[6] = static_cast<int32_t>(t.attr.usage); 590 ints[7] = static_cast<int32_t>(t.attr.id >> 32); 591 ints[8] = static_cast<int32_t>(t.attr.id & 0xFFFFFFFF); 592 ints[9] = static_cast<int32_t>(t.attr.generationNumber); 593 ints[10] = 0; 594 ints[11] = 0; 595 if (handle) { 596 ints[10] = static_cast<int32_t>(handle->numFds); 597 ints[11] = static_cast<int32_t>(handle->numInts); 598 int* intsStart = handle->data + handle->numFds; 599 std::copy(handle->data, intsStart, fds); 600 std::copy(intsStart, intsStart + handle->numInts, &ints[12]); 601 } 602 603 void const* constBuffer = static_cast<void const*>(ints); 604 size_t size = numInts * sizeof(int32_t); 605 int const* constFds = static_cast<int const*>(fds); 606 status_t status = l->unflatten(constBuffer, size, constFds, numFds); 607 608 delete [] fds; 609 delete [] ints; 610 native_handle_delete(handle); 611 return status == NO_ERROR; 612} 613 614/** 615 * \brief Wrap `GraphicBuffer` in `CodecBuffer`. 616 * 617 * \param[out] t The wrapper of type `CodecBuffer`. 618 * \param[in] l The source `GraphicBuffer`. 619 */ 620// wrap: OMXBuffer -> CodecBuffer 621inline CodecBuffer *wrapAs(CodecBuffer *t, sp<GraphicBuffer> const& graphicBuffer) { 622 t->sharedMemory = hidl_memory(); 623 t->nativeHandle = hidl_handle(); 624 t->type = CodecBuffer::Type::ANW_BUFFER; 625 if (graphicBuffer == nullptr) { 626 t->attr.anwBuffer.width = 0; 627 t->attr.anwBuffer.height = 0; 628 t->attr.anwBuffer.stride = 0; 629 t->attr.anwBuffer.format = static_cast<PixelFormat>(1); 630 t->attr.anwBuffer.layerCount = 0; 631 t->attr.anwBuffer.usage = 0; 632 return t; 633 } 634 t->attr.anwBuffer.width = graphicBuffer->getWidth(); 635 t->attr.anwBuffer.height = graphicBuffer->getHeight(); 636 t->attr.anwBuffer.stride = graphicBuffer->getStride(); 637 t->attr.anwBuffer.format = static_cast<PixelFormat>( 638 graphicBuffer->getPixelFormat()); 639 t->attr.anwBuffer.layerCount = graphicBuffer->getLayerCount(); 640 t->attr.anwBuffer.usage = graphicBuffer->getUsage(); 641 t->nativeHandle = graphicBuffer->handle; 642 return t; 643} 644 645/** 646 * \brief Wrap `OMXBuffer` in `CodecBuffer`. 647 * 648 * \param[out] t The wrapper of type `CodecBuffer`. 649 * \param[in] l The source `OMXBuffer`. 650 * \return `true` if the wrapping is successful; `false` otherwise. 651 */ 652// wrap: OMXBuffer -> CodecBuffer 653inline bool wrapAs(CodecBuffer* t, OMXBuffer const& l) { 654 t->sharedMemory = hidl_memory(); 655 t->nativeHandle = hidl_handle(); 656 switch (l.mBufferType) { 657 case OMXBuffer::kBufferTypeInvalid: { 658 t->type = CodecBuffer::Type::INVALID; 659 return true; 660 } 661 case OMXBuffer::kBufferTypePreset: { 662 t->type = CodecBuffer::Type::PRESET; 663 t->attr.preset.rangeLength = static_cast<uint32_t>(l.mRangeLength); 664 t->attr.preset.rangeOffset = static_cast<uint32_t>(l.mRangeOffset); 665 return true; 666 } 667 case OMXBuffer::kBufferTypeHidlMemory: { 668 t->type = CodecBuffer::Type::SHARED_MEM; 669 t->sharedMemory = l.mHidlMemory; 670 return true; 671 } 672 case OMXBuffer::kBufferTypeSharedMem: { 673 // This is not supported. 674 return false; 675 } 676 case OMXBuffer::kBufferTypeANWBuffer: { 677 wrapAs(t, l.mGraphicBuffer); 678 return true; 679 } 680 case OMXBuffer::kBufferTypeNativeHandle: { 681 t->type = CodecBuffer::Type::NATIVE_HANDLE; 682 t->nativeHandle = l.mNativeHandle->handle(); 683 return true; 684 } 685 } 686 return false; 687} 688 689/** 690 * \brief Convert `CodecBuffer` to `OMXBuffer`. 691 * 692 * \param[out] l The destination `OMXBuffer`. 693 * \param[in] t The source `CodecBuffer`. 694 * \return `true` if successful; `false` otherwise. 695 */ 696// convert: CodecBuffer -> OMXBuffer 697inline bool convertTo(OMXBuffer* l, CodecBuffer const& t) { 698 switch (t.type) { 699 case CodecBuffer::Type::INVALID: { 700 *l = OMXBuffer(); 701 return true; 702 } 703 case CodecBuffer::Type::PRESET: { 704 *l = OMXBuffer( 705 t.attr.preset.rangeOffset, 706 t.attr.preset.rangeLength); 707 return true; 708 } 709 case CodecBuffer::Type::SHARED_MEM: { 710 *l = OMXBuffer(t.sharedMemory); 711 return true; 712 } 713 case CodecBuffer::Type::ANW_BUFFER: { 714 if (t.nativeHandle.getNativeHandle() == nullptr) { 715 *l = OMXBuffer(sp<GraphicBuffer>(nullptr)); 716 return true; 717 } 718 AnwBuffer anwBuffer; 719 anwBuffer.nativeHandle = t.nativeHandle; 720 anwBuffer.attr = t.attr.anwBuffer; 721 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 722 if (!convertTo(graphicBuffer.get(), anwBuffer)) { 723 return false; 724 } 725 *l = OMXBuffer(graphicBuffer); 726 return true; 727 } 728 case CodecBuffer::Type::NATIVE_HANDLE: { 729 *l = OMXBuffer(NativeHandle::create( 730 native_handle_clone(t.nativeHandle), true)); 731 return true; 732 } 733 } 734 return false; 735} 736 737/** 738 * \brief Convert `IOMX::ComponentInfo` to `IOmx::ComponentInfo`. 739 * 740 * \param[out] t The destination `IOmx::ComponentInfo`. 741 * \param[in] l The source `IOMX::ComponentInfo`. 742 */ 743// convert: IOMX::ComponentInfo -> IOmx::ComponentInfo 744inline bool convertTo(IOmx::ComponentInfo* t, IOMX::ComponentInfo const& l) { 745 t->mName = l.mName.string(); 746 t->mRoles.resize(l.mRoles.size()); 747 size_t i = 0; 748 for (auto& role : l.mRoles) { 749 t->mRoles[i++] = role.string(); 750 } 751 return true; 752} 753 754/** 755 * \brief Convert `IOmx::ComponentInfo` to `IOMX::ComponentInfo`. 756 * 757 * \param[out] l The destination `IOMX::ComponentInfo`. 758 * \param[in] t The source `IOmx::ComponentInfo`. 759 */ 760// convert: IOmx::ComponentInfo -> IOMX::ComponentInfo 761inline bool convertTo(IOMX::ComponentInfo* l, IOmx::ComponentInfo const& t) { 762 l->mName = t.mName.c_str(); 763 l->mRoles.clear(); 764 for (size_t i = 0; i < t.mRoles.size(); ++i) { 765 l->mRoles.push_back(String8(t.mRoles[i].c_str())); 766 } 767 return true; 768} 769 770/** 771 * \brief Convert `OMX_BOOL` to `bool`. 772 * 773 * \param[in] l The source `OMX_BOOL`. 774 * \return The destination `bool`. 775 */ 776// convert: OMX_BOOL -> bool 777inline bool toRawBool(OMX_BOOL l) { 778 return l == OMX_FALSE ? false : true; 779} 780 781/** 782 * \brief Convert `bool` to `OMX_BOOL`. 783 * 784 * \param[in] t The source `bool`. 785 * \return The destination `OMX_BOOL`. 786 */ 787// convert: bool -> OMX_BOOL 788inline OMX_BOOL toEnumBool(bool t) { 789 return t ? OMX_TRUE : OMX_FALSE; 790} 791 792/** 793 * \brief Convert `OMX_COMMANDTYPE` to `uint32_t`. 794 * 795 * \param[in] l The source `OMX_COMMANDTYPE`. 796 * \return The underlying value of type `uint32_t`. 797 * 798 * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`. 799 */ 800// convert: OMX_COMMANDTYPE -> uint32_t 801inline uint32_t toRawCommandType(OMX_COMMANDTYPE l) { 802 return static_cast<uint32_t>(l); 803} 804 805/** 806 * \brief Convert `uint32_t` to `OMX_COMMANDTYPE`. 807 * 808 * \param[in] t The source `uint32_t`. 809 * \return The corresponding enum value of type `OMX_COMMANDTYPE`. 810 * 811 * `OMX_COMMANDTYPE` is an enum type whose underlying type is `uint32_t`. 812 */ 813// convert: uint32_t -> OMX_COMMANDTYPE 814inline OMX_COMMANDTYPE toEnumCommandType(uint32_t t) { 815 return static_cast<OMX_COMMANDTYPE>(t); 816} 817 818/** 819 * \brief Convert `OMX_INDEXTYPE` to `uint32_t`. 820 * 821 * \param[in] l The source `OMX_INDEXTYPE`. 822 * \return The underlying value of type `uint32_t`. 823 * 824 * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`. 825 */ 826// convert: OMX_INDEXTYPE -> uint32_t 827inline uint32_t toRawIndexType(OMX_INDEXTYPE l) { 828 return static_cast<uint32_t>(l); 829} 830 831/** 832 * \brief Convert `uint32_t` to `OMX_INDEXTYPE`. 833 * 834 * \param[in] t The source `uint32_t`. 835 * \return The corresponding enum value of type `OMX_INDEXTYPE`. 836 * 837 * `OMX_INDEXTYPE` is an enum type whose underlying type is `uint32_t`. 838 */ 839// convert: uint32_t -> OMX_INDEXTYPE 840inline OMX_INDEXTYPE toEnumIndexType(uint32_t t) { 841 return static_cast<OMX_INDEXTYPE>(t); 842} 843 844/** 845 * \brief Convert `IOMX::PortMode` to `PortMode`. 846 * 847 * \param[in] l The source `IOMX::PortMode`. 848 * \return The destination `PortMode`. 849 */ 850// convert: IOMX::PortMode -> PortMode 851inline PortMode toHardwarePortMode(IOMX::PortMode l) { 852 return static_cast<PortMode>(l); 853} 854 855/** 856 * \brief Convert `PortMode` to `IOMX::PortMode`. 857 * 858 * \param[in] t The source `PortMode`. 859 * \return The destination `IOMX::PortMode`. 860 */ 861// convert: PortMode -> IOMX::PortMode 862inline IOMX::PortMode toIOMXPortMode(PortMode t) { 863 return static_cast<IOMX::PortMode>(t); 864} 865 866/** 867 * \brief Convert `OMX_TICKS` to `uint64_t`. 868 * 869 * \param[in] l The source `OMX_TICKS`. 870 * \return The destination `uint64_t`. 871 */ 872// convert: OMX_TICKS -> uint64_t 873inline uint64_t toRawTicks(OMX_TICKS l) { 874#ifndef OMX_SKIP64BIT 875 return static_cast<uint64_t>(l); 876#else 877 return static_cast<uint64_t>(l.nLowPart) | 878 static_cast<uint64_t>(l.nHighPart << 32); 879#endif 880} 881 882/** 883 * \brief Convert `uint64_t` to `OMX_TICKS`. 884 * 885 * \param[in] l The source `uint64_t`. 886 * \return The destination `OMX_TICKS`. 887 */ 888// convert: uint64_t -> OMX_TICKS 889inline OMX_TICKS toOMXTicks(uint64_t t) { 890#ifndef OMX_SKIP64BIT 891 return static_cast<OMX_TICKS>(t); 892#else 893 return OMX_TICKS{ 894 static_cast<uint32_t>(t & 0xFFFFFFFF), 895 static_cast<uint32_t>(t >> 32)}; 896#endif 897} 898 899/** 900 * Conversion functions for types outside media 901 * ============================================ 902 * 903 * Some objects in libui and libgui that were made to go through binder calls do 904 * not expose ways to read or write their fields to the public. To pass an 905 * object of this kind through the HIDL boundary, translation functions need to 906 * work around the access restriction by using the publicly available 907 * `flatten()` and `unflatten()` functions. 908 * 909 * All `flatten()` and `unflatten()` overloads follow the same convention as 910 * follows: 911 * 912 * status_t flatten(ObjectType const& object, 913 * [OtherType const& other, ...] 914 * void*& buffer, size_t& size, 915 * int*& fds, size_t& numFds) 916 * 917 * status_t unflatten(ObjectType* object, 918 * [OtherType* other, ...,] 919 * void*& buffer, size_t& size, 920 * int*& fds, size_t& numFds) 921 * 922 * The number of `other` parameters varies depending on the `ObjectType`. For 923 * example, in the process of unflattening an object that contains 924 * `hidl_handle`, `other` is needed to hold `native_handle_t` objects that will 925 * be created. 926 * 927 * The last four parameters always work the same way in all overloads of 928 * `flatten()` and `unflatten()`: 929 * - For `flatten()`, `buffer` is the pointer to the non-fd buffer to be filled, 930 * `size` is the size (in bytes) of the non-fd buffer pointed to by `buffer`, 931 * `fds` is the pointer to the fd buffer to be filled, and `numFds` is the 932 * size (in ints) of the fd buffer pointed to by `fds`. 933 * - For `unflatten()`, `buffer` is the pointer to the non-fd buffer to be read 934 * from, `size` is the size (in bytes) of the non-fd buffer pointed to by 935 * `buffer`, `fds` is the pointer to the fd buffer to be read from, and 936 * `numFds` is the size (in ints) of the fd buffer pointed to by `fds`. 937 * - After a successful call to `flatten()` or `unflatten()`, `buffer` and `fds` 938 * will be advanced, while `size` and `numFds` will be decreased to reflect 939 * how much storage/data of the two buffers (fd and non-fd) have been used. 940 * - After an unsuccessful call, the values of `buffer`, `size`, `fds` and 941 * `numFds` are invalid. 942 * 943 * The return value of a successful `flatten()` or `unflatten()` call will be 944 * `OK` (also aliased as `NO_ERROR`). Any other values indicate a failure. 945 * 946 * For each object type that supports flattening, there will be two accompanying 947 * functions: `getFlattenedSize()` and `getFdCount()`. `getFlattenedSize()` will 948 * return the size of the non-fd buffer that the object will need for 949 * flattening. `getFdCount()` will return the size of the fd buffer that the 950 * object will need for flattening. 951 * 952 * The set of these four functions, `getFlattenedSize()`, `getFdCount()`, 953 * `flatten()` and `unflatten()`, are similar to functions of the same name in 954 * the abstract class `Flattenable`. The only difference is that functions in 955 * this file are not member functions of the object type. For example, we write 956 * 957 * flatten(x, buffer, size, fds, numFds) 958 * 959 * instead of 960 * 961 * x.flatten(buffer, size, fds, numFds) 962 * 963 * because we cannot modify the type of `x`. 964 * 965 * There is one exception to the naming convention: `hidl_handle` that 966 * represents a fence. The four functions for this "Fence" type have the word 967 * "Fence" attched to their names because the object type, which is 968 * `hidl_handle`, does not carry the special meaning that the object itself can 969 * only contain zero or one file descriptor. 970 */ 971 972// Ref: frameworks/native/libs/ui/Fence.cpp 973 974/** 975 * \brief Return the size of the non-fd buffer required to flatten a fence. 976 * 977 * \param[in] fence The input fence of type `hidl_handle`. 978 * \return The required size of the flat buffer. 979 * 980 * The current version of this function always returns 4, which is the number of 981 * bytes required to store the number of file descriptors contained in the fd 982 * part of the flat buffer. 983 */ 984inline size_t getFenceFlattenedSize(hidl_handle const& /* fence */) { 985 return 4; 986}; 987 988/** 989 * \brief Return the number of file descriptors contained in a fence. 990 * 991 * \param[in] fence The input fence of type `hidl_handle`. 992 * \return `0` if \p fence does not contain a valid file descriptor, or `1` 993 * otherwise. 994 */ 995inline size_t getFenceFdCount(hidl_handle const& fence) { 996 return native_handle_read_fd(fence) == -1 ? 0 : 1; 997} 998 999/** 1000 * \brief Unflatten `Fence` to `hidl_handle`. 1001 * 1002 * \param[out] fence The destination `hidl_handle`. 1003 * \param[out] nh The underlying native handle. 1004 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1005 * \param[in,out] size The size of the flat non-fd buffer. 1006 * \param[in,out] fds The pointer to the flat fd buffer. 1007 * \param[in,out] numFds The size of the flat fd buffer. 1008 * \return `NO_ERROR` on success; other value on failure. 1009 * 1010 * If the return value is `NO_ERROR`, \p nh will point to a newly created 1011 * native handle, which needs to be deleted with `native_handle_delete()` 1012 * afterwards. 1013 */ 1014inline status_t unflattenFence(hidl_handle* fence, native_handle_t** nh, 1015 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) { 1016 if (size < 4) { 1017 return NO_MEMORY; 1018 } 1019 1020 uint32_t numFdsInHandle; 1021 FlattenableUtils::read(buffer, size, numFdsInHandle); 1022 1023 if (numFdsInHandle > 1) { 1024 return BAD_VALUE; 1025 } 1026 1027 if (numFds < numFdsInHandle) { 1028 return NO_MEMORY; 1029 } 1030 1031 if (numFdsInHandle) { 1032 *nh = native_handle_create_from_fd(*fds); 1033 if (*nh == nullptr) { 1034 return NO_MEMORY; 1035 } 1036 *fence = *nh; 1037 ++fds; 1038 --numFds; 1039 } else { 1040 *nh = nullptr; 1041 *fence = hidl_handle(); 1042 } 1043 1044 return NO_ERROR; 1045} 1046 1047/** 1048 * \brief Flatten `hidl_handle` as `Fence`. 1049 * 1050 * \param[in] t The source `hidl_handle`. 1051 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1052 * \param[in,out] size The size of the flat non-fd buffer. 1053 * \param[in,out] fds The pointer to the flat fd buffer. 1054 * \param[in,out] numFds The size of the flat fd buffer. 1055 * \return `NO_ERROR` on success; other value on failure. 1056 */ 1057inline status_t flattenFence(hidl_handle const& fence, 1058 void*& buffer, size_t& size, int*& fds, size_t& numFds) { 1059 if (size < getFenceFlattenedSize(fence) || 1060 numFds < getFenceFdCount(fence)) { 1061 return NO_MEMORY; 1062 } 1063 // Cast to uint32_t since the size of a size_t can vary between 32- and 1064 // 64-bit processes 1065 FlattenableUtils::write(buffer, size, 1066 static_cast<uint32_t>(getFenceFdCount(fence))); 1067 int fd = native_handle_read_fd(fence); 1068 if (fd != -1) { 1069 *fds = fd; 1070 ++fds; 1071 --numFds; 1072 } 1073 return NO_ERROR; 1074} 1075 1076/** 1077 * \brief Wrap `Fence` in `hidl_handle`. 1078 * 1079 * \param[out] t The wrapper of type `hidl_handle`. 1080 * \param[out] nh The native handle pointed to by \p t. 1081 * \param[in] l The source `Fence`. 1082 * 1083 * On success, \p nh will hold a newly created native handle, which must be 1084 * deleted manually with `native_handle_delete()` afterwards. 1085 */ 1086// wrap: Fence -> hidl_handle 1087inline bool wrapAs(hidl_handle* t, native_handle_t** nh, Fence const& l) { 1088 size_t const baseSize = l.getFlattenedSize(); 1089 std::unique_ptr<uint8_t[]> baseBuffer( 1090 new (std::nothrow) uint8_t[baseSize]); 1091 if (!baseBuffer) { 1092 return false; 1093 } 1094 1095 size_t const baseNumFds = l.getFdCount(); 1096 std::unique_ptr<int[]> baseFds( 1097 new (std::nothrow) int[baseNumFds]); 1098 if (!baseFds) { 1099 return false; 1100 } 1101 1102 void* buffer = static_cast<void*>(baseBuffer.get()); 1103 size_t size = baseSize; 1104 int* fds = static_cast<int*>(baseFds.get()); 1105 size_t numFds = baseNumFds; 1106 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) { 1107 return false; 1108 } 1109 1110 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1111 size = baseSize; 1112 int const* constFds = static_cast<int const*>(baseFds.get()); 1113 numFds = baseNumFds; 1114 if (unflattenFence(t, nh, constBuffer, size, constFds, numFds) 1115 != NO_ERROR) { 1116 return false; 1117 } 1118 1119 return true; 1120} 1121 1122/** 1123 * \brief Convert `hidl_handle` to `Fence`. 1124 * 1125 * \param[out] l The destination `Fence`. `l` must not have been used 1126 * (`l->isValid()` must return `false`) before this function is called. 1127 * \param[in] t The source `hidl_handle`. 1128 * 1129 * If \p t contains a valid file descriptor, it will be duplicated. 1130 */ 1131// convert: hidl_handle -> Fence 1132inline bool convertTo(Fence* l, hidl_handle const& t) { 1133 int fd = native_handle_read_fd(t); 1134 if (fd != -1) { 1135 fd = dup(fd); 1136 if (fd == -1) { 1137 return false; 1138 } 1139 } 1140 native_handle_t* nh = native_handle_create_from_fd(fd); 1141 if (nh == nullptr) { 1142 if (fd != -1) { 1143 close(fd); 1144 } 1145 return false; 1146 } 1147 1148 size_t const baseSize = getFenceFlattenedSize(t); 1149 std::unique_ptr<uint8_t[]> baseBuffer( 1150 new (std::nothrow) uint8_t[baseSize]); 1151 if (!baseBuffer) { 1152 native_handle_delete(nh); 1153 return false; 1154 } 1155 1156 size_t const baseNumFds = getFenceFdCount(t); 1157 std::unique_ptr<int[]> baseFds( 1158 new (std::nothrow) int[baseNumFds]); 1159 if (!baseFds) { 1160 native_handle_delete(nh); 1161 return false; 1162 } 1163 1164 void* buffer = static_cast<void*>(baseBuffer.get()); 1165 size_t size = baseSize; 1166 int* fds = static_cast<int*>(baseFds.get()); 1167 size_t numFds = baseNumFds; 1168 if (flattenFence(hidl_handle(nh), buffer, size, fds, numFds) != NO_ERROR) { 1169 native_handle_delete(nh); 1170 return false; 1171 } 1172 native_handle_delete(nh); 1173 1174 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1175 size = baseSize; 1176 int const* constFds = static_cast<int const*>(baseFds.get()); 1177 numFds = baseNumFds; 1178 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) { 1179 return false; 1180 } 1181 1182 return true; 1183} 1184 1185// Ref: frameworks/native/libs/ui/FenceTime.cpp: FenceTime::Snapshot 1186 1187/** 1188 * \brief Return the size of the non-fd buffer required to flatten 1189 * `FenceTimeSnapshot`. 1190 * 1191 * \param[in] t The input `FenceTimeSnapshot`. 1192 * \return The required size of the flat buffer. 1193 */ 1194inline size_t getFlattenedSize( 1195 HGraphicBufferProducer::FenceTimeSnapshot const& t) { 1196 constexpr size_t min = sizeof(t.state); 1197 switch (t.state) { 1198 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY: 1199 return min; 1200 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE: 1201 return min + getFenceFlattenedSize(t.fence); 1202 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME: 1203 return min + sizeof( 1204 ::android::FenceTime::Snapshot::signalTime); 1205 } 1206 return 0; 1207} 1208 1209/** 1210 * \brief Return the number of file descriptors contained in 1211 * `FenceTimeSnapshot`. 1212 * 1213 * \param[in] t The input `FenceTimeSnapshot`. 1214 * \return The number of file descriptors contained in \p snapshot. 1215 */ 1216inline size_t getFdCount( 1217 HGraphicBufferProducer::FenceTimeSnapshot const& t) { 1218 return t.state == 1219 HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE ? 1220 getFenceFdCount(t.fence) : 0; 1221} 1222 1223/** 1224 * \brief Flatten `FenceTimeSnapshot`. 1225 * 1226 * \param[in] t The source `FenceTimeSnapshot`. 1227 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1228 * \param[in,out] size The size of the flat non-fd buffer. 1229 * \param[in,out] fds The pointer to the flat fd buffer. 1230 * \param[in,out] numFds The size of the flat fd buffer. 1231 * \return `NO_ERROR` on success; other value on failure. 1232 * 1233 * This function will duplicate the file descriptor in `t.fence` if `t.state == 1234 * FENCE`. 1235 */ 1236inline status_t flatten(HGraphicBufferProducer::FenceTimeSnapshot const& t, 1237 void*& buffer, size_t& size, int*& fds, size_t& numFds) { 1238 if (size < getFlattenedSize(t)) { 1239 return NO_MEMORY; 1240 } 1241 1242 switch (t.state) { 1243 case HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY: 1244 FlattenableUtils::write(buffer, size, 1245 ::android::FenceTime::Snapshot::State::EMPTY); 1246 return NO_ERROR; 1247 case HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE: 1248 FlattenableUtils::write(buffer, size, 1249 ::android::FenceTime::Snapshot::State::FENCE); 1250 return flattenFence(t.fence, buffer, size, fds, numFds); 1251 case HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME: 1252 FlattenableUtils::write(buffer, size, 1253 ::android::FenceTime::Snapshot::State::SIGNAL_TIME); 1254 FlattenableUtils::write(buffer, size, t.signalTimeNs); 1255 return NO_ERROR; 1256 } 1257 return NO_ERROR; 1258} 1259 1260/** 1261 * \brief Unflatten `FenceTimeSnapshot`. 1262 * 1263 * \param[out] t The destination `FenceTimeSnapshot`. 1264 * \param[out] nh The underlying native handle. 1265 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1266 * \param[in,out] size The size of the flat non-fd buffer. 1267 * \param[in,out] fds The pointer to the flat fd buffer. 1268 * \param[in,out] numFds The size of the flat fd buffer. 1269 * \return `NO_ERROR` on success; other value on failure. 1270 * 1271 * If the return value is `NO_ERROR` and the constructed snapshot contains a 1272 * file descriptor, \p nh will be created to hold that file descriptor. In this 1273 * case, \p nh needs to be deleted with `native_handle_delete()` afterwards. 1274 */ 1275inline status_t unflatten( 1276 HGraphicBufferProducer::FenceTimeSnapshot* t, native_handle_t** nh, 1277 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) { 1278 if (size < sizeof(t->state)) { 1279 return NO_MEMORY; 1280 } 1281 1282 *nh = nullptr; 1283 ::android::FenceTime::Snapshot::State state; 1284 FlattenableUtils::read(buffer, size, state); 1285 switch (state) { 1286 case ::android::FenceTime::Snapshot::State::EMPTY: 1287 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::EMPTY; 1288 return NO_ERROR; 1289 case ::android::FenceTime::Snapshot::State::FENCE: 1290 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::FENCE; 1291 return unflattenFence(&t->fence, nh, buffer, size, fds, numFds); 1292 case ::android::FenceTime::Snapshot::State::SIGNAL_TIME: 1293 t->state = HGraphicBufferProducer::FenceTimeSnapshot::State::SIGNAL_TIME; 1294 if (size < sizeof(t->signalTimeNs)) { 1295 return NO_MEMORY; 1296 } 1297 FlattenableUtils::read(buffer, size, t->signalTimeNs); 1298 return NO_ERROR; 1299 } 1300 return NO_ERROR; 1301} 1302 1303// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventsDelta 1304 1305/** 1306 * \brief Return a lower bound on the size of the non-fd buffer required to 1307 * flatten `FrameEventsDelta`. 1308 * 1309 * \param[in] t The input `FrameEventsDelta`. 1310 * \return A lower bound on the size of the flat buffer. 1311 */ 1312constexpr size_t minFlattenedSize( 1313 HGraphicBufferProducer::FrameEventsDelta const& /* t */) { 1314 return sizeof(uint64_t) + // mFrameNumber 1315 sizeof(uint8_t) + // mIndex 1316 sizeof(uint8_t) + // mAddPostCompositeCalled 1317 sizeof(uint8_t) + // mAddRetireCalled 1318 sizeof(uint8_t) + // mAddReleaseCalled 1319 sizeof(nsecs_t) + // mPostedTime 1320 sizeof(nsecs_t) + // mRequestedPresentTime 1321 sizeof(nsecs_t) + // mLatchTime 1322 sizeof(nsecs_t) + // mFirstRefreshStartTime 1323 sizeof(nsecs_t); // mLastRefreshStartTime 1324} 1325 1326/** 1327 * \brief Return the size of the non-fd buffer required to flatten 1328 * `FrameEventsDelta`. 1329 * 1330 * \param[in] t The input `FrameEventsDelta`. 1331 * \return The required size of the flat buffer. 1332 */ 1333inline size_t getFlattenedSize( 1334 HGraphicBufferProducer::FrameEventsDelta const& t) { 1335 return minFlattenedSize(t) + 1336 getFlattenedSize(t.gpuCompositionDoneFence) + 1337 getFlattenedSize(t.displayPresentFence) + 1338 getFlattenedSize(t.displayRetireFence) + 1339 getFlattenedSize(t.releaseFence); 1340}; 1341 1342/** 1343 * \brief Return the number of file descriptors contained in 1344 * `FrameEventsDelta`. 1345 * 1346 * \param[in] t The input `FrameEventsDelta`. 1347 * \return The number of file descriptors contained in \p t. 1348 */ 1349inline size_t getFdCount( 1350 HGraphicBufferProducer::FrameEventsDelta const& t) { 1351 return getFdCount(t.gpuCompositionDoneFence) + 1352 getFdCount(t.displayPresentFence) + 1353 getFdCount(t.displayRetireFence) + 1354 getFdCount(t.releaseFence); 1355}; 1356 1357/** 1358 * \brief Unflatten `FrameEventsDelta`. 1359 * 1360 * \param[out] t The destination `FrameEventsDelta`. 1361 * \param[out] nh The underlying array of native handles. 1362 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1363 * \param[in,out] size The size of the flat non-fd buffer. 1364 * \param[in,out] fds The pointer to the flat fd buffer. 1365 * \param[in,out] numFds The size of the flat fd buffer. 1366 * \return `NO_ERROR` on success; other value on failure. 1367 * 1368 * If the return value is `NO_ERROR`, \p nh will have length 4, and it will be 1369 * populated with `nullptr` or newly created handles. Each non-null slot in \p 1370 * nh will need to be deleted manually with `native_handle_delete()`. 1371 */ 1372inline status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t, 1373 std::vector<native_handle_t*>* nh, 1374 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) { 1375 if (size < minFlattenedSize(*t)) { 1376 return NO_MEMORY; 1377 } 1378 FlattenableUtils::read(buffer, size, t->frameNumber); 1379 1380 // These were written as uint8_t for alignment. 1381 uint8_t temp = 0; 1382 FlattenableUtils::read(buffer, size, temp); 1383 size_t index = static_cast<size_t>(temp); 1384 if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) { 1385 return BAD_VALUE; 1386 } 1387 t->index = static_cast<uint32_t>(index); 1388 1389 FlattenableUtils::read(buffer, size, temp); 1390 t->addPostCompositeCalled = static_cast<bool>(temp); 1391 FlattenableUtils::read(buffer, size, temp); 1392 t->addRetireCalled = static_cast<bool>(temp); 1393 FlattenableUtils::read(buffer, size, temp); 1394 t->addReleaseCalled = static_cast<bool>(temp); 1395 1396 FlattenableUtils::read(buffer, size, t->postedTimeNs); 1397 FlattenableUtils::read(buffer, size, t->requestedPresentTimeNs); 1398 FlattenableUtils::read(buffer, size, t->latchTimeNs); 1399 FlattenableUtils::read(buffer, size, t->firstRefreshStartTimeNs); 1400 FlattenableUtils::read(buffer, size, t->lastRefreshStartTimeNs); 1401 FlattenableUtils::read(buffer, size, t->dequeueReadyTime); 1402 1403 // Fences 1404 HGraphicBufferProducer::FenceTimeSnapshot* tSnapshot[4]; 1405 tSnapshot[0] = &t->gpuCompositionDoneFence; 1406 tSnapshot[1] = &t->displayPresentFence; 1407 tSnapshot[2] = &t->displayRetireFence; 1408 tSnapshot[3] = &t->releaseFence; 1409 nh->resize(4); 1410 for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) { 1411 status_t status = unflatten( 1412 tSnapshot[snapshotIndex], &((*nh)[snapshotIndex]), 1413 buffer, size, fds, numFds); 1414 if (status != NO_ERROR) { 1415 while (snapshotIndex > 0) { 1416 --snapshotIndex; 1417 if ((*nh)[snapshotIndex] != nullptr) { 1418 native_handle_delete((*nh)[snapshotIndex]); 1419 } 1420 } 1421 return status; 1422 } 1423 } 1424 return NO_ERROR; 1425} 1426 1427/** 1428 * \brief Flatten `FrameEventsDelta`. 1429 * 1430 * \param[in] t The source `FrameEventsDelta`. 1431 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1432 * \param[in,out] size The size of the flat non-fd buffer. 1433 * \param[in,out] fds The pointer to the flat fd buffer. 1434 * \param[in,out] numFds The size of the flat fd buffer. 1435 * \return `NO_ERROR` on success; other value on failure. 1436 * 1437 * This function will duplicate file descriptors contained in \p t. 1438 */ 1439// Ref: frameworks/native/libs/gui/FrameTimestamp.cpp: 1440// FrameEventsDelta::flatten 1441inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t, 1442 void*& buffer, size_t& size, int*& fds, size_t numFds) { 1443 // Check that t.index is within a valid range. 1444 if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY) 1445 || t.index > std::numeric_limits<uint8_t>::max()) { 1446 return BAD_VALUE; 1447 } 1448 1449 FlattenableUtils::write(buffer, size, t.frameNumber); 1450 1451 // These are static_cast to uint8_t for alignment. 1452 FlattenableUtils::write(buffer, size, static_cast<uint8_t>(t.index)); 1453 FlattenableUtils::write( 1454 buffer, size, static_cast<uint8_t>(t.addPostCompositeCalled)); 1455 FlattenableUtils::write( 1456 buffer, size, static_cast<uint8_t>(t.addRetireCalled)); 1457 FlattenableUtils::write( 1458 buffer, size, static_cast<uint8_t>(t.addReleaseCalled)); 1459 1460 FlattenableUtils::write(buffer, size, t.postedTimeNs); 1461 FlattenableUtils::write(buffer, size, t.requestedPresentTimeNs); 1462 FlattenableUtils::write(buffer, size, t.latchTimeNs); 1463 FlattenableUtils::write(buffer, size, t.firstRefreshStartTimeNs); 1464 FlattenableUtils::write(buffer, size, t.lastRefreshStartTimeNs); 1465 FlattenableUtils::write(buffer, size, t.dequeueReadyTime); 1466 1467 // Fences 1468 HGraphicBufferProducer::FenceTimeSnapshot const* tSnapshot[4]; 1469 tSnapshot[0] = &t.gpuCompositionDoneFence; 1470 tSnapshot[1] = &t.displayPresentFence; 1471 tSnapshot[2] = &t.displayRetireFence; 1472 tSnapshot[3] = &t.releaseFence; 1473 for (size_t snapshotIndex = 0; snapshotIndex < 4; ++snapshotIndex) { 1474 status_t status = flatten( 1475 *(tSnapshot[snapshotIndex]), buffer, size, fds, numFds); 1476 if (status != NO_ERROR) { 1477 return status; 1478 } 1479 } 1480 return NO_ERROR; 1481} 1482 1483// Ref: frameworks/native/libs/gui/FrameTimestamps.cpp: FrameEventHistoryDelta 1484 1485/** 1486 * \brief Return the size of the non-fd buffer required to flatten 1487 * `HGraphicBufferProducer::FrameEventHistoryDelta`. 1488 * 1489 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`. 1490 * \return The required size of the flat buffer. 1491 */ 1492inline size_t getFlattenedSize( 1493 HGraphicBufferProducer::FrameEventHistoryDelta const& t) { 1494 size_t size = 4 + // mDeltas.size() 1495 sizeof(t.compositorTiming); 1496 for (size_t i = 0; i < t.deltas.size(); ++i) { 1497 size += getFlattenedSize(t.deltas[i]); 1498 } 1499 return size; 1500} 1501 1502/** 1503 * \brief Return the number of file descriptors contained in 1504 * `HGraphicBufferProducer::FrameEventHistoryDelta`. 1505 * 1506 * \param[in] t The input `HGraphicBufferProducer::FrameEventHistoryDelta`. 1507 * \return The number of file descriptors contained in \p t. 1508 */ 1509inline size_t getFdCount( 1510 HGraphicBufferProducer::FrameEventHistoryDelta const& t) { 1511 size_t numFds = 0; 1512 for (size_t i = 0; i < t.deltas.size(); ++i) { 1513 numFds += getFdCount(t.deltas[i]); 1514 } 1515 return numFds; 1516} 1517 1518/** 1519 * \brief Unflatten `FrameEventHistoryDelta`. 1520 * 1521 * \param[out] t The destination `FrameEventHistoryDelta`. 1522 * \param[out] nh The underlying array of arrays of native handles. 1523 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1524 * \param[in,out] size The size of the flat non-fd buffer. 1525 * \param[in,out] fds The pointer to the flat fd buffer. 1526 * \param[in,out] numFds The size of the flat fd buffer. 1527 * \return `NO_ERROR` on success; other value on failure. 1528 * 1529 * If the return value is `NO_ERROR`, \p nh will be populated with `nullptr` or 1530 * newly created handles. The second dimension of \p nh will be 4. Each non-null 1531 * slot in \p nh will need to be deleted manually with `native_handle_delete()`. 1532 */ 1533inline status_t unflatten( 1534 HGraphicBufferProducer::FrameEventHistoryDelta* t, 1535 std::vector<std::vector<native_handle_t*> >* nh, 1536 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) { 1537 if (size < 4) { 1538 return NO_MEMORY; 1539 } 1540 1541 FlattenableUtils::read(buffer, size, t->compositorTiming); 1542 1543 uint32_t deltaCount = 0; 1544 FlattenableUtils::read(buffer, size, deltaCount); 1545 if (static_cast<size_t>(deltaCount) > 1546 ::android::FrameEventHistory::MAX_FRAME_HISTORY) { 1547 return BAD_VALUE; 1548 } 1549 t->deltas.resize(deltaCount); 1550 nh->resize(deltaCount); 1551 for (size_t deltaIndex = 0; deltaIndex < deltaCount; ++deltaIndex) { 1552 status_t status = unflatten( 1553 &(t->deltas[deltaIndex]), &((*nh)[deltaIndex]), 1554 buffer, size, fds, numFds); 1555 if (status != NO_ERROR) { 1556 return status; 1557 } 1558 } 1559 return NO_ERROR; 1560} 1561 1562/** 1563 * \brief Flatten `FrameEventHistoryDelta`. 1564 * 1565 * \param[in] t The source `FrameEventHistoryDelta`. 1566 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1567 * \param[in,out] size The size of the flat non-fd buffer. 1568 * \param[in,out] fds The pointer to the flat fd buffer. 1569 * \param[in,out] numFds The size of the flat fd buffer. 1570 * \return `NO_ERROR` on success; other value on failure. 1571 * 1572 * This function will duplicate file descriptors contained in \p t. 1573 */ 1574inline status_t flatten( 1575 HGraphicBufferProducer::FrameEventHistoryDelta const& t, 1576 void*& buffer, size_t& size, int*& fds, size_t& numFds) { 1577 if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) { 1578 return BAD_VALUE; 1579 } 1580 if (size < getFlattenedSize(t)) { 1581 return NO_MEMORY; 1582 } 1583 1584 FlattenableUtils::write(buffer, size, t.compositorTiming); 1585 1586 FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.deltas.size())); 1587 for (size_t deltaIndex = 0; deltaIndex < t.deltas.size(); ++deltaIndex) { 1588 status_t status = flatten(t.deltas[deltaIndex], buffer, size, fds, numFds); 1589 if (status != NO_ERROR) { 1590 return status; 1591 } 1592 } 1593 return NO_ERROR; 1594} 1595 1596/** 1597 * \brief Wrap `::android::FrameEventHistoryData` in 1598 * `HGraphicBufferProducer::FrameEventHistoryDelta`. 1599 * 1600 * \param[out] t The wrapper of type 1601 * `HGraphicBufferProducer::FrameEventHistoryDelta`. 1602 * \param[out] nh The array of array of native handles that are referred to by 1603 * members of \p t. 1604 * \param[in] l The source `::android::FrameEventHistoryDelta`. 1605 * 1606 * On success, each member of \p nh will be either `nullptr` or a newly created 1607 * native handle. All the non-`nullptr` elements must be deleted individually 1608 * with `native_handle_delete()`. 1609 */ 1610inline bool wrapAs(HGraphicBufferProducer::FrameEventHistoryDelta* t, 1611 std::vector<std::vector<native_handle_t*> >* nh, 1612 ::android::FrameEventHistoryDelta const& l) { 1613 1614 size_t const baseSize = l.getFlattenedSize(); 1615 std::unique_ptr<uint8_t[]> baseBuffer( 1616 new (std::nothrow) uint8_t[baseSize]); 1617 if (!baseBuffer) { 1618 return false; 1619 } 1620 1621 size_t const baseNumFds = l.getFdCount(); 1622 std::unique_ptr<int[]> baseFds( 1623 new (std::nothrow) int[baseNumFds]); 1624 if (!baseFds) { 1625 return false; 1626 } 1627 1628 void* buffer = static_cast<void*>(baseBuffer.get()); 1629 size_t size = baseSize; 1630 int* fds = baseFds.get(); 1631 size_t numFds = baseNumFds; 1632 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) { 1633 return false; 1634 } 1635 1636 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1637 size = baseSize; 1638 int const* constFds = static_cast<int const*>(baseFds.get()); 1639 numFds = baseNumFds; 1640 if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) { 1641 return false; 1642 } 1643 1644 return true; 1645} 1646 1647/** 1648 * \brief Convert `HGraphicBufferProducer::FrameEventHistoryDelta` to 1649 * `::android::FrameEventHistoryDelta`. 1650 * 1651 * \param[out] l The destination `::android::FrameEventHistoryDelta`. 1652 * \param[in] t The source `HGraphicBufferProducer::FrameEventHistoryDelta`. 1653 * 1654 * This function will duplicate all file descriptors contained in \p t. 1655 */ 1656inline bool convertTo( 1657 ::android::FrameEventHistoryDelta* l, 1658 HGraphicBufferProducer::FrameEventHistoryDelta const& t) { 1659 1660 size_t const baseSize = getFlattenedSize(t); 1661 std::unique_ptr<uint8_t[]> baseBuffer( 1662 new (std::nothrow) uint8_t[baseSize]); 1663 if (!baseBuffer) { 1664 return false; 1665 } 1666 1667 size_t const baseNumFds = getFdCount(t); 1668 std::unique_ptr<int[]> baseFds( 1669 new (std::nothrow) int[baseNumFds]); 1670 if (!baseFds) { 1671 return false; 1672 } 1673 1674 void* buffer = static_cast<void*>(baseBuffer.get()); 1675 size_t size = baseSize; 1676 int* fds = static_cast<int*>(baseFds.get()); 1677 size_t numFds = baseNumFds; 1678 if (flatten(t, buffer, size, fds, numFds) != NO_ERROR) { 1679 return false; 1680 } 1681 1682 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1683 size = baseSize; 1684 int const* constFds = static_cast<int const*>(baseFds.get()); 1685 numFds = baseNumFds; 1686 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) { 1687 return false; 1688 } 1689 1690 return true; 1691} 1692 1693// Ref: frameworks/native/libs/ui/Region.cpp 1694 1695/** 1696 * \brief Return the size of the buffer required to flatten `Region`. 1697 * 1698 * \param[in] t The input `Region`. 1699 * \return The required size of the flat buffer. 1700 */ 1701inline size_t getFlattenedSize(Region const& t) { 1702 return sizeof(uint32_t) + t.size() * sizeof(::android::Rect); 1703} 1704 1705/** 1706 * \brief Unflatten `Region`. 1707 * 1708 * \param[out] t The destination `Region`. 1709 * \param[in,out] buffer The pointer to the flat buffer. 1710 * \param[in,out] size The size of the flat buffer. 1711 * \return `NO_ERROR` on success; other value on failure. 1712 */ 1713inline status_t unflatten(Region* t, void const*& buffer, size_t& size) { 1714 if (size < sizeof(uint32_t)) { 1715 return NO_MEMORY; 1716 } 1717 1718 uint32_t numRects = 0; 1719 FlattenableUtils::read(buffer, size, numRects); 1720 if (size < numRects * sizeof(Rect)) { 1721 return NO_MEMORY; 1722 } 1723 if (numRects > (UINT32_MAX / sizeof(Rect))) { 1724 return NO_MEMORY; 1725 } 1726 1727 t->resize(numRects); 1728 for (size_t r = 0; r < numRects; ++r) { 1729 ::android::Rect rect(::android::Rect::EMPTY_RECT); 1730 status_t status = rect.unflatten(buffer, size); 1731 if (status != NO_ERROR) { 1732 return status; 1733 } 1734 FlattenableUtils::advance(buffer, size, sizeof(rect)); 1735 (*t)[r] = Rect{ 1736 static_cast<int32_t>(rect.left), 1737 static_cast<int32_t>(rect.top), 1738 static_cast<int32_t>(rect.right), 1739 static_cast<int32_t>(rect.bottom)}; 1740 } 1741 return NO_ERROR; 1742} 1743 1744/** 1745 * \brief Flatten `Region`. 1746 * 1747 * \param[in] t The source `Region`. 1748 * \param[in,out] buffer The pointer to the flat buffer. 1749 * \param[in,out] size The size of the flat buffer. 1750 * \return `NO_ERROR` on success; other value on failure. 1751 */ 1752inline status_t flatten(Region const& t, void*& buffer, size_t& size) { 1753 if (size < getFlattenedSize(t)) { 1754 return NO_MEMORY; 1755 } 1756 1757 FlattenableUtils::write(buffer, size, static_cast<uint32_t>(t.size())); 1758 for (size_t r = 0; r < t.size(); ++r) { 1759 ::android::Rect rect( 1760 static_cast<int32_t>(t[r].left), 1761 static_cast<int32_t>(t[r].top), 1762 static_cast<int32_t>(t[r].right), 1763 static_cast<int32_t>(t[r].bottom)); 1764 status_t status = rect.flatten(buffer, size); 1765 if (status != NO_ERROR) { 1766 return status; 1767 } 1768 FlattenableUtils::advance(buffer, size, sizeof(rect)); 1769 } 1770 return NO_ERROR; 1771} 1772 1773/** 1774 * \brief Convert `::android::Region` to `Region`. 1775 * 1776 * \param[out] t The destination `Region`. 1777 * \param[in] l The source `::android::Region`. 1778 */ 1779// convert: ::android::Region -> Region 1780inline bool convertTo(Region* t, ::android::Region const& l) { 1781 size_t const baseSize = l.getFlattenedSize(); 1782 std::unique_ptr<uint8_t[]> baseBuffer( 1783 new (std::nothrow) uint8_t[baseSize]); 1784 if (!baseBuffer) { 1785 return false; 1786 } 1787 1788 void* buffer = static_cast<void*>(baseBuffer.get()); 1789 size_t size = baseSize; 1790 if (l.flatten(buffer, size) != NO_ERROR) { 1791 return false; 1792 } 1793 1794 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1795 size = baseSize; 1796 if (unflatten(t, constBuffer, size) != NO_ERROR) { 1797 return false; 1798 } 1799 1800 return true; 1801} 1802 1803/** 1804 * \brief Convert `Region` to `::android::Region`. 1805 * 1806 * \param[out] l The destination `::android::Region`. 1807 * \param[in] t The source `Region`. 1808 */ 1809// convert: Region -> ::android::Region 1810inline bool convertTo(::android::Region* l, Region const& t) { 1811 size_t const baseSize = getFlattenedSize(t); 1812 std::unique_ptr<uint8_t[]> baseBuffer( 1813 new (std::nothrow) uint8_t[baseSize]); 1814 if (!baseBuffer) { 1815 return false; 1816 } 1817 1818 void* buffer = static_cast<void*>(baseBuffer.get()); 1819 size_t size = baseSize; 1820 if (flatten(t, buffer, size) != NO_ERROR) { 1821 return false; 1822 } 1823 1824 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 1825 size = baseSize; 1826 if (l->unflatten(constBuffer, size) != NO_ERROR) { 1827 return false; 1828 } 1829 1830 return true; 1831} 1832 1833// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp: 1834// BGraphicBufferProducer::QueueBufferInput 1835 1836/** 1837 * \brief Return a lower bound on the size of the buffer required to flatten 1838 * `HGraphicBufferProducer::QueueBufferInput`. 1839 * 1840 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`. 1841 * \return A lower bound on the size of the flat buffer. 1842 */ 1843constexpr size_t minFlattenedSize( 1844 HGraphicBufferProducer::QueueBufferInput const& /* t */) { 1845 return sizeof(int64_t) + // timestamp 1846 sizeof(int) + // isAutoTimestamp 1847 sizeof(android_dataspace) + // dataSpace 1848 sizeof(::android::Rect) + // crop 1849 sizeof(int) + // scalingMode 1850 sizeof(uint32_t) + // transform 1851 sizeof(uint32_t) + // stickyTransform 1852 sizeof(bool); // getFrameTimestamps 1853} 1854 1855/** 1856 * \brief Return the size of the buffer required to flatten 1857 * `HGraphicBufferProducer::QueueBufferInput`. 1858 * 1859 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`. 1860 * \return The required size of the flat buffer. 1861 */ 1862inline size_t getFlattenedSize(HGraphicBufferProducer::QueueBufferInput const& t) { 1863 return minFlattenedSize(t) + 1864 getFenceFlattenedSize(t.fence) + 1865 getFlattenedSize(t.surfaceDamage) + 1866 sizeof(HdrMetadata::validTypes); 1867} 1868 1869/** 1870 * \brief Return the number of file descriptors contained in 1871 * `HGraphicBufferProducer::QueueBufferInput`. 1872 * 1873 * \param[in] t The input `HGraphicBufferProducer::QueueBufferInput`. 1874 * \return The number of file descriptors contained in \p t. 1875 */ 1876inline size_t getFdCount( 1877 HGraphicBufferProducer::QueueBufferInput const& t) { 1878 return getFenceFdCount(t.fence); 1879} 1880 1881/** 1882 * \brief Flatten `HGraphicBufferProducer::QueueBufferInput`. 1883 * 1884 * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`. 1885 * \param[out] nh The native handle cloned from `t.fence`. 1886 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1887 * \param[in,out] size The size of the flat non-fd buffer. 1888 * \param[in,out] fds The pointer to the flat fd buffer. 1889 * \param[in,out] numFds The size of the flat fd buffer. 1890 * \return `NO_ERROR` on success; other value on failure. 1891 * 1892 * This function will duplicate the file descriptor in `t.fence`. */ 1893inline status_t flatten(HGraphicBufferProducer::QueueBufferInput const& t, 1894 native_handle_t** nh, 1895 void*& buffer, size_t& size, int*& fds, size_t& numFds) { 1896 if (size < getFlattenedSize(t)) { 1897 return NO_MEMORY; 1898 } 1899 1900 FlattenableUtils::write(buffer, size, t.timestamp); 1901 FlattenableUtils::write(buffer, size, static_cast<int>(t.isAutoTimestamp)); 1902 FlattenableUtils::write(buffer, size, 1903 static_cast<android_dataspace_t>(t.dataSpace)); 1904 FlattenableUtils::write(buffer, size, ::android::Rect( 1905 static_cast<int32_t>(t.crop.left), 1906 static_cast<int32_t>(t.crop.top), 1907 static_cast<int32_t>(t.crop.right), 1908 static_cast<int32_t>(t.crop.bottom))); 1909 FlattenableUtils::write(buffer, size, static_cast<int>(t.scalingMode)); 1910 FlattenableUtils::write(buffer, size, t.transform); 1911 FlattenableUtils::write(buffer, size, t.stickyTransform); 1912 FlattenableUtils::write(buffer, size, t.getFrameTimestamps); 1913 1914 *nh = t.fence.getNativeHandle() == nullptr ? 1915 nullptr : native_handle_clone(t.fence); 1916 status_t status = flattenFence(hidl_handle(*nh), buffer, size, fds, numFds); 1917 if (status != NO_ERROR) { 1918 return status; 1919 } 1920 status = flatten(t.surfaceDamage, buffer, size); 1921 if (status != NO_ERROR) { 1922 return status; 1923 } 1924 FlattenableUtils::write(buffer, size, decltype(HdrMetadata::validTypes)(0)); 1925 return NO_ERROR; 1926} 1927 1928/** 1929 * \brief Unflatten `HGraphicBufferProducer::QueueBufferInput`. 1930 * 1931 * \param[out] t The destination `HGraphicBufferProducer::QueueBufferInput`. 1932 * \param[out] nh The underlying native handle for `t->fence`. 1933 * \param[in,out] buffer The pointer to the flat non-fd buffer. 1934 * \param[in,out] size The size of the flat non-fd buffer. 1935 * \param[in,out] fds The pointer to the flat fd buffer. 1936 * \param[in,out] numFds The size of the flat fd buffer. 1937 * \return `NO_ERROR` on success; other value on failure. 1938 * 1939 * If the return value is `NO_ERROR` and `t->fence` contains a valid file 1940 * descriptor, \p nh will be a newly created native handle holding that file 1941 * descriptor. \p nh needs to be deleted with `native_handle_delete()` 1942 * afterwards. 1943 */ 1944inline status_t unflatten( 1945 HGraphicBufferProducer::QueueBufferInput* t, native_handle_t** nh, 1946 void const*& buffer, size_t& size, int const*& fds, size_t& numFds) { 1947 if (size < minFlattenedSize(*t)) { 1948 return NO_MEMORY; 1949 } 1950 1951 FlattenableUtils::read(buffer, size, t->timestamp); 1952 int lIsAutoTimestamp; 1953 FlattenableUtils::read(buffer, size, lIsAutoTimestamp); 1954 t->isAutoTimestamp = static_cast<int32_t>(lIsAutoTimestamp); 1955 android_dataspace_t lDataSpace; 1956 FlattenableUtils::read(buffer, size, lDataSpace); 1957 t->dataSpace = static_cast<Dataspace>(lDataSpace); 1958 Rect lCrop; 1959 FlattenableUtils::read(buffer, size, lCrop); 1960 t->crop = Rect{ 1961 static_cast<int32_t>(lCrop.left), 1962 static_cast<int32_t>(lCrop.top), 1963 static_cast<int32_t>(lCrop.right), 1964 static_cast<int32_t>(lCrop.bottom)}; 1965 int lScalingMode; 1966 FlattenableUtils::read(buffer, size, lScalingMode); 1967 t->scalingMode = static_cast<int32_t>(lScalingMode); 1968 FlattenableUtils::read(buffer, size, t->transform); 1969 FlattenableUtils::read(buffer, size, t->stickyTransform); 1970 FlattenableUtils::read(buffer, size, t->getFrameTimestamps); 1971 1972 status_t status = unflattenFence(&(t->fence), nh, 1973 buffer, size, fds, numFds); 1974 if (status != NO_ERROR) { 1975 return status; 1976 } 1977 // HdrMetadata ignored 1978 return unflatten(&(t->surfaceDamage), buffer, size); 1979} 1980 1981/** 1982 * \brief Wrap `BGraphicBufferProducer::QueueBufferInput` in 1983 * `HGraphicBufferProducer::QueueBufferInput`. 1984 * 1985 * \param[out] t The wrapper of type 1986 * `HGraphicBufferProducer::QueueBufferInput`. 1987 * \param[out] nh The underlying native handle for `t->fence`. 1988 * \param[in] l The source `BGraphicBufferProducer::QueueBufferInput`. 1989 * 1990 * If the return value is `true` and `t->fence` contains a valid file 1991 * descriptor, \p nh will be a newly created native handle holding that file 1992 * descriptor. \p nh needs to be deleted with `native_handle_delete()` 1993 * afterwards. 1994 */ 1995inline bool wrapAs( 1996 HGraphicBufferProducer::QueueBufferInput* t, 1997 native_handle_t** nh, 1998 BGraphicBufferProducer::QueueBufferInput const& l) { 1999 2000 size_t const baseSize = l.getFlattenedSize(); 2001 std::unique_ptr<uint8_t[]> baseBuffer( 2002 new (std::nothrow) uint8_t[baseSize]); 2003 if (!baseBuffer) { 2004 return false; 2005 } 2006 2007 size_t const baseNumFds = l.getFdCount(); 2008 std::unique_ptr<int[]> baseFds( 2009 new (std::nothrow) int[baseNumFds]); 2010 if (!baseFds) { 2011 return false; 2012 } 2013 2014 void* buffer = static_cast<void*>(baseBuffer.get()); 2015 size_t size = baseSize; 2016 int* fds = baseFds.get(); 2017 size_t numFds = baseNumFds; 2018 if (l.flatten(buffer, size, fds, numFds) != NO_ERROR) { 2019 return false; 2020 } 2021 2022 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 2023 size = baseSize; 2024 int const* constFds = static_cast<int const*>(baseFds.get()); 2025 numFds = baseNumFds; 2026 if (unflatten(t, nh, constBuffer, size, constFds, numFds) != NO_ERROR) { 2027 return false; 2028 } 2029 2030 return true; 2031} 2032 2033/** 2034 * \brief Convert `HGraphicBufferProducer::QueueBufferInput` to 2035 * `BGraphicBufferProducer::QueueBufferInput`. 2036 * 2037 * \param[out] l The destination `BGraphicBufferProducer::QueueBufferInput`. 2038 * \param[in] t The source `HGraphicBufferProducer::QueueBufferInput`. 2039 * 2040 * If `t.fence` has a valid file descriptor, it will be duplicated. 2041 */ 2042inline bool convertTo( 2043 BGraphicBufferProducer::QueueBufferInput* l, 2044 HGraphicBufferProducer::QueueBufferInput const& t) { 2045 2046 size_t const baseSize = getFlattenedSize(t); 2047 std::unique_ptr<uint8_t[]> baseBuffer( 2048 new (std::nothrow) uint8_t[baseSize]); 2049 if (!baseBuffer) { 2050 return false; 2051 } 2052 2053 size_t const baseNumFds = getFdCount(t); 2054 std::unique_ptr<int[]> baseFds( 2055 new (std::nothrow) int[baseNumFds]); 2056 if (!baseFds) { 2057 return false; 2058 } 2059 2060 void* buffer = static_cast<void*>(baseBuffer.get()); 2061 size_t size = baseSize; 2062 int* fds = baseFds.get(); 2063 size_t numFds = baseNumFds; 2064 native_handle_t* nh; 2065 if (flatten(t, &nh, buffer, size, fds, numFds) != NO_ERROR) { 2066 return false; 2067 } 2068 2069 void const* constBuffer = static_cast<void const*>(baseBuffer.get()); 2070 size = baseSize; 2071 int const* constFds = static_cast<int const*>(baseFds.get()); 2072 numFds = baseNumFds; 2073 if (l->unflatten(constBuffer, size, constFds, numFds) != NO_ERROR) { 2074 if (nh != nullptr) { 2075 native_handle_close(nh); 2076 native_handle_delete(nh); 2077 } 2078 return false; 2079 } 2080 2081 native_handle_delete(nh); 2082 return true; 2083} 2084 2085// Ref: frameworks/native/libs/gui/BGraphicBufferProducer.cpp: 2086// BGraphicBufferProducer::QueueBufferOutput 2087 2088/** 2089 * \brief Wrap `BGraphicBufferProducer::QueueBufferOutput` in 2090 * `HGraphicBufferProducer::QueueBufferOutput`. 2091 * 2092 * \param[out] t The wrapper of type 2093 * `HGraphicBufferProducer::QueueBufferOutput`. 2094 * \param[out] nh The array of array of native handles that are referred to by 2095 * members of \p t. 2096 * \param[in] l The source `BGraphicBufferProducer::QueueBufferOutput`. 2097 * 2098 * On success, each member of \p nh will be either `nullptr` or a newly created 2099 * native handle. All the non-`nullptr` elements must be deleted individually 2100 * with `native_handle_delete()`. 2101 */ 2102// wrap: BGraphicBufferProducer::QueueBufferOutput -> 2103// HGraphicBufferProducer::QueueBufferOutput 2104inline bool wrapAs(HGraphicBufferProducer::QueueBufferOutput* t, 2105 std::vector<std::vector<native_handle_t*> >* nh, 2106 BGraphicBufferProducer::QueueBufferOutput const& l) { 2107 if (!wrapAs(&(t->frameTimestamps), nh, l.frameTimestamps)) { 2108 return false; 2109 } 2110 t->width = l.width; 2111 t->height = l.height; 2112 t->transformHint = l.transformHint; 2113 t->numPendingBuffers = l.numPendingBuffers; 2114 t->nextFrameNumber = l.nextFrameNumber; 2115 t->bufferReplaced = l.bufferReplaced; 2116 return true; 2117} 2118 2119/** 2120 * \brief Convert `HGraphicBufferProducer::QueueBufferOutput` to 2121 * `BGraphicBufferProducer::QueueBufferOutput`. 2122 * 2123 * \param[out] l The destination `BGraphicBufferProducer::QueueBufferOutput`. 2124 * \param[in] t The source `HGraphicBufferProducer::QueueBufferOutput`. 2125 * 2126 * This function will duplicate all file descriptors contained in \p t. 2127 */ 2128// convert: HGraphicBufferProducer::QueueBufferOutput -> 2129// BGraphicBufferProducer::QueueBufferOutput 2130inline bool convertTo( 2131 BGraphicBufferProducer::QueueBufferOutput* l, 2132 HGraphicBufferProducer::QueueBufferOutput const& t) { 2133 if (!convertTo(&(l->frameTimestamps), t.frameTimestamps)) { 2134 return false; 2135 } 2136 l->width = t.width; 2137 l->height = t.height; 2138 l->transformHint = t.transformHint; 2139 l->numPendingBuffers = t.numPendingBuffers; 2140 l->nextFrameNumber = t.nextFrameNumber; 2141 l->bufferReplaced = t.bufferReplaced; 2142 return true; 2143} 2144 2145/** 2146 * \brief Convert `BGraphicBufferProducer::DisconnectMode` to 2147 * `HGraphicBufferProducer::DisconnectMode`. 2148 * 2149 * \param[in] l The source `BGraphicBufferProducer::DisconnectMode`. 2150 * \return The corresponding `HGraphicBufferProducer::DisconnectMode`. 2151 */ 2152inline HGraphicBufferProducer::DisconnectMode toOmxDisconnectMode( 2153 BGraphicBufferProducer::DisconnectMode l) { 2154 switch (l) { 2155 case BGraphicBufferProducer::DisconnectMode::Api: 2156 return HGraphicBufferProducer::DisconnectMode::API; 2157 case BGraphicBufferProducer::DisconnectMode::AllLocal: 2158 return HGraphicBufferProducer::DisconnectMode::ALL_LOCAL; 2159 } 2160 return HGraphicBufferProducer::DisconnectMode::API; 2161} 2162 2163/** 2164 * \brief Convert `HGraphicBufferProducer::DisconnectMode` to 2165 * `BGraphicBufferProducer::DisconnectMode`. 2166 * 2167 * \param[in] l The source `HGraphicBufferProducer::DisconnectMode`. 2168 * \return The corresponding `BGraphicBufferProducer::DisconnectMode`. 2169 */ 2170inline BGraphicBufferProducer::DisconnectMode toGuiDisconnectMode( 2171 HGraphicBufferProducer::DisconnectMode t) { 2172 switch (t) { 2173 case HGraphicBufferProducer::DisconnectMode::API: 2174 return BGraphicBufferProducer::DisconnectMode::Api; 2175 case HGraphicBufferProducer::DisconnectMode::ALL_LOCAL: 2176 return BGraphicBufferProducer::DisconnectMode::AllLocal; 2177 } 2178 return BGraphicBufferProducer::DisconnectMode::Api; 2179} 2180 2181} // namespace implementation 2182} // namespace V1_0 2183} // namespace omx 2184} // namespace media 2185} // namespace hardware 2186} // namespace android 2187 2188#endif // ANDROID_HARDWARE_MEDIA_OMX_V1_0__CONVERSION_H 2189