Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 The Android Open Source Project |
| 3 | * * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | |
| 16 | #define LOG_TAG "GrallocMapperPassthrough" |
| 17 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 18 | #include <android/hardware/graphics/allocator/2.0/IAllocator.h> |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 19 | #include <android/hardware/graphics/mapper/2.0/IMapper.h> |
| 20 | #include <hardware/gralloc1.h> |
| 21 | #include <log/log.h> |
| 22 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 23 | #include <unordered_set> |
| 24 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 25 | namespace android { |
| 26 | namespace hardware { |
| 27 | namespace graphics { |
| 28 | namespace mapper { |
| 29 | namespace V2_0 { |
| 30 | namespace implementation { |
| 31 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 32 | using Capability = allocator::V2_0::IAllocator::Capability; |
| 33 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 34 | class GrallocDevice : public Device { |
| 35 | public: |
| 36 | GrallocDevice(); |
| 37 | ~GrallocDevice(); |
| 38 | |
| 39 | // IMapper interface |
| 40 | Error retain(const native_handle_t* bufferHandle); |
| 41 | Error release(const native_handle_t* bufferHandle); |
| 42 | Error getDimensions(const native_handle_t* bufferHandle, |
| 43 | uint32_t* outWidth, uint32_t* outHeight); |
| 44 | Error getFormat(const native_handle_t* bufferHandle, |
| 45 | PixelFormat* outFormat); |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 46 | Error getLayerCount(const native_handle_t* bufferHandle, |
| 47 | uint32_t* outLayerCount); |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 48 | Error getProducerUsageMask(const native_handle_t* bufferHandle, |
| 49 | uint64_t* outUsageMask); |
| 50 | Error getConsumerUsageMask(const native_handle_t* bufferHandle, |
| 51 | uint64_t* outUsageMask); |
| 52 | Error getBackingStore(const native_handle_t* bufferHandle, |
| 53 | BackingStore* outStore); |
| 54 | Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride); |
| 55 | Error getNumFlexPlanes(const native_handle_t* bufferHandle, |
| 56 | uint32_t* outNumPlanes); |
| 57 | Error lock(const native_handle_t* bufferHandle, |
| 58 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 59 | const Rect* accessRegion, int32_t acquireFence, void** outData); |
| 60 | Error lockFlex(const native_handle_t* bufferHandle, |
| 61 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 62 | const Rect* accessRegion, int32_t acquireFence, |
| 63 | FlexLayout* outFlexLayout); |
| 64 | Error unlock(const native_handle_t* bufferHandle, |
| 65 | int32_t* outReleaseFence); |
| 66 | |
| 67 | private: |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 68 | void initCapabilities(); |
| 69 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 70 | void initDispatch(); |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 71 | bool hasCapability(Capability capability) const; |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 72 | |
| 73 | gralloc1_device_t* mDevice; |
| 74 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 75 | std::unordered_set<Capability> mCapabilities; |
| 76 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 77 | struct { |
| 78 | GRALLOC1_PFN_RETAIN retain; |
| 79 | GRALLOC1_PFN_RELEASE release; |
| 80 | GRALLOC1_PFN_GET_DIMENSIONS getDimensions; |
| 81 | GRALLOC1_PFN_GET_FORMAT getFormat; |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 82 | GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount; |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 83 | GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage; |
| 84 | GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage; |
| 85 | GRALLOC1_PFN_GET_BACKING_STORE getBackingStore; |
| 86 | GRALLOC1_PFN_GET_STRIDE getStride; |
| 87 | GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes; |
| 88 | GRALLOC1_PFN_LOCK lock; |
| 89 | GRALLOC1_PFN_LOCK_FLEX lockFlex; |
| 90 | GRALLOC1_PFN_UNLOCK unlock; |
| 91 | } mDispatch; |
| 92 | }; |
| 93 | |
| 94 | GrallocDevice::GrallocDevice() |
| 95 | { |
| 96 | const hw_module_t* module; |
| 97 | int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); |
| 98 | if (status) { |
| 99 | LOG_ALWAYS_FATAL("failed to get gralloc module"); |
| 100 | } |
| 101 | |
| 102 | uint8_t major = (module->module_api_version >> 8) & 0xff; |
| 103 | if (major != 1) { |
| 104 | LOG_ALWAYS_FATAL("unknown gralloc module major version %d", major); |
| 105 | } |
| 106 | |
| 107 | status = gralloc1_open(module, &mDevice); |
| 108 | if (status) { |
| 109 | LOG_ALWAYS_FATAL("failed to open gralloc1 device"); |
| 110 | } |
| 111 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 112 | initCapabilities(); |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 113 | initDispatch(); |
| 114 | } |
| 115 | |
| 116 | GrallocDevice::~GrallocDevice() |
| 117 | { |
| 118 | gralloc1_close(mDevice); |
| 119 | } |
| 120 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 121 | void GrallocDevice::initCapabilities() |
| 122 | { |
| 123 | uint32_t count; |
| 124 | mDevice->getCapabilities(mDevice, &count, nullptr); |
| 125 | |
| 126 | std::vector<Capability> caps(count); |
| 127 | mDevice->getCapabilities(mDevice, &count, reinterpret_cast< |
| 128 | std::underlying_type<Capability>::type*>(caps.data())); |
| 129 | caps.resize(count); |
| 130 | |
| 131 | mCapabilities.insert(caps.cbegin(), caps.cend()); |
| 132 | } |
| 133 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 134 | void GrallocDevice::initDispatch() |
| 135 | { |
| 136 | #define CHECK_FUNC(func, desc) do { \ |
| 137 | mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>( \ |
| 138 | mDevice->getFunction(mDevice, desc)); \ |
| 139 | if (!mDispatch.func) { \ |
| 140 | LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \ |
| 141 | } \ |
| 142 | } while (0) |
| 143 | |
| 144 | CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN); |
| 145 | CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE); |
| 146 | CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS); |
| 147 | CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT); |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 148 | if (hasCapability(Capability::LAYERED_BUFFERS)) { |
| 149 | CHECK_FUNC(getLayerCount, GRALLOC1_FUNCTION_GET_LAYER_COUNT); |
| 150 | } |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 151 | CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE); |
| 152 | CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE); |
| 153 | CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE); |
| 154 | CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE); |
| 155 | CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES); |
| 156 | CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK); |
| 157 | CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX); |
| 158 | CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK); |
| 159 | |
| 160 | #undef CHECK_FUNC |
| 161 | } |
| 162 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 163 | bool GrallocDevice::hasCapability(Capability capability) const |
| 164 | { |
| 165 | return (mCapabilities.count(capability) > 0); |
| 166 | } |
| 167 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 168 | Error GrallocDevice::retain(const native_handle_t* bufferHandle) |
| 169 | { |
| 170 | int32_t error = mDispatch.retain(mDevice, bufferHandle); |
| 171 | return static_cast<Error>(error); |
| 172 | } |
| 173 | |
| 174 | Error GrallocDevice::release(const native_handle_t* bufferHandle) |
| 175 | { |
| 176 | int32_t error = mDispatch.release(mDevice, bufferHandle); |
| 177 | return static_cast<Error>(error); |
| 178 | } |
| 179 | |
| 180 | Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle, |
| 181 | uint32_t* outWidth, uint32_t* outHeight) |
| 182 | { |
| 183 | int32_t error = mDispatch.getDimensions(mDevice, bufferHandle, |
| 184 | outWidth, outHeight); |
| 185 | return static_cast<Error>(error); |
| 186 | } |
| 187 | |
| 188 | Error GrallocDevice::getFormat(const native_handle_t* bufferHandle, |
| 189 | PixelFormat* outFormat) |
| 190 | { |
| 191 | int32_t error = mDispatch.getFormat(mDevice, bufferHandle, |
| 192 | reinterpret_cast<int32_t*>(outFormat)); |
| 193 | return static_cast<Error>(error); |
| 194 | } |
| 195 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 196 | Error GrallocDevice::getLayerCount(const native_handle_t* bufferHandle, |
| 197 | uint32_t* outLayerCount) |
| 198 | { |
| 199 | if (hasCapability(Capability::LAYERED_BUFFERS)) { |
| 200 | int32_t error = mDispatch.getLayerCount(mDevice, bufferHandle, |
| 201 | outLayerCount); |
| 202 | return static_cast<Error>(error); |
| 203 | } else { |
| 204 | *outLayerCount = 1; |
| 205 | return Error::NONE; |
| 206 | } |
| 207 | } |
| 208 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 209 | Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle, |
| 210 | uint64_t* outUsageMask) |
| 211 | { |
| 212 | int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle, |
| 213 | outUsageMask); |
| 214 | return static_cast<Error>(error); |
| 215 | } |
| 216 | |
| 217 | Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle, |
| 218 | uint64_t* outUsageMask) |
| 219 | { |
| 220 | int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle, |
| 221 | outUsageMask); |
| 222 | return static_cast<Error>(error); |
| 223 | } |
| 224 | |
| 225 | Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle, |
| 226 | BackingStore* outStore) |
| 227 | { |
| 228 | int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle, |
| 229 | outStore); |
| 230 | return static_cast<Error>(error); |
| 231 | } |
| 232 | |
| 233 | Error GrallocDevice::getStride(const native_handle_t* bufferHandle, |
| 234 | uint32_t* outStride) |
| 235 | { |
| 236 | int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride); |
| 237 | return static_cast<Error>(error); |
| 238 | } |
| 239 | |
| 240 | Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle, |
| 241 | uint32_t* outNumPlanes) |
| 242 | { |
| 243 | int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle, |
| 244 | outNumPlanes); |
| 245 | return static_cast<Error>(error); |
| 246 | } |
| 247 | |
| 248 | Error GrallocDevice::lock(const native_handle_t* bufferHandle, |
| 249 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 250 | const Rect* accessRegion, int32_t acquireFence, |
| 251 | void** outData) |
| 252 | { |
| 253 | int32_t error = mDispatch.lock(mDevice, bufferHandle, |
| 254 | producerUsageMask, consumerUsageMask, |
| 255 | reinterpret_cast<const gralloc1_rect_t*>(accessRegion), |
| 256 | outData, acquireFence); |
| 257 | return static_cast<Error>(error); |
| 258 | } |
| 259 | |
| 260 | Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle, |
| 261 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 262 | const Rect* accessRegion, int32_t acquireFence, |
| 263 | FlexLayout* outFlexLayout) |
| 264 | { |
| 265 | int32_t error = mDispatch.lockFlex(mDevice, bufferHandle, |
| 266 | producerUsageMask, consumerUsageMask, |
| 267 | reinterpret_cast<const gralloc1_rect_t*>(accessRegion), |
| 268 | reinterpret_cast<android_flex_layout_t*>(outFlexLayout), |
| 269 | acquireFence); |
| 270 | return static_cast<Error>(error); |
| 271 | } |
| 272 | |
| 273 | Error GrallocDevice::unlock(const native_handle_t* bufferHandle, |
| 274 | int32_t* outReleaseFence) |
| 275 | { |
| 276 | int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence); |
| 277 | return static_cast<Error>(error); |
| 278 | } |
| 279 | |
| 280 | class GrallocMapper : public IMapper { |
| 281 | public: |
| 282 | GrallocMapper() : IMapper{ |
| 283 | .createDevice = createDevice, |
| 284 | .destroyDevice = destroyDevice, |
| 285 | .retain = retain, |
| 286 | .release = release, |
| 287 | .getDimensions = getDimensions, |
| 288 | .getFormat = getFormat, |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 289 | .getLayerCount = getLayerCount, |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 290 | .getProducerUsageMask = getProducerUsageMask, |
| 291 | .getConsumerUsageMask = getConsumerUsageMask, |
| 292 | .getBackingStore = getBackingStore, |
| 293 | .getStride = getStride, |
| 294 | .getNumFlexPlanes = getNumFlexPlanes, |
| 295 | .lock = lock, |
| 296 | .lockFlex = lockFlex, |
| 297 | .unlock = unlock, |
| 298 | } {} |
| 299 | |
| 300 | const IMapper* getInterface() const |
| 301 | { |
| 302 | return static_cast<const IMapper*>(this); |
| 303 | } |
| 304 | |
| 305 | private: |
| 306 | static GrallocDevice* cast(Device* device) |
| 307 | { |
| 308 | return reinterpret_cast<GrallocDevice*>(device); |
| 309 | } |
| 310 | |
| 311 | static Error createDevice(Device** outDevice) |
| 312 | { |
| 313 | *outDevice = new GrallocDevice; |
| 314 | return Error::NONE; |
| 315 | } |
| 316 | |
| 317 | static Error destroyDevice(Device* device) |
| 318 | { |
| 319 | delete cast(device); |
| 320 | return Error::NONE; |
| 321 | } |
| 322 | |
| 323 | static Error retain(Device* device, |
| 324 | const native_handle_t* bufferHandle) |
| 325 | { |
| 326 | return cast(device)->retain(bufferHandle); |
| 327 | } |
| 328 | |
| 329 | static Error release(Device* device, |
| 330 | const native_handle_t* bufferHandle) |
| 331 | { |
| 332 | return cast(device)->release(bufferHandle); |
| 333 | } |
| 334 | |
| 335 | static Error getDimensions(Device* device, |
| 336 | const native_handle_t* bufferHandle, |
| 337 | uint32_t* outWidth, uint32_t* outHeight) |
| 338 | { |
| 339 | return cast(device)->getDimensions(bufferHandle, outWidth, outHeight); |
| 340 | } |
| 341 | |
| 342 | static Error getFormat(Device* device, |
| 343 | const native_handle_t* bufferHandle, PixelFormat* outFormat) |
| 344 | { |
| 345 | return cast(device)->getFormat(bufferHandle, outFormat); |
| 346 | } |
| 347 | |
Craig Donner | 0b00adf | 2016-10-20 17:12:58 -0700 | [diff] [blame] | 348 | static Error getLayerCount(Device* device, |
| 349 | const native_handle_t* bufferHandle, uint32_t* outLayerCount) |
| 350 | { |
| 351 | return cast(device)->getLayerCount(bufferHandle, outLayerCount); |
| 352 | } |
| 353 | |
Chia-I Wu | 0f215c5 | 2016-10-11 11:48:21 +0800 | [diff] [blame] | 354 | static Error getProducerUsageMask(Device* device, |
| 355 | const native_handle_t* bufferHandle, uint64_t* outUsageMask) |
| 356 | { |
| 357 | return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask); |
| 358 | } |
| 359 | |
| 360 | static Error getConsumerUsageMask(Device* device, |
| 361 | const native_handle_t* bufferHandle, uint64_t* outUsageMask) |
| 362 | { |
| 363 | return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask); |
| 364 | } |
| 365 | |
| 366 | static Error getBackingStore(Device* device, |
| 367 | const native_handle_t* bufferHandle, BackingStore* outStore) |
| 368 | { |
| 369 | return cast(device)->getBackingStore(bufferHandle, outStore); |
| 370 | } |
| 371 | |
| 372 | static Error getStride(Device* device, |
| 373 | const native_handle_t* bufferHandle, uint32_t* outStride) |
| 374 | { |
| 375 | return cast(device)->getStride(bufferHandle, outStride); |
| 376 | } |
| 377 | |
| 378 | static Error getNumFlexPlanes(Device* device, |
| 379 | const native_handle_t* bufferHandle, uint32_t* outNumPlanes) |
| 380 | { |
| 381 | return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes); |
| 382 | } |
| 383 | |
| 384 | static Error lock(Device* device, |
| 385 | const native_handle_t* bufferHandle, |
| 386 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 387 | const Device::Rect* accessRegion, int32_t acquireFence, |
| 388 | void** outData) |
| 389 | { |
| 390 | return cast(device)->lock(bufferHandle, |
| 391 | producerUsageMask, consumerUsageMask, |
| 392 | accessRegion, acquireFence, outData); |
| 393 | } |
| 394 | |
| 395 | static Error lockFlex(Device* device, |
| 396 | const native_handle_t* bufferHandle, |
| 397 | uint64_t producerUsageMask, uint64_t consumerUsageMask, |
| 398 | const Device::Rect* accessRegion, int32_t acquireFence, |
| 399 | FlexLayout* outFlexLayout) |
| 400 | { |
| 401 | return cast(device)->lockFlex(bufferHandle, |
| 402 | producerUsageMask, consumerUsageMask, |
| 403 | accessRegion, acquireFence, outFlexLayout); |
| 404 | } |
| 405 | |
| 406 | static Error unlock(Device* device, |
| 407 | const native_handle_t* bufferHandle, int32_t* outReleaseFence) |
| 408 | { |
| 409 | return cast(device)->unlock(bufferHandle, outReleaseFence); |
| 410 | } |
| 411 | }; |
| 412 | |
| 413 | extern "C" const void* HALLIB_FETCH_Interface(const char* name) |
| 414 | { |
| 415 | if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) { |
| 416 | static GrallocMapper sGrallocMapper; |
| 417 | return sGrallocMapper.getInterface(); |
| 418 | } |
| 419 | |
| 420 | return nullptr; |
| 421 | } |
| 422 | |
| 423 | } // namespace implementation |
| 424 | } // namespace V2_0 |
| 425 | } // namespace mapper |
| 426 | } // namespace graphics |
| 427 | } // namespace hardware |
| 428 | } // namespace android |