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 #undef LOG_TAG 18 #define LOG_TAG "Gralloc1On0Adapter" 19 //#define LOG_NDEBUG 0 20 21 #include "Gralloc1On0Adapter.h" 22 #include "gralloc1-adapter.h" 23 24 #include <grallocusage/GrallocUsageConversion.h> 25 26 #include <hardware/gralloc.h> 27 28 #include <log/log.h> 29 #include <sync/sync.h> 30 31 #include <inttypes.h> 32 #include <unistd.h> 33 34 template <typename PFN, typename T> 35 static gralloc1_function_pointer_t asFP(T function) 36 { 37 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer"); 38 return reinterpret_cast<gralloc1_function_pointer_t>(function); 39 } 40 41 namespace android { 42 namespace hardware { 43 44 Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module) 45 : gralloc1_device_t(), 46 mModule(reinterpret_cast<const gralloc_module_t*>(module)), 47 mDevice(nullptr) 48 { 49 ALOGV("Constructing"); 50 51 int minor = 0; 52 mModule->perform(mModule, 53 GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR, 54 &minor); 55 mMinorVersion = minor; 56 57 common.tag = HARDWARE_DEVICE_TAG, 58 common.version = HARDWARE_DEVICE_API_VERSION(0, 0), 59 common.module = const_cast<struct hw_module_t*>(module), 60 common.close = closeHook, 61 62 getCapabilities = getCapabilitiesHook; 63 getFunction = getFunctionHook; 64 int error = ::gralloc_open(&(mModule->common), &mDevice); 65 if (error) { 66 ALOGE("Failed to open gralloc0 module: %d", error); 67 } 68 ALOGV("Opened gralloc0 device %p", mDevice); 69 } 70 71 Gralloc1On0Adapter::~Gralloc1On0Adapter() 72 { 73 ALOGV("Destructing"); 74 if (mDevice) { 75 ALOGV("Closing gralloc0 device %p", mDevice); 76 ::gralloc_close(mDevice); 77 } 78 } 79 80 void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount, 81 int32_t* /*outCapabilities*/) { 82 *outCount = 0; 83 } 84 85 gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction( 86 int32_t intDescriptor) 87 { 88 constexpr auto lastDescriptor = 89 static_cast<int32_t>(GRALLOC1_LAST_FUNCTION); 90 if (intDescriptor < 0 || intDescriptor > lastDescriptor) { 91 ALOGE("Invalid function descriptor"); 92 return nullptr; 93 } 94 95 auto descriptor = 96 static_cast<gralloc1_function_descriptor_t>(intDescriptor); 97 switch (descriptor) { 98 case GRALLOC1_FUNCTION_DUMP: 99 return asFP<GRALLOC1_PFN_DUMP>(dumpHook); 100 case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR: 101 return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook); 102 case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR: 103 return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook); 104 case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE: 105 return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook); 106 case GRALLOC1_FUNCTION_SET_DIMENSIONS: 107 return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook); 108 case GRALLOC1_FUNCTION_SET_FORMAT: 109 return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook); 110 case GRALLOC1_FUNCTION_SET_LAYER_COUNT: 111 return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook); 112 case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE: 113 return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook); 114 case GRALLOC1_FUNCTION_GET_BACKING_STORE: 115 return asFP<GRALLOC1_PFN_GET_BACKING_STORE>( 116 bufferHook<decltype(&Buffer::getBackingStore), 117 &Buffer::getBackingStore, gralloc1_backing_store_t*>); 118 case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE: 119 return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook); 120 case GRALLOC1_FUNCTION_GET_DIMENSIONS: 121 return asFP<GRALLOC1_PFN_GET_DIMENSIONS>( 122 bufferHook<decltype(&Buffer::getDimensions), 123 &Buffer::getDimensions, uint32_t*, uint32_t*>); 124 case GRALLOC1_FUNCTION_GET_FORMAT: 125 return asFP<GRALLOC1_PFN_GET_FORMAT>( 126 bufferHook<decltype(&Buffer::getFormat), 127 &Buffer::getFormat, int32_t*>); 128 case GRALLOC1_FUNCTION_GET_LAYER_COUNT: 129 return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>( 130 bufferHook<decltype(&Buffer::getLayerCount), 131 &Buffer::getLayerCount, uint32_t*>); 132 case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE: 133 return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook); 134 case GRALLOC1_FUNCTION_GET_STRIDE: 135 return asFP<GRALLOC1_PFN_GET_STRIDE>( 136 bufferHook<decltype(&Buffer::getStride), 137 &Buffer::getStride, uint32_t*>); 138 case GRALLOC1_FUNCTION_ALLOCATE: 139 if (mDevice != nullptr) { 140 return asFP<GRALLOC1_PFN_ALLOCATE>(allocateHook); 141 } else { 142 return nullptr; 143 } 144 case GRALLOC1_FUNCTION_RETAIN: 145 return asFP<GRALLOC1_PFN_RETAIN>(retainHook); 146 case GRALLOC1_FUNCTION_RELEASE: 147 return asFP<GRALLOC1_PFN_RELEASE>(releaseHook); 148 case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES: 149 return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>( 150 bufferHook<decltype(&Buffer::getNumFlexPlanes), 151 &Buffer::getNumFlexPlanes, uint32_t*>); 152 case GRALLOC1_FUNCTION_LOCK: 153 return asFP<GRALLOC1_PFN_LOCK>( 154 lockHook<void*, &Gralloc1On0Adapter::lock>); 155 case GRALLOC1_FUNCTION_LOCK_FLEX: 156 return asFP<GRALLOC1_PFN_LOCK_FLEX>( 157 lockHook<struct android_flex_layout, 158 &Gralloc1On0Adapter::lockFlex>); 159 case GRALLOC1_FUNCTION_UNLOCK: 160 return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook); 161 case GRALLOC1_FUNCTION_INVALID: 162 ALOGE("Invalid function descriptor"); 163 return nullptr; 164 case GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE: 165 case GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE: 166 case GRALLOC1_FUNCTION_IMPORT_BUFFER: 167 ALOGW("Not supported by gralloc 0"); 168 return nullptr; 169 } 170 171 ALOGE("Unknown function descriptor: %d", intDescriptor); 172 return nullptr; 173 } 174 175 void Gralloc1On0Adapter::dump(uint32_t* outSize, char* outBuffer) 176 { 177 ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer); 178 179 if (!mDevice->dump) { 180 // dump is optional on gralloc0 implementations 181 *outSize = 0; 182 return; 183 } 184 185 if (!outBuffer) { 186 constexpr int32_t BUFFER_LENGTH = 4096; 187 char buffer[BUFFER_LENGTH] = {}; 188 mDevice->dump(mDevice, buffer, BUFFER_LENGTH); 189 buffer[BUFFER_LENGTH - 1] = 0; // Ensure the buffer is null-terminated 190 size_t actualLength = std::strlen(buffer); 191 mCachedDump.resize(actualLength); 192 std::copy_n(buffer, actualLength, mCachedDump.begin()); 193 *outSize = static_cast<uint32_t>(actualLength); 194 } else { 195 *outSize = std::min(*outSize, 196 static_cast<uint32_t>(mCachedDump.size())); 197 outBuffer = std::copy_n(mCachedDump.cbegin(), *outSize, outBuffer); 198 } 199 } 200 201 gralloc1_error_t Gralloc1On0Adapter::createDescriptor( 202 gralloc1_buffer_descriptor_t* outDescriptor) 203 { 204 auto descriptorId = sNextBufferDescriptorId++; 205 std::lock_guard<std::mutex> lock(mDescriptorMutex); 206 mDescriptors.emplace(descriptorId, std::make_shared<Descriptor>()); 207 208 ALOGV("Created descriptor %" PRIu64, descriptorId); 209 210 *outDescriptor = descriptorId; 211 return GRALLOC1_ERROR_NONE; 212 } 213 214 gralloc1_error_t Gralloc1On0Adapter::destroyDescriptor( 215 gralloc1_buffer_descriptor_t descriptor) 216 { 217 ALOGV("Destroying descriptor %" PRIu64, descriptor); 218 219 std::lock_guard<std::mutex> lock(mDescriptorMutex); 220 if (mDescriptors.count(descriptor) == 0) { 221 return GRALLOC1_ERROR_BAD_DESCRIPTOR; 222 } 223 224 mDescriptors.erase(descriptor); 225 return GRALLOC1_ERROR_NONE; 226 } 227 228 Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle, 229 gralloc1_backing_store_t store, const Descriptor& descriptor, 230 uint32_t stride, uint32_t numFlexPlanes, bool wasAllocated) 231 : mHandle(handle), 232 mReferenceCount(1), 233 mStore(store), 234 mDescriptor(descriptor), 235 mStride(stride), 236 mNumFlexPlanes(numFlexPlanes), 237 mWasAllocated(wasAllocated) {} 238 239 gralloc1_error_t Gralloc1On0Adapter::allocate( 240 gralloc1_buffer_descriptor_t id, 241 const std::shared_ptr<Descriptor>& descriptor, 242 buffer_handle_t* outBufferHandle) 243 { 244 ALOGV("allocate(%" PRIu64 ")", id); 245 246 // If this function is being called, it's because we handed out its function 247 // pointer, which only occurs when mDevice has been loaded successfully and 248 // we are permitted to allocate 249 250 int usage = android_convertGralloc1To0Usage( 251 descriptor->producerUsage, descriptor->consumerUsage); 252 buffer_handle_t handle = nullptr; 253 int stride = 0; 254 ALOGV("Calling alloc(%p, %u, %u, %i, %u)", mDevice, descriptor->width, 255 descriptor->height, descriptor->format, usage); 256 auto error = mDevice->alloc(mDevice, 257 static_cast<int>(descriptor->width), 258 static_cast<int>(descriptor->height), descriptor->format, 259 usage, &handle, &stride); 260 if (error != 0) { 261 ALOGE("gralloc0 allocation failed: %d (%s)", error, 262 strerror(-error)); 263 return GRALLOC1_ERROR_NO_RESOURCES; 264 } 265 266 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_SET_USAGES, 267 handle, 268 static_cast<int>(descriptor->producerUsage), 269 static_cast<int>(descriptor->consumerUsage)); 270 271 uint64_t backingStore = 0; 272 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE, 273 handle, &backingStore); 274 int numFlexPlanes = 0; 275 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES, 276 handle, &numFlexPlanes); 277 278 *outBufferHandle = handle; 279 auto buffer = std::make_shared<Buffer>(handle, backingStore, 280 *descriptor, stride, numFlexPlanes, true); 281 282 std::lock_guard<std::mutex> lock(mBufferMutex); 283 mBuffers.emplace(handle, std::move(buffer)); 284 285 return GRALLOC1_ERROR_NONE; 286 } 287 288 int32_t Gralloc1On0Adapter::allocateHook(gralloc1_device* device, 289 uint32_t numDescriptors, 290 const gralloc1_buffer_descriptor_t* descriptors, 291 buffer_handle_t* outBuffers) 292 { 293 if (!outBuffers) { 294 return GRALLOC1_ERROR_UNDEFINED; 295 } 296 297 auto adapter = getAdapter(device); 298 299 gralloc1_error_t error = GRALLOC1_ERROR_NONE; 300 uint32_t i; 301 for (i = 0; i < numDescriptors; i++) { 302 auto descriptor = adapter->getDescriptor(descriptors[i]); 303 if (!descriptor) { 304 error = GRALLOC1_ERROR_BAD_DESCRIPTOR; 305 break; 306 } 307 308 buffer_handle_t bufferHandle = nullptr; 309 error = adapter->allocate(descriptors[i], descriptor, &bufferHandle); 310 if (error != GRALLOC1_ERROR_NONE) { 311 break; 312 } 313 314 outBuffers[i] = bufferHandle; 315 } 316 317 if (error == GRALLOC1_ERROR_NONE) { 318 if (numDescriptors > 1) { 319 error = GRALLOC1_ERROR_NOT_SHARED; 320 } 321 } else { 322 for (uint32_t j = 0; j < i; j++) { 323 adapter->release(adapter->getBuffer(outBuffers[j])); 324 outBuffers[j] = nullptr; 325 } 326 } 327 328 return error; 329 } 330 331 gralloc1_error_t Gralloc1On0Adapter::retain( 332 const std::shared_ptr<Buffer>& buffer) 333 { 334 std::lock_guard<std::mutex> lock(mBufferMutex); 335 buffer->retain(); 336 return GRALLOC1_ERROR_NONE; 337 } 338 339 gralloc1_error_t Gralloc1On0Adapter::release( 340 const std::shared_ptr<Buffer>& buffer) 341 { 342 std::lock_guard<std::mutex> lock(mBufferMutex); 343 if (!buffer->release()) { 344 return GRALLOC1_ERROR_NONE; 345 } 346 347 buffer_handle_t handle = buffer->getHandle(); 348 if (buffer->wasAllocated()) { 349 ALOGV("Calling free(%p)", handle); 350 int result = mDevice->free(mDevice, handle); 351 if (result != 0) { 352 ALOGE("gralloc0 free failed: %d", result); 353 } 354 } else { 355 ALOGV("Calling unregisterBuffer(%p)", handle); 356 int result = mModule->unregisterBuffer(mModule, handle); 357 if (result != 0) { 358 ALOGE("gralloc0 unregister failed: %d", result); 359 } 360 } 361 362 mBuffers.erase(handle); 363 return GRALLOC1_ERROR_NONE; 364 } 365 366 gralloc1_error_t Gralloc1On0Adapter::retain(buffer_handle_t bufferHandle) 367 { 368 ALOGV("retain(%p)", bufferHandle); 369 370 std::lock_guard<std::mutex> lock(mBufferMutex); 371 372 if (mBuffers.count(bufferHandle) != 0) { 373 mBuffers[bufferHandle]->retain(); 374 return GRALLOC1_ERROR_NONE; 375 } 376 377 ALOGV("Calling registerBuffer(%p)", bufferHandle); 378 int result = mModule->registerBuffer(mModule, bufferHandle); 379 if (result != 0) { 380 ALOGE("gralloc0 register failed: %d", result); 381 return GRALLOC1_ERROR_NO_RESOURCES; 382 } 383 384 uint64_t backingStore = 0; 385 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE, 386 bufferHandle, &backingStore); 387 388 int numFlexPlanes = 0; 389 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES, 390 bufferHandle, &numFlexPlanes); 391 392 int stride = 0; 393 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_STRIDE, 394 bufferHandle, &stride); 395 396 int width = 0; 397 int height = 0; 398 int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 399 int producerUsage = 0; 400 int consumerUsage = 0; 401 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS, 402 bufferHandle, &width, &height); 403 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_FORMAT, 404 bufferHandle, &format); 405 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE, 406 bufferHandle, &producerUsage); 407 mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE, 408 bufferHandle, &consumerUsage); 409 410 Descriptor descriptor; 411 descriptor.setDimensions(width, height); 412 descriptor.setFormat(format); 413 descriptor.setProducerUsage( 414 static_cast<gralloc1_producer_usage_t>(producerUsage)); 415 descriptor.setConsumerUsage( 416 static_cast<gralloc1_consumer_usage_t>(consumerUsage)); 417 418 auto buffer = std::make_shared<Buffer>(bufferHandle, backingStore, 419 descriptor, stride, numFlexPlanes, false); 420 mBuffers.emplace(bufferHandle, std::move(buffer)); 421 return GRALLOC1_ERROR_NONE; 422 } 423 424 static void syncWaitForever(int fd, const char* logname) 425 { 426 if (fd < 0) { 427 return; 428 } 429 430 const int warningTimeout = 3500; 431 const int error = sync_wait(fd, warningTimeout); 432 if (error < 0 && errno == ETIME) { 433 ALOGE("%s: fence %d didn't signal in %u ms", logname, fd, 434 warningTimeout); 435 sync_wait(fd, -1); 436 } 437 } 438 439 gralloc1_error_t Gralloc1On0Adapter::lock( 440 const std::shared_ptr<Buffer>& buffer, 441 gralloc1_producer_usage_t producerUsage, 442 gralloc1_consumer_usage_t consumerUsage, 443 const gralloc1_rect_t& accessRegion, void** outData, 444 int acquireFence) 445 { 446 if (mMinorVersion >= 3) { 447 int result = mModule->lockAsync(mModule, buffer->getHandle(), 448 android_convertGralloc1To0Usage(producerUsage, consumerUsage), 449 accessRegion.left, accessRegion.top, accessRegion.width, 450 accessRegion.height, outData, acquireFence); 451 if (result != 0) { 452 return GRALLOC1_ERROR_UNSUPPORTED; 453 } 454 } else { 455 syncWaitForever(acquireFence, "Gralloc1On0Adapter::lock"); 456 457 int result = mModule->lock(mModule, buffer->getHandle(), 458 android_convertGralloc1To0Usage(producerUsage, consumerUsage), 459 accessRegion.left, accessRegion.top, accessRegion.width, 460 accessRegion.height, outData); 461 ALOGV("gralloc0 lock returned %d", result); 462 if (result != 0) { 463 return GRALLOC1_ERROR_UNSUPPORTED; 464 } else if (acquireFence >= 0) { 465 close(acquireFence); 466 } 467 } 468 return GRALLOC1_ERROR_NONE; 469 } 470 471 gralloc1_error_t Gralloc1On0Adapter::lockFlex( 472 const std::shared_ptr<Buffer>& buffer, 473 gralloc1_producer_usage_t producerUsage, 474 gralloc1_consumer_usage_t consumerUsage, 475 const gralloc1_rect_t& accessRegion, 476 struct android_flex_layout* outFlex, 477 int acquireFence) 478 { 479 if (mMinorVersion >= 3) { 480 int result = mModule->perform(mModule, 481 GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX, 482 buffer->getHandle(), 483 static_cast<int>(producerUsage), 484 static_cast<int>(consumerUsage), 485 accessRegion.left, 486 accessRegion.top, 487 accessRegion.width, 488 accessRegion.height, 489 outFlex, acquireFence); 490 if (result != 0) { 491 return GRALLOC1_ERROR_UNSUPPORTED; 492 } 493 } else { 494 syncWaitForever(acquireFence, "Gralloc1On0Adapter::lockFlex"); 495 496 int result = mModule->perform(mModule, 497 GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX, 498 buffer->getHandle(), 499 static_cast<int>(producerUsage), 500 static_cast<int>(consumerUsage), 501 accessRegion.left, 502 accessRegion.top, 503 accessRegion.width, 504 accessRegion.height, 505 outFlex, -1); 506 if (result != 0) { 507 return GRALLOC1_ERROR_UNSUPPORTED; 508 } else if (acquireFence >= 0) { 509 close(acquireFence); 510 } 511 } 512 513 return GRALLOC1_ERROR_NONE; 514 } 515 516 gralloc1_error_t Gralloc1On0Adapter::unlock( 517 const std::shared_ptr<Buffer>& buffer, 518 int* outReleaseFence) 519 { 520 if (mMinorVersion >= 3) { 521 int fenceFd = -1; 522 int result = mModule->unlockAsync(mModule, buffer->getHandle(), 523 &fenceFd); 524 if (result != 0) { 525 close(fenceFd); 526 ALOGE("gralloc0 unlockAsync failed: %d", result); 527 } else { 528 *outReleaseFence = fenceFd; 529 } 530 } else { 531 int result = mModule->unlock(mModule, buffer->getHandle()); 532 if (result != 0) { 533 ALOGE("gralloc0 unlock failed: %d", result); 534 } else { 535 *outReleaseFence = -1; 536 } 537 } 538 return GRALLOC1_ERROR_NONE; 539 } 540 541 std::shared_ptr<Gralloc1On0Adapter::Descriptor> 542 Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId) 543 { 544 std::lock_guard<std::mutex> lock(mDescriptorMutex); 545 if (mDescriptors.count(descriptorId) == 0) { 546 return nullptr; 547 } 548 549 return mDescriptors[descriptorId]; 550 } 551 552 std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer( 553 buffer_handle_t bufferHandle) 554 { 555 std::lock_guard<std::mutex> lock(mBufferMutex); 556 if (mBuffers.count(bufferHandle) == 0) { 557 return nullptr; 558 } 559 560 return mBuffers[bufferHandle]; 561 } 562 563 std::atomic<gralloc1_buffer_descriptor_t> 564 Gralloc1On0Adapter::sNextBufferDescriptorId(1); 565 566 } // namespace hardware 567 } // namespace android 568