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 #define LOG_TAG "Gralloc2" 18 19 #include <hidl/ServiceManagement.h> 20 #include <hwbinder/IPCThreadState.h> 21 #include <ui/Gralloc2.h> 22 23 #include <inttypes.h> 24 #include <log/log.h> 25 #pragma clang diagnostic push 26 #pragma clang diagnostic ignored "-Wzero-length-array" 27 #include <sync/sync.h> 28 #pragma clang diagnostic pop 29 30 using android::hardware::graphics::allocator::V2_0::IAllocator; 31 using android::hardware::graphics::common::V1_1::BufferUsage; 32 using android::hardware::graphics::common::V1_1::PixelFormat; 33 using android::hardware::graphics::mapper::V2_0::BufferDescriptor; 34 using android::hardware::graphics::mapper::V2_0::Error; 35 using android::hardware::graphics::mapper::V2_0::YCbCrLayout; 36 using android::hardware::graphics::mapper::V2_1::IMapper; 37 38 namespace android { 39 40 namespace { 41 42 static constexpr Error kTransactionError = Error::NO_RESOURCES; 43 44 uint64_t getValid10UsageBits() { 45 static const uint64_t valid10UsageBits = []() -> uint64_t { 46 using hardware::graphics::common::V1_0::BufferUsage; 47 uint64_t bits = 0; 48 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) { 49 bits = bits | bit; 50 } 51 return bits; 52 }(); 53 return valid10UsageBits; 54 } 55 56 uint64_t getValid11UsageBits() { 57 static const uint64_t valid11UsageBits = []() -> uint64_t { 58 using hardware::graphics::common::V1_1::BufferUsage; 59 uint64_t bits = 0; 60 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) { 61 bits = bits | bit; 62 } 63 return bits; 64 }(); 65 return valid11UsageBits; 66 } 67 68 static inline IMapper::Rect sGralloc2Rect(const Rect& rect) { 69 IMapper::Rect outRect{}; 70 outRect.left = rect.left; 71 outRect.top = rect.top; 72 outRect.width = rect.width(); 73 outRect.height = rect.height(); 74 return outRect; 75 } 76 77 } // anonymous namespace 78 79 void Gralloc2Mapper::preload() { 80 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>(); 81 } 82 83 Gralloc2Mapper::Gralloc2Mapper() { 84 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService(); 85 if (mMapper == nullptr) { 86 ALOGW("mapper 2.x is not supported"); 87 return; 88 } 89 if (mMapper->isRemote()) { 90 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode"); 91 } 92 93 // IMapper 2.1 is optional 94 mMapperV2_1 = IMapper::castFrom(mMapper); 95 } 96 97 bool Gralloc2Mapper::isLoaded() const { 98 return mMapper != nullptr; 99 } 100 101 status_t Gralloc2Mapper::validateBufferDescriptorInfo( 102 IMapper::BufferDescriptorInfo* descriptorInfo) const { 103 uint64_t validUsageBits = getValid10UsageBits(); 104 if (mMapperV2_1 != nullptr) { 105 validUsageBits = validUsageBits | getValid11UsageBits(); 106 } 107 108 if (descriptorInfo->usage & ~validUsageBits) { 109 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64, 110 descriptorInfo->usage & ~validUsageBits); 111 return BAD_VALUE; 112 } 113 return NO_ERROR; 114 } 115 116 status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo, 117 void* outBufferDescriptor) const { 118 IMapper::BufferDescriptorInfo* descriptorInfo = 119 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo); 120 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor); 121 122 status_t status = validateBufferDescriptorInfo(descriptorInfo); 123 if (status != NO_ERROR) { 124 return status; 125 } 126 127 Error error; 128 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) 129 { 130 error = tmpError; 131 if (error != Error::NONE) { 132 return; 133 } 134 135 *outDescriptor = tmpDescriptor; 136 }; 137 138 hardware::Return<void> ret; 139 if (mMapperV2_1 != nullptr) { 140 ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb); 141 } else { 142 const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = { 143 descriptorInfo->width, 144 descriptorInfo->height, 145 descriptorInfo->layerCount, 146 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format), 147 descriptorInfo->usage, 148 }; 149 ret = mMapper->createDescriptor(info, hidl_cb); 150 } 151 152 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError); 153 } 154 155 status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle, 156 buffer_handle_t* outBufferHandle) const { 157 Error error; 158 auto ret = mMapper->importBuffer(rawHandle, 159 [&](const auto& tmpError, const auto& tmpBuffer) 160 { 161 error = tmpError; 162 if (error != Error::NONE) { 163 return; 164 } 165 166 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer); 167 }); 168 169 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError); 170 } 171 172 void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const { 173 auto buffer = const_cast<native_handle_t*>(bufferHandle); 174 auto ret = mMapper->freeBuffer(buffer); 175 176 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError; 177 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", 178 buffer, error); 179 } 180 181 status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width, 182 uint32_t height, android::PixelFormat format, 183 uint32_t layerCount, uint64_t usage, 184 uint32_t stride) const { 185 if (mMapperV2_1 == nullptr) { 186 return NO_ERROR; 187 } 188 189 IMapper::BufferDescriptorInfo descriptorInfo = {}; 190 descriptorInfo.width = width; 191 descriptorInfo.height = height; 192 descriptorInfo.layerCount = layerCount; 193 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format); 194 descriptorInfo.usage = usage; 195 196 auto buffer = const_cast<native_handle_t*>(bufferHandle); 197 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride); 198 199 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError); 200 } 201 202 void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds, 203 uint32_t* outNumInts) const { 204 *outNumFds = uint32_t(bufferHandle->numFds); 205 *outNumInts = uint32_t(bufferHandle->numInts); 206 207 if (mMapperV2_1 == nullptr) { 208 return; 209 } 210 211 Error error; 212 auto buffer = const_cast<native_handle_t*>(bufferHandle); 213 auto ret = mMapperV2_1->getTransportSize(buffer, 214 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) { 215 error = tmpError; 216 if (error != Error::NONE) { 217 return; 218 } 219 220 *outNumFds = tmpNumFds; 221 *outNumInts = tmpNumInts; 222 }); 223 224 error = (ret.isOk()) ? error : kTransactionError; 225 226 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error); 227 } 228 229 status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds, 230 int acquireFence, void** outData, int32_t* outBytesPerPixel, 231 int32_t* outBytesPerStride) const { 232 if (outBytesPerPixel) { 233 *outBytesPerPixel = -1; 234 } 235 if (outBytesPerStride) { 236 *outBytesPerStride = -1; 237 } 238 auto buffer = const_cast<native_handle_t*>(bufferHandle); 239 240 IMapper::Rect accessRegion = sGralloc2Rect(bounds); 241 242 // put acquireFence in a hidl_handle 243 hardware::hidl_handle acquireFenceHandle; 244 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); 245 if (acquireFence >= 0) { 246 auto h = native_handle_init(acquireFenceStorage, 1, 0); 247 h->data[0] = acquireFence; 248 acquireFenceHandle = h; 249 } 250 251 Error error; 252 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle, 253 [&](const auto& tmpError, const auto& tmpData) 254 { 255 error = tmpError; 256 if (error != Error::NONE) { 257 return; 258 } 259 260 *outData = tmpData; 261 }); 262 263 // we own acquireFence even on errors 264 if (acquireFence >= 0) { 265 close(acquireFence); 266 } 267 268 error = (ret.isOk()) ? error : kTransactionError; 269 270 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error); 271 272 return static_cast<status_t>(error); 273 } 274 275 status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds, 276 int acquireFence, android_ycbcr* ycbcr) const { 277 auto buffer = const_cast<native_handle_t*>(bufferHandle); 278 279 IMapper::Rect accessRegion = sGralloc2Rect(bounds); 280 281 // put acquireFence in a hidl_handle 282 hardware::hidl_handle acquireFenceHandle; 283 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0); 284 if (acquireFence >= 0) { 285 auto h = native_handle_init(acquireFenceStorage, 1, 0); 286 h->data[0] = acquireFence; 287 acquireFenceHandle = h; 288 } 289 290 YCbCrLayout layout; 291 Error error; 292 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, 293 acquireFenceHandle, 294 [&](const auto& tmpError, const auto& tmpLayout) 295 { 296 error = tmpError; 297 if (error != Error::NONE) { 298 return; 299 } 300 301 layout = tmpLayout; 302 }); 303 304 if (error == Error::NONE) { 305 ycbcr->y = layout.y; 306 ycbcr->cb = layout.cb; 307 ycbcr->cr = layout.cr; 308 ycbcr->ystride = static_cast<size_t>(layout.yStride); 309 ycbcr->cstride = static_cast<size_t>(layout.cStride); 310 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep); 311 } 312 313 // we own acquireFence even on errors 314 if (acquireFence >= 0) { 315 close(acquireFence); 316 } 317 318 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError); 319 } 320 321 int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const { 322 auto buffer = const_cast<native_handle_t*>(bufferHandle); 323 324 int releaseFence = -1; 325 Error error; 326 auto ret = mMapper->unlock(buffer, 327 [&](const auto& tmpError, const auto& tmpReleaseFence) 328 { 329 error = tmpError; 330 if (error != Error::NONE) { 331 return; 332 } 333 334 auto fenceHandle = tmpReleaseFence.getNativeHandle(); 335 if (fenceHandle && fenceHandle->numFds == 1) { 336 int fd = dup(fenceHandle->data[0]); 337 if (fd >= 0) { 338 releaseFence = fd; 339 } else { 340 ALOGD("failed to dup unlock release fence"); 341 sync_wait(fenceHandle->data[0], -1); 342 } 343 } 344 }); 345 346 error = (ret.isOk()) ? error : kTransactionError; 347 if (error != Error::NONE) { 348 ALOGE("unlock(%p) failed with %d", buffer, error); 349 } 350 351 return releaseFence; 352 } 353 354 status_t Gralloc2Mapper::isSupported(uint32_t /*width*/, uint32_t /*height*/, 355 android::PixelFormat /*format*/, uint32_t /*layerCount*/, 356 uint64_t /*usage*/, bool* /*outSupported*/) const { 357 return INVALID_OPERATION; 358 } 359 360 Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) { 361 mAllocator = IAllocator::getService(); 362 if (mAllocator == nullptr) { 363 ALOGW("allocator 2.x is not supported"); 364 return; 365 } 366 } 367 368 bool Gralloc2Allocator::isLoaded() const { 369 return mAllocator != nullptr; 370 } 371 372 std::string Gralloc2Allocator::dumpDebugInfo() const { 373 std::string debugInfo; 374 375 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { 376 debugInfo = tmpDebugInfo.c_str(); 377 }); 378 379 return debugInfo; 380 } 381 382 status_t Gralloc2Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format, 383 uint32_t layerCount, uint64_t usage, uint32_t bufferCount, 384 uint32_t* outStride, buffer_handle_t* outBufferHandles) const { 385 IMapper::BufferDescriptorInfo descriptorInfo = {}; 386 descriptorInfo.width = width; 387 descriptorInfo.height = height; 388 descriptorInfo.layerCount = layerCount; 389 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format); 390 descriptorInfo.usage = usage; 391 392 BufferDescriptor descriptor; 393 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo), 394 static_cast<void*>(&descriptor)); 395 if (error != NO_ERROR) { 396 return error; 397 } 398 399 auto ret = mAllocator->allocate(descriptor, bufferCount, 400 [&](const auto& tmpError, const auto& tmpStride, 401 const auto& tmpBuffers) { 402 error = static_cast<status_t>(tmpError); 403 if (tmpError != Error::NONE) { 404 return; 405 } 406 407 // import buffers 408 for (uint32_t i = 0; i < bufferCount; i++) { 409 error = mMapper.importBuffer(tmpBuffers[i], 410 &outBufferHandles[i]); 411 if (error != NO_ERROR) { 412 for (uint32_t j = 0; j < i; j++) { 413 mMapper.freeBuffer(outBufferHandles[j]); 414 outBufferHandles[j] = nullptr; 415 } 416 return; 417 } 418 } 419 420 *outStride = tmpStride; 421 }); 422 423 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now 424 hardware::IPCThreadState::self()->flushCommands(); 425 426 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError); 427 } 428 429 } // namespace android 430