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_UI_GRALLOC_1_ON_0_ADAPTER_H 18 #define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H 19 20 #include <ui/Fence.h> 21 #include <ui/GraphicBuffer.h> 22 23 #include <hardware/gralloc1.h> 24 25 #include <mutex> 26 #include <string> 27 #include <unordered_map> 28 #include <vector> 29 30 struct gralloc_module_t; 31 32 // This is not an "official" capability (i.e., it is not found in gralloc1.h), 33 // but we will use it to detect that we are running through the adapter, which 34 // is capable of collaborating with GraphicBuffer such that queries on a 35 // buffer_handle_t succeed 36 static const auto GRALLOC1_CAPABILITY_ON_ADAPTER = 37 static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1); 38 39 static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER = 40 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1); 41 static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID = 42 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2); 43 static const auto GRALLOC1_FUNCTION_LOCK_YCBCR = 44 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3); 45 static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR; 46 47 typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)( 48 gralloc1_device_t* device, const android::GraphicBuffer* buffer); 49 typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)( 50 gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor, 51 gralloc1_backing_store_t id, buffer_handle_t* outBuffer); 52 typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)( 53 gralloc1_device_t* device, buffer_handle_t buffer, 54 uint64_t /*gralloc1_producer_usage_t*/ producerUsage, 55 uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage, 56 const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr, 57 int32_t acquireFence); 58 59 namespace android { 60 61 class Gralloc1On0Adapter : public gralloc1_device_t 62 { 63 public: 64 Gralloc1On0Adapter(const hw_module_t* module); 65 ~Gralloc1On0Adapter(); 66 getDevice()67 gralloc1_device_t* getDevice() { 68 return static_cast<gralloc1_device_t*>(this); 69 } 70 71 private: getAdapter(gralloc1_device_t * device)72 static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) { 73 return static_cast<Gralloc1On0Adapter*>(device); 74 } 75 76 // getCapabilities 77 78 void doGetCapabilities(uint32_t* outCount, 79 int32_t* /*gralloc1_capability_t*/ outCapabilities); getCapabilitiesHook(gralloc1_device_t * device,uint32_t * outCount,int32_t * outCapabilities)80 static void getCapabilitiesHook(gralloc1_device_t* device, 81 uint32_t* outCount, 82 int32_t* /*gralloc1_capability_t*/ outCapabilities) { 83 getAdapter(device)->doGetCapabilities(outCount, outCapabilities); 84 }; 85 86 // getFunction 87 88 gralloc1_function_pointer_t doGetFunction( 89 int32_t /*gralloc1_function_descriptor_t*/ descriptor); getFunctionHook(gralloc1_device_t * device,int32_t descriptor)90 static gralloc1_function_pointer_t getFunctionHook( 91 gralloc1_device_t* device, 92 int32_t /*gralloc1_function_descriptor_t*/ descriptor) { 93 return getAdapter(device)->doGetFunction(descriptor); 94 } 95 96 // dump 97 98 void dump(uint32_t* outSize, char* outBuffer); dumpHook(gralloc1_device_t * device,uint32_t * outSize,char * outBuffer)99 static void dumpHook(gralloc1_device_t* device, uint32_t* outSize, 100 char* outBuffer) { 101 return getAdapter(device)->dump(outSize, outBuffer); 102 } 103 std::string mCachedDump; 104 105 // Buffer descriptor lifecycle functions 106 107 class Descriptor; 108 109 gralloc1_error_t createDescriptor( 110 gralloc1_buffer_descriptor_t* outDescriptor); createDescriptorHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t * outDescriptor)111 static int32_t createDescriptorHook(gralloc1_device_t* device, 112 gralloc1_buffer_descriptor_t* outDescriptor) { 113 auto error = getAdapter(device)->createDescriptor(outDescriptor); 114 return static_cast<int32_t>(error); 115 } 116 117 gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor); destroyDescriptorHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptor)118 static int32_t destroyDescriptorHook(gralloc1_device_t* device, 119 gralloc1_buffer_descriptor_t descriptor) { 120 auto error = getAdapter(device)->destroyDescriptor(descriptor); 121 return static_cast<int32_t>(error); 122 } 123 124 // Buffer descriptor modification functions 125 126 struct Descriptor : public std::enable_shared_from_this<Descriptor> { DescriptorDescriptor127 Descriptor(Gralloc1On0Adapter* adapter, 128 gralloc1_buffer_descriptor_t id) 129 : adapter(adapter), 130 id(id), 131 width(0), 132 height(0), 133 format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED), 134 producerUsage(GRALLOC1_PRODUCER_USAGE_NONE), 135 consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {} 136 setDimensionsDescriptor137 gralloc1_error_t setDimensions(uint32_t w, uint32_t h) { 138 width = w; 139 height = h; 140 return GRALLOC1_ERROR_NONE; 141 } 142 setFormatDescriptor143 gralloc1_error_t setFormat(int32_t f) { 144 format = f; 145 return GRALLOC1_ERROR_NONE; 146 } 147 setProducerUsageDescriptor148 gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) { 149 producerUsage = usage; 150 return GRALLOC1_ERROR_NONE; 151 } 152 setConsumerUsageDescriptor153 gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) { 154 consumerUsage = usage; 155 return GRALLOC1_ERROR_NONE; 156 } 157 158 Gralloc1On0Adapter* const adapter; 159 const gralloc1_buffer_descriptor_t id; 160 161 uint32_t width; 162 uint32_t height; 163 int32_t format; 164 gralloc1_producer_usage_t producerUsage; 165 gralloc1_consumer_usage_t consumerUsage; 166 }; 167 168 template <typename ...Args> callDescriptorFunction(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,gralloc1_error_t (Descriptor::* member)(Args...),Args...args)169 static int32_t callDescriptorFunction(gralloc1_device_t* device, 170 gralloc1_buffer_descriptor_t descriptorId, 171 gralloc1_error_t (Descriptor::*member)(Args...), Args... args) { 172 auto descriptor = getAdapter(device)->getDescriptor(descriptorId); 173 if (!descriptor) { 174 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR); 175 } 176 auto error = ((*descriptor).*member)(std::forward<Args>(args)...); 177 return static_cast<int32_t>(error); 178 } 179 setConsumerUsageHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint64_t intUsage)180 static int32_t setConsumerUsageHook(gralloc1_device_t* device, 181 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) { 182 auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage); 183 return callDescriptorFunction(device, descriptorId, 184 &Descriptor::setConsumerUsage, usage); 185 } 186 setDimensionsHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint32_t width,uint32_t height)187 static int32_t setDimensionsHook(gralloc1_device_t* device, 188 gralloc1_buffer_descriptor_t descriptorId, uint32_t width, 189 uint32_t height) { 190 return callDescriptorFunction(device, descriptorId, 191 &Descriptor::setDimensions, width, height); 192 } 193 setFormatHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,int32_t format)194 static int32_t setFormatHook(gralloc1_device_t* device, 195 gralloc1_buffer_descriptor_t descriptorId, int32_t format) { 196 return callDescriptorFunction(device, descriptorId, 197 &Descriptor::setFormat, format); 198 } 199 setProducerUsageHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint64_t intUsage)200 static int32_t setProducerUsageHook(gralloc1_device_t* device, 201 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) { 202 auto usage = static_cast<gralloc1_producer_usage_t>(intUsage); 203 return callDescriptorFunction(device, descriptorId, 204 &Descriptor::setProducerUsage, usage); 205 } 206 207 // Buffer handle query functions 208 209 class Buffer { 210 public: 211 Buffer(buffer_handle_t handle, gralloc1_backing_store_t store, 212 const Descriptor& descriptor, uint32_t stride, 213 bool wasAllocated); 214 getHandle()215 buffer_handle_t getHandle() const { return mHandle; } 216 retain()217 void retain() { ++mReferenceCount; } 218 219 // Returns true if the reference count has dropped to 0, indicating that 220 // the buffer needs to be released release()221 bool release() { return --mReferenceCount == 0; } 222 wasAllocated()223 bool wasAllocated() const { return mWasAllocated; } 224 getBackingStore(gralloc1_backing_store_t * outStore)225 gralloc1_error_t getBackingStore( 226 gralloc1_backing_store_t* outStore) const { 227 *outStore = mStore; 228 return GRALLOC1_ERROR_NONE; 229 } 230 getConsumerUsage(gralloc1_consumer_usage_t * outUsage)231 gralloc1_error_t getConsumerUsage( 232 gralloc1_consumer_usage_t* outUsage) const { 233 *outUsage = mDescriptor.consumerUsage; 234 return GRALLOC1_ERROR_NONE; 235 } 236 getDimensions(uint32_t * outWidth,uint32_t * outHeight)237 gralloc1_error_t getDimensions(uint32_t* outWidth, 238 uint32_t* outHeight) const { 239 *outWidth = mDescriptor.width; 240 *outHeight = mDescriptor.height; 241 return GRALLOC1_ERROR_NONE; 242 } 243 getFormat(int32_t * outFormat)244 gralloc1_error_t getFormat(int32_t* outFormat) const { 245 *outFormat = mDescriptor.format; 246 return GRALLOC1_ERROR_NONE; 247 } 248 getNumFlexPlanes(uint32_t * outNumPlanes)249 gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const { 250 // TODO: This is conservative, and we could do better by examining 251 // the format, but it won't hurt anything for now 252 *outNumPlanes = 4; 253 return GRALLOC1_ERROR_NONE; 254 } 255 getProducerUsage(gralloc1_producer_usage_t * outUsage)256 gralloc1_error_t getProducerUsage( 257 gralloc1_producer_usage_t* outUsage) const { 258 *outUsage = mDescriptor.producerUsage; 259 return GRALLOC1_ERROR_NONE; 260 } 261 getStride(uint32_t * outStride)262 gralloc1_error_t getStride(uint32_t* outStride) const { 263 *outStride = mStride; 264 return GRALLOC1_ERROR_NONE; 265 } 266 267 private: 268 269 const buffer_handle_t mHandle; 270 size_t mReferenceCount; 271 272 // Since we're adapting to gralloc0, there will always be a 1:1 273 // correspondence between buffer handles and backing stores, and the 274 // backing store ID will be the same as the GraphicBuffer unique ID 275 const gralloc1_backing_store_t mStore; 276 277 const Descriptor mDescriptor; 278 const uint32_t mStride; 279 280 // Whether this buffer allocated in this process (as opposed to just 281 // being retained here), which determines whether to free or unregister 282 // the buffer when this Buffer is released 283 const bool mWasAllocated; 284 }; 285 286 template <typename ...Args> callBufferFunction(gralloc1_device_t * device,buffer_handle_t bufferHandle,gralloc1_error_t (Buffer::* member)(Args...)const,Args...args)287 static int32_t callBufferFunction(gralloc1_device_t* device, 288 buffer_handle_t bufferHandle, 289 gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) { 290 auto buffer = getAdapter(device)->getBuffer(bufferHandle); 291 if (!buffer) { 292 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE); 293 } 294 auto error = ((*buffer).*member)(std::forward<Args>(args)...); 295 return static_cast<int32_t>(error); 296 } 297 298 template <typename MF, MF memFunc, typename ...Args> bufferHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,Args...args)299 static int32_t bufferHook(gralloc1_device_t* device, 300 buffer_handle_t bufferHandle, Args... args) { 301 return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle, 302 memFunc, std::forward<Args>(args)...); 303 } 304 getConsumerUsageHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t * outUsage)305 static int32_t getConsumerUsageHook(gralloc1_device_t* device, 306 buffer_handle_t bufferHandle, uint64_t* outUsage) { 307 auto usage = GRALLOC1_CONSUMER_USAGE_NONE; 308 auto error = callBufferFunction(device, bufferHandle, 309 &Buffer::getConsumerUsage, &usage); 310 if (error != GRALLOC1_ERROR_NONE) { 311 *outUsage = static_cast<uint64_t>(usage); 312 } 313 return error; 314 } 315 getProducerUsageHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t * outUsage)316 static int32_t getProducerUsageHook(gralloc1_device_t* device, 317 buffer_handle_t bufferHandle, uint64_t* outUsage) { 318 auto usage = GRALLOC1_PRODUCER_USAGE_NONE; 319 auto error = callBufferFunction(device, bufferHandle, 320 &Buffer::getProducerUsage, &usage); 321 if (error != GRALLOC1_ERROR_NONE) { 322 *outUsage = static_cast<uint64_t>(usage); 323 } 324 return error; 325 } 326 327 // Buffer management functions 328 329 // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be 330 // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID 331 gralloc1_error_t allocate( 332 const std::shared_ptr<Descriptor>& descriptor, 333 gralloc1_backing_store_t id, 334 buffer_handle_t* outBufferHandle); 335 static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device, 336 gralloc1_buffer_descriptor_t descriptors, 337 gralloc1_backing_store_t id, buffer_handle_t* outBuffer); 338 339 gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer); 340 gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer); 341 342 // Member function pointer 'member' will either be retain or release 343 template <gralloc1_error_t (Gralloc1On0Adapter::*member)( 344 const std::shared_ptr<Buffer>& buffer)> managementHook(gralloc1_device_t * device,buffer_handle_t bufferHandle)345 static int32_t managementHook(gralloc1_device_t* device, 346 buffer_handle_t bufferHandle) { 347 auto adapter = getAdapter(device); 348 349 auto buffer = adapter->getBuffer(bufferHandle); 350 if (!buffer) { 351 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE); 352 } 353 354 auto error = ((*adapter).*member)(buffer); 355 return static_cast<int32_t>(error); 356 } 357 358 gralloc1_error_t retain(const GraphicBuffer* buffer); retainGraphicBufferHook(gralloc1_device_t * device,const GraphicBuffer * buffer)359 static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device, 360 const GraphicBuffer* buffer) { 361 auto adapter = getAdapter(device); 362 return adapter->retain(buffer); 363 } 364 365 // Buffer access functions 366 367 gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer, 368 gralloc1_producer_usage_t producerUsage, 369 gralloc1_consumer_usage_t consumerUsage, 370 const gralloc1_rect_t& accessRegion, void** outData, 371 const sp<Fence>& acquireFence); 372 gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer, 373 gralloc1_producer_usage_t producerUsage, 374 gralloc1_consumer_usage_t consumerUsage, 375 const gralloc1_rect_t& accessRegion, 376 struct android_flex_layout* outFlex, 377 const sp<Fence>& acquireFence); 378 gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer, 379 gralloc1_producer_usage_t producerUsage, 380 gralloc1_consumer_usage_t consumerUsage, 381 const gralloc1_rect_t& accessRegion, 382 struct android_ycbcr* outFlex, 383 const sp<Fence>& acquireFence); 384 385 template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)( 386 const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t, 387 gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*, 388 const sp<Fence>&)> lockHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t uintProducerUsage,uint64_t uintConsumerUsage,const gralloc1_rect_t * accessRegion,OUT * outData,int32_t acquireFenceFd)389 static int32_t lockHook(gralloc1_device_t* device, 390 buffer_handle_t bufferHandle, 391 uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage, 392 uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage, 393 const gralloc1_rect_t* accessRegion, OUT* outData, 394 int32_t acquireFenceFd) { 395 auto adapter = getAdapter(device); 396 397 // Exactly one of producer and consumer usage must be *_USAGE_NONE, 398 // but we can't check this until the upper levels of the framework 399 // correctly distinguish between producer and consumer usage 400 /* 401 bool hasProducerUsage = 402 uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE; 403 bool hasConsumerUsage = 404 uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE; 405 if (hasProducerUsage && hasConsumerUsage || 406 !hasProducerUsage && !hasConsumerUsage) { 407 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE); 408 } 409 */ 410 411 auto producerUsage = 412 static_cast<gralloc1_producer_usage_t>(uintProducerUsage); 413 auto consumerUsage = 414 static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage); 415 416 if (!outData) { 417 const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ | 418 GRALLOC1_PRODUCER_USAGE_CPU_WRITE; 419 if (producerUsage & producerCpuUsage != 0) { 420 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE); 421 } 422 if (consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ != 0) { 423 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE); 424 } 425 } 426 427 auto buffer = adapter->getBuffer(bufferHandle); 428 if (!buffer) { 429 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE); 430 } 431 432 if (!accessRegion) { 433 ALOGE("accessRegion is null"); 434 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE); 435 } 436 437 sp<Fence> acquireFence{new Fence(acquireFenceFd)}; 438 auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage, 439 *accessRegion, outData, acquireFence); 440 return static_cast<int32_t>(error); 441 } 442 443 gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer, 444 sp<Fence>* outReleaseFence); unlockHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,int32_t * outReleaseFenceFd)445 static int32_t unlockHook(gralloc1_device_t* device, 446 buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) { 447 auto adapter = getAdapter(device); 448 449 auto buffer = adapter->getBuffer(bufferHandle); 450 if (!buffer) { 451 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE); 452 } 453 454 sp<Fence> releaseFence = Fence::NO_FENCE; 455 auto error = adapter->unlock(buffer, &releaseFence); 456 if (error == GRALLOC1_ERROR_NONE) { 457 *outReleaseFenceFd = releaseFence->dup(); 458 } 459 return static_cast<int32_t>(error); 460 } 461 462 // Adapter internals 463 const gralloc_module_t* mModule; 464 uint8_t mMinorVersion; 465 alloc_device_t* mDevice; 466 467 std::shared_ptr<Descriptor> getDescriptor( 468 gralloc1_buffer_descriptor_t descriptorId); 469 std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle); 470 471 static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId; 472 std::mutex mDescriptorMutex; 473 std::unordered_map<gralloc1_buffer_descriptor_t, 474 std::shared_ptr<Descriptor>> mDescriptors; 475 std::mutex mBufferMutex; 476 std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers; 477 }; 478 479 } // namespace android 480 481 #endif 482