1 /* 2 * Copyright (C) 2007 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 "GraphicBuffer" 18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 19 20 #include <ui/GraphicBuffer.h> 21 22 #include <cutils/atomic.h> 23 24 #include <grallocusage/GrallocUsageConversion.h> 25 26 #ifndef LIBUI_IN_VNDK 27 #include <ui/BufferHubBuffer.h> 28 #endif // LIBUI_IN_VNDK 29 30 #include <ui/Gralloc2.h> 31 #include <ui/GraphicBufferAllocator.h> 32 #include <ui/GraphicBufferMapper.h> 33 #include <utils/Trace.h> 34 35 namespace android { 36 37 // =========================================================================== 38 // Buffer and implementation of ANativeWindowBuffer 39 // =========================================================================== 40 41 static uint64_t getUniqueId() { 42 static volatile int32_t nextId = 0; 43 uint64_t id = static_cast<uint64_t>(getpid()) << 32; 44 id |= static_cast<uint32_t>(android_atomic_inc(&nextId)); 45 return id; 46 } 47 48 sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { 49 return static_cast<GraphicBuffer *>(anwb); 50 } 51 52 GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) { 53 return reinterpret_cast<GraphicBuffer*>(buffer); 54 } 55 56 GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) { 57 return reinterpret_cast<GraphicBuffer const*>(buffer); 58 } 59 60 AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() { 61 return reinterpret_cast<AHardwareBuffer*>(this); 62 } 63 64 AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const { 65 return reinterpret_cast<AHardwareBuffer const*>(this); 66 } 67 68 GraphicBuffer::GraphicBuffer() 69 : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), 70 mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) 71 { 72 width = 73 height = 74 stride = 75 format = 76 usage_deprecated = 0; 77 usage = 0; 78 layerCount = 0; 79 handle = nullptr; 80 } 81 82 // deprecated 83 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, 84 PixelFormat inFormat, uint32_t inUsage, std::string requestorName) 85 : GraphicBuffer(inWidth, inHeight, inFormat, 1, static_cast<uint64_t>(inUsage), requestorName) 86 { 87 } 88 89 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 90 uint32_t inLayerCount, uint64_t inUsage, std::string requestorName) 91 : GraphicBuffer() { 92 mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, 93 std::move(requestorName)); 94 } 95 96 // deprecated 97 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, 98 PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage, 99 uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) 100 : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE, 101 inWidth, inHeight, inFormat, inLayerCount, static_cast<uint64_t>(inUsage), 102 inStride) 103 { 104 } 105 106 GraphicBuffer::GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod method, 107 uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 108 uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) 109 : GraphicBuffer() { 110 mInitCheck = initWithHandle(inHandle, method, inWidth, inHeight, inFormat, inLayerCount, 111 inUsage, inStride); 112 } 113 114 #ifndef LIBUI_IN_VNDK 115 GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() { 116 if (buffer == nullptr) { 117 mInitCheck = BAD_VALUE; 118 return; 119 } 120 121 mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, 122 buffer->desc().width, buffer->desc().height, 123 static_cast<PixelFormat>(buffer->desc().format), 124 buffer->desc().layers, buffer->desc().usage, buffer->desc().stride); 125 mBufferId = buffer->id(); 126 mBufferHubBuffer = std::move(buffer); 127 } 128 #endif // LIBUI_IN_VNDK 129 130 GraphicBuffer::~GraphicBuffer() 131 { 132 ATRACE_CALL(); 133 if (handle) { 134 free_handle(); 135 } 136 for (auto& [callback, context] : mDeathCallbacks) { 137 callback(context, mId); 138 } 139 } 140 141 void GraphicBuffer::free_handle() 142 { 143 if (mOwner == ownHandle) { 144 mBufferMapper.freeBuffer(handle); 145 } else if (mOwner == ownData) { 146 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 147 allocator.free(handle); 148 } 149 handle = nullptr; 150 } 151 152 status_t GraphicBuffer::initCheck() const { 153 return static_cast<status_t>(mInitCheck); 154 } 155 156 void GraphicBuffer::dumpAllocationsToSystemLog() 157 { 158 GraphicBufferAllocator::dumpToSystemLog(); 159 } 160 161 ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const 162 { 163 return static_cast<ANativeWindowBuffer*>( 164 const_cast<GraphicBuffer*>(this)); 165 } 166 167 status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, 168 PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage) 169 { 170 if (mOwner != ownData) 171 return INVALID_OPERATION; 172 173 if (handle && 174 static_cast<int>(inWidth) == width && 175 static_cast<int>(inHeight) == height && 176 inFormat == format && 177 inLayerCount == layerCount && 178 inUsage == usage) 179 return NO_ERROR; 180 181 if (handle) { 182 GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); 183 allocator.free(handle); 184 handle = nullptr; 185 } 186 return initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, "[Reallocation]"); 187 } 188 189 bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight, 190 PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage) 191 { 192 if (static_cast<int>(inWidth) != width) return true; 193 if (static_cast<int>(inHeight) != height) return true; 194 if (inFormat != format) return true; 195 if (inLayerCount != layerCount) return true; 196 if ((usage & inUsage) != inUsage) return true; 197 if ((usage & USAGE_PROTECTED) != (inUsage & USAGE_PROTECTED)) return true; 198 return false; 199 } 200 201 status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight, 202 PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage, 203 std::string requestorName) 204 { 205 GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); 206 uint32_t outStride = 0; 207 status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount, 208 inUsage, &handle, &outStride, mId, 209 std::move(requestorName)); 210 if (err == NO_ERROR) { 211 mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); 212 213 width = static_cast<int>(inWidth); 214 height = static_cast<int>(inHeight); 215 format = inFormat; 216 layerCount = inLayerCount; 217 usage = inUsage; 218 usage_deprecated = int(usage); 219 stride = static_cast<int>(outStride); 220 } 221 return err; 222 } 223 224 status_t GraphicBuffer::initWithHandle(const native_handle_t* inHandle, HandleWrapMethod method, 225 uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 226 uint32_t inLayerCount, uint64_t inUsage, uint32_t inStride) { 227 ANativeWindowBuffer::width = static_cast<int>(inWidth); 228 ANativeWindowBuffer::height = static_cast<int>(inHeight); 229 ANativeWindowBuffer::stride = static_cast<int>(inStride); 230 ANativeWindowBuffer::format = inFormat; 231 ANativeWindowBuffer::usage = inUsage; 232 ANativeWindowBuffer::usage_deprecated = int(inUsage); 233 234 ANativeWindowBuffer::layerCount = inLayerCount; 235 236 mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle; 237 238 if (method == TAKE_UNREGISTERED_HANDLE || method == CLONE_HANDLE) { 239 buffer_handle_t importedHandle; 240 status_t err = mBufferMapper.importBuffer(inHandle, inWidth, inHeight, inLayerCount, 241 inFormat, inUsage, inStride, &importedHandle); 242 if (err != NO_ERROR) { 243 initWithHandle(nullptr, WRAP_HANDLE, 0, 0, 0, 0, 0, 0); 244 245 return err; 246 } 247 248 if (method == TAKE_UNREGISTERED_HANDLE) { 249 native_handle_close(inHandle); 250 native_handle_delete(const_cast<native_handle_t*>(inHandle)); 251 } 252 253 inHandle = importedHandle; 254 mBufferMapper.getTransportSize(inHandle, &mTransportNumFds, &mTransportNumInts); 255 } 256 257 ANativeWindowBuffer::handle = inHandle; 258 259 return NO_ERROR; 260 } 261 262 status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr, int32_t* outBytesPerPixel, 263 int32_t* outBytesPerStride) { 264 const Rect lockBounds(width, height); 265 status_t res = lock(inUsage, lockBounds, vaddr, outBytesPerPixel, outBytesPerStride); 266 return res; 267 } 268 269 status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr, 270 int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 271 if (rect.left < 0 || rect.right > width || 272 rect.top < 0 || rect.bottom > height) { 273 ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 274 rect.left, rect.top, rect.right, rect.bottom, 275 width, height); 276 return BAD_VALUE; 277 } 278 279 status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr, outBytesPerPixel, 280 outBytesPerStride); 281 282 return res; 283 } 284 285 status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, android_ycbcr* ycbcr) 286 { 287 const Rect lockBounds(width, height); 288 status_t res = lockYCbCr(inUsage, lockBounds, ycbcr); 289 return res; 290 } 291 292 status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, const Rect& rect, 293 android_ycbcr* ycbcr) 294 { 295 if (rect.left < 0 || rect.right > width || 296 rect.top < 0 || rect.bottom > height) { 297 ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 298 rect.left, rect.top, rect.right, rect.bottom, 299 width, height); 300 return BAD_VALUE; 301 } 302 status_t res = getBufferMapper().lockYCbCr(handle, inUsage, rect, ycbcr); 303 return res; 304 } 305 306 status_t GraphicBuffer::unlock() 307 { 308 status_t res = getBufferMapper().unlock(handle); 309 return res; 310 } 311 312 status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd, 313 int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 314 const Rect lockBounds(width, height); 315 status_t res = 316 lockAsync(inUsage, lockBounds, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); 317 return res; 318 } 319 320 status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect, void** vaddr, int fenceFd, 321 int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 322 return lockAsync(inUsage, inUsage, rect, vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); 323 } 324 325 status_t GraphicBuffer::lockAsync(uint64_t inProducerUsage, uint64_t inConsumerUsage, 326 const Rect& rect, void** vaddr, int fenceFd, 327 int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { 328 if (rect.left < 0 || rect.right > width || 329 rect.top < 0 || rect.bottom > height) { 330 ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 331 rect.left, rect.top, rect.right, rect.bottom, 332 width, height); 333 return BAD_VALUE; 334 } 335 336 status_t res = getBufferMapper().lockAsync(handle, inProducerUsage, inConsumerUsage, rect, 337 vaddr, fenceFd, outBytesPerPixel, outBytesPerStride); 338 339 return res; 340 } 341 342 status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, android_ycbcr* ycbcr, 343 int fenceFd) 344 { 345 const Rect lockBounds(width, height); 346 status_t res = lockAsyncYCbCr(inUsage, lockBounds, ycbcr, fenceFd); 347 return res; 348 } 349 350 status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, const Rect& rect, 351 android_ycbcr* ycbcr, int fenceFd) 352 { 353 if (rect.left < 0 || rect.right > width || 354 rect.top < 0 || rect.bottom > height) { 355 ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", 356 rect.left, rect.top, rect.right, rect.bottom, 357 width, height); 358 return BAD_VALUE; 359 } 360 status_t res = getBufferMapper().lockAsyncYCbCr(handle, inUsage, rect, ycbcr, fenceFd); 361 return res; 362 } 363 364 status_t GraphicBuffer::unlockAsync(int *fenceFd) 365 { 366 status_t res = getBufferMapper().unlockAsync(handle, fenceFd); 367 return res; 368 } 369 370 status_t GraphicBuffer::isSupported(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, 371 uint32_t inLayerCount, uint64_t inUsage, 372 bool* outSupported) const { 373 return mBufferMapper.isSupported(inWidth, inHeight, inFormat, inLayerCount, inUsage, 374 outSupported); 375 } 376 377 size_t GraphicBuffer::getFlattenedSize() const { 378 #ifndef LIBUI_IN_VNDK 379 if (mBufferHubBuffer != nullptr) { 380 return 48; 381 } 382 #endif 383 return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int); 384 } 385 386 size_t GraphicBuffer::getFdCount() const { 387 #ifndef LIBUI_IN_VNDK 388 if (mBufferHubBuffer != nullptr) { 389 return 0; 390 } 391 #endif 392 return static_cast<size_t>(handle ? mTransportNumFds : 0); 393 } 394 395 status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { 396 #ifndef LIBUI_IN_VNDK 397 if (mBufferHubBuffer != nullptr) { 398 return flattenBufferHubBuffer(buffer, size); 399 } 400 #endif 401 size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); 402 if (size < sizeNeeded) return NO_MEMORY; 403 404 size_t fdCountNeeded = GraphicBuffer::getFdCount(); 405 if (count < fdCountNeeded) return NO_MEMORY; 406 407 int32_t* buf = static_cast<int32_t*>(buffer); 408 buf[0] = 'GB01'; 409 buf[1] = width; 410 buf[2] = height; 411 buf[3] = stride; 412 buf[4] = format; 413 buf[5] = static_cast<int32_t>(layerCount); 414 buf[6] = int(usage); // low 32-bits 415 buf[7] = static_cast<int32_t>(mId >> 32); 416 buf[8] = static_cast<int32_t>(mId & 0xFFFFFFFFull); 417 buf[9] = static_cast<int32_t>(mGenerationNumber); 418 buf[10] = 0; 419 buf[11] = 0; 420 buf[12] = int(usage >> 32); // high 32-bits 421 422 if (handle) { 423 buf[10] = int32_t(mTransportNumFds); 424 buf[11] = int32_t(mTransportNumInts); 425 memcpy(fds, handle->data, static_cast<size_t>(mTransportNumFds) * sizeof(int)); 426 memcpy(buf + 13, handle->data + handle->numFds, 427 static_cast<size_t>(mTransportNumInts) * sizeof(int)); 428 } 429 430 buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded); 431 size -= sizeNeeded; 432 if (handle) { 433 fds += mTransportNumFds; 434 count -= static_cast<size_t>(mTransportNumFds); 435 } 436 return NO_ERROR; 437 } 438 439 status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& fds, 440 size_t& count) { 441 // Check if size is not smaller than buf[0] is supposed to take. 442 if (size < sizeof(int)) { 443 return NO_MEMORY; 444 } 445 446 int const* buf = static_cast<int const*>(buffer); 447 448 // NOTE: it turns out that some media code generates a flattened GraphicBuffer manually!!!!! 449 // see H2BGraphicBufferProducer.cpp 450 uint32_t flattenWordCount = 0; 451 if (buf[0] == 'GB01') { 452 // new version with 64-bits usage bits 453 flattenWordCount = 13; 454 } else if (buf[0] == 'GBFR') { 455 // old version, when usage bits were 32-bits 456 flattenWordCount = 12; 457 } else if (buf[0] == 'BHBB') { // BufferHub backed buffer. 458 #ifndef LIBUI_IN_VNDK 459 return unflattenBufferHubBuffer(buffer, size); 460 #else 461 return BAD_TYPE; 462 #endif 463 } else { 464 return BAD_TYPE; 465 } 466 467 if (size < 12 * sizeof(int)) { 468 android_errorWriteLog(0x534e4554, "114223584"); 469 return NO_MEMORY; 470 } 471 472 const size_t numFds = static_cast<size_t>(buf[10]); 473 const size_t numInts = static_cast<size_t>(buf[11]); 474 475 // Limit the maxNumber to be relatively small. The number of fds or ints 476 // should not come close to this number, and the number itself was simply 477 // chosen to be high enough to not cause issues and low enough to prevent 478 // overflow problems. 479 const size_t maxNumber = 4096; 480 if (numFds >= maxNumber || numInts >= (maxNumber - flattenWordCount)) { 481 width = height = stride = format = usage_deprecated = 0; 482 layerCount = 0; 483 usage = 0; 484 handle = nullptr; 485 ALOGE("unflatten: numFds or numInts is too large: %zd, %zd", numFds, numInts); 486 return BAD_VALUE; 487 } 488 489 const size_t sizeNeeded = (flattenWordCount + numInts) * sizeof(int); 490 if (size < sizeNeeded) return NO_MEMORY; 491 492 size_t fdCountNeeded = numFds; 493 if (count < fdCountNeeded) return NO_MEMORY; 494 495 if (handle) { 496 // free previous handle if any 497 free_handle(); 498 } 499 500 if (numFds || numInts) { 501 width = buf[1]; 502 height = buf[2]; 503 stride = buf[3]; 504 format = buf[4]; 505 layerCount = static_cast<uintptr_t>(buf[5]); 506 usage_deprecated = buf[6]; 507 if (flattenWordCount == 13) { 508 usage = (uint64_t(buf[12]) << 32) | uint32_t(buf[6]); 509 } else { 510 usage = uint64_t(usage_deprecated); 511 } 512 native_handle* h = 513 native_handle_create(static_cast<int>(numFds), static_cast<int>(numInts)); 514 if (!h) { 515 width = height = stride = format = usage_deprecated = 0; 516 layerCount = 0; 517 usage = 0; 518 handle = nullptr; 519 ALOGE("unflatten: native_handle_create failed"); 520 return NO_MEMORY; 521 } 522 memcpy(h->data, fds, numFds * sizeof(int)); 523 memcpy(h->data + numFds, buf + flattenWordCount, numInts * sizeof(int)); 524 handle = h; 525 } else { 526 width = height = stride = format = usage_deprecated = 0; 527 layerCount = 0; 528 usage = 0; 529 handle = nullptr; 530 } 531 532 mId = static_cast<uint64_t>(buf[7]) << 32; 533 mId |= static_cast<uint32_t>(buf[8]); 534 535 mGenerationNumber = static_cast<uint32_t>(buf[9]); 536 537 mOwner = ownHandle; 538 539 if (handle != nullptr) { 540 buffer_handle_t importedHandle; 541 status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height), 542 uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle); 543 if (err != NO_ERROR) { 544 width = height = stride = format = usage_deprecated = 0; 545 layerCount = 0; 546 usage = 0; 547 handle = nullptr; 548 ALOGE("unflatten: registerBuffer failed: %s (%d)", strerror(-err), err); 549 return err; 550 } 551 552 native_handle_close(handle); 553 native_handle_delete(const_cast<native_handle_t*>(handle)); 554 handle = importedHandle; 555 mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); 556 } 557 558 buffer = static_cast<void const*>(static_cast<uint8_t const*>(buffer) + sizeNeeded); 559 size -= sizeNeeded; 560 fds += numFds; 561 count -= numFds; 562 return NO_ERROR; 563 } 564 565 void GraphicBuffer::addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context) { 566 mDeathCallbacks.emplace_back(deathCallback, context); 567 } 568 569 #ifndef LIBUI_IN_VNDK 570 status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size) const { 571 sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate(); 572 if (tokenHandle == nullptr || tokenHandle->handle() == nullptr || 573 tokenHandle->handle()->numFds != 0) { 574 return BAD_VALUE; 575 } 576 577 // Size needed for one label, one number of ints inside the token, one generation number and 578 // the token itself. 579 int numIntsInToken = tokenHandle->handle()->numInts; 580 const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); 581 if (size < sizeNeeded) { 582 ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, 583 static_cast<int>(sizeNeeded), static_cast<int>(size)); 584 return NO_MEMORY; 585 } 586 size -= sizeNeeded; 587 588 int* buf = static_cast<int*>(buffer); 589 buf[0] = 'BHBB'; 590 buf[1] = numIntsInToken; 591 memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int)); 592 buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber); 593 594 return NO_ERROR; 595 } 596 597 status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size) { 598 const int* buf = static_cast<const int*>(buffer); 599 int numIntsInToken = buf[1]; 600 // Size needed for one label, one number of ints inside the token, one generation number and 601 // the token itself. 602 const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int); 603 if (size < sizeNeeded) { 604 ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__, 605 static_cast<int>(sizeNeeded), static_cast<int>(size)); 606 return NO_MEMORY; 607 } 608 size -= sizeNeeded; 609 native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken); 610 memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int)); 611 sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true); 612 std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle); 613 if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) { 614 return BAD_VALUE; 615 } 616 // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object. 617 if (handle) { 618 free_handle(); 619 } 620 mId = 0; 621 mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]); 622 mInitCheck = 623 initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE, 624 bufferHubBuffer->desc().width, bufferHubBuffer->desc().height, 625 static_cast<PixelFormat>(bufferHubBuffer->desc().format), 626 bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage, 627 bufferHubBuffer->desc().stride); 628 mBufferId = bufferHubBuffer->id(); 629 mBufferHubBuffer.reset(std::move(bufferHubBuffer.get())); 630 631 return NO_ERROR; 632 } 633 634 bool GraphicBuffer::isBufferHubBuffer() const { 635 return mBufferHubBuffer != nullptr; 636 } 637 #endif // LIBUI_IN_VNDK 638 639 // --------------------------------------------------------------------------- 640 641 }; // namespace android 642