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