Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 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_GRALLOC1_H |
| 18 | #define ANDROID_UI_GRALLOC1_H |
| 19 | |
| 20 | #define GRALLOC1_LOG_TAG "Gralloc1" |
| 21 | |
Mathias Agopian | fe2f54f | 2017-02-15 19:48:58 -0800 | [diff] [blame] | 22 | #include <functional> |
| 23 | #include <memory> |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 24 | #include <unordered_set> |
| 25 | |
Mathias Agopian | fe2f54f | 2017-02-15 19:48:58 -0800 | [diff] [blame] | 26 | #include <log/log.h> |
| 27 | |
| 28 | #include <ui/Fence.h> |
| 29 | |
| 30 | #include <hardware/gralloc1.h> |
| 31 | |
| 32 | |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 33 | namespace std { |
| 34 | template <> |
| 35 | struct hash<gralloc1_capability_t> { |
| 36 | size_t operator()(gralloc1_capability_t capability) const { |
| 37 | return std::hash<int32_t>()(static_cast<int32_t>(capability)); |
| 38 | } |
| 39 | }; |
| 40 | } |
| 41 | |
| 42 | namespace android { |
Mathias Agopian | fe2f54f | 2017-02-15 19:48:58 -0800 | [diff] [blame] | 43 | class GraphicBuffer; |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 44 | class Fence; |
| 45 | class GraphicBuffer; |
Mathias Agopian | fe2f54f | 2017-02-15 19:48:58 -0800 | [diff] [blame] | 46 | class Gralloc1On0Adapter; |
| 47 | } // namespace android |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 48 | |
Mathias Agopian | fe2f54f | 2017-02-15 19:48:58 -0800 | [diff] [blame] | 49 | |
| 50 | // This is not an "official" capability (i.e., it is not found in gralloc1.h), |
| 51 | // but we will use it to detect that we are running through the adapter, which |
| 52 | // is capable of collaborating with GraphicBuffer such that queries on a |
| 53 | // buffer_handle_t succeed |
| 54 | static const auto GRALLOC1_CAPABILITY_ON_ADAPTER = |
| 55 | static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1); |
| 56 | |
| 57 | static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER = |
| 58 | static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1); |
| 59 | static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID = |
| 60 | static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2); |
| 61 | static const auto GRALLOC1_FUNCTION_LOCK_YCBCR = |
| 62 | static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3); |
| 63 | static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR; |
| 64 | |
| 65 | typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)( |
| 66 | gralloc1_device_t* device, const android::GraphicBuffer* buffer); |
| 67 | typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)( |
| 68 | gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor, |
| 69 | gralloc1_backing_store_t id, buffer_handle_t* outBuffer); |
| 70 | typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)( |
| 71 | gralloc1_device_t* device, buffer_handle_t buffer, |
| 72 | uint64_t /*gralloc1_producer_usage_t*/ producerUsage, |
| 73 | uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage, |
| 74 | const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr, |
| 75 | int32_t acquireFence); |
| 76 | |
| 77 | |
| 78 | namespace android { |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 79 | namespace Gralloc1 { |
| 80 | |
| 81 | class Device; |
| 82 | |
| 83 | class Descriptor { |
| 84 | public: |
| 85 | Descriptor(Device& device, gralloc1_buffer_descriptor_t deviceId) |
| 86 | : mShimDevice(device), |
| 87 | mDeviceId(deviceId), |
| 88 | mWidth(0), |
| 89 | mHeight(0), |
| 90 | mFormat(static_cast<android_pixel_format_t>(0)), |
Craig Donner | 6ebc46a | 2016-10-21 15:23:44 -0700 | [diff] [blame] | 91 | mLayerCount(0), |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 92 | mProducerUsage(GRALLOC1_PRODUCER_USAGE_NONE), |
| 93 | mConsumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {} |
| 94 | |
| 95 | ~Descriptor(); |
| 96 | |
| 97 | gralloc1_buffer_descriptor_t getDeviceId() const { return mDeviceId; } |
| 98 | |
| 99 | gralloc1_error_t setDimensions(uint32_t width, uint32_t height); |
| 100 | gralloc1_error_t setFormat(android_pixel_format_t format); |
Craig Donner | 6ebc46a | 2016-10-21 15:23:44 -0700 | [diff] [blame] | 101 | gralloc1_error_t setLayerCount(uint32_t layerCount); |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 102 | gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage); |
| 103 | gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage); |
| 104 | |
| 105 | private: |
| 106 | Device& mShimDevice; |
| 107 | const gralloc1_buffer_descriptor_t mDeviceId; |
| 108 | |
| 109 | uint32_t mWidth; |
| 110 | uint32_t mHeight; |
| 111 | android_pixel_format_t mFormat; |
Craig Donner | 6ebc46a | 2016-10-21 15:23:44 -0700 | [diff] [blame] | 112 | uint32_t mLayerCount; |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 113 | gralloc1_producer_usage_t mProducerUsage; |
| 114 | gralloc1_consumer_usage_t mConsumerUsage; |
| 115 | |
| 116 | }; // Descriptor |
| 117 | |
| 118 | class Device { |
| 119 | friend class Gralloc1::Descriptor; |
| 120 | |
| 121 | public: |
| 122 | Device(gralloc1_device_t* device); |
| 123 | |
| 124 | bool hasCapability(gralloc1_capability_t capability) const; |
| 125 | |
| 126 | std::string dump(); |
| 127 | |
| 128 | std::shared_ptr<Descriptor> createDescriptor(); |
| 129 | |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 130 | gralloc1_error_t allocate( |
| 131 | const std::vector<std::shared_ptr<const Descriptor>>& descriptors, |
| 132 | std::vector<buffer_handle_t>* outBuffers); |
| 133 | gralloc1_error_t allocate( |
| 134 | const std::shared_ptr<const Descriptor>& descriptor, |
| 135 | gralloc1_backing_store_t id, buffer_handle_t* outBuffer); |
| 136 | |
| 137 | gralloc1_error_t retain(buffer_handle_t buffer); |
| 138 | gralloc1_error_t retain(const GraphicBuffer* buffer); |
| 139 | |
| 140 | gralloc1_error_t release(buffer_handle_t buffer); |
| 141 | |
Craig Donner | 58a1ef2 | 2017-02-02 12:40:05 -0800 | [diff] [blame] | 142 | gralloc1_error_t getDimensions(buffer_handle_t buffer, |
| 143 | uint32_t* outWidth, uint32_t* outHeight); |
| 144 | gralloc1_error_t getFormat(buffer_handle_t buffer, |
| 145 | int32_t* outFormat); |
| 146 | gralloc1_error_t getLayerCount(buffer_handle_t buffer, |
| 147 | uint32_t* outLayerCount); |
| 148 | gralloc1_error_t getProducerUsage(buffer_handle_t buffer, |
| 149 | uint64_t* outProducerUsage); |
| 150 | gralloc1_error_t getConsumerUsage(buffer_handle_t buffer, |
| 151 | uint64_t* outConsumerUsage); |
| 152 | gralloc1_error_t getBackingStore(buffer_handle_t buffer, |
| 153 | uint64_t* outBackingStore); |
| 154 | gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride); |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 155 | gralloc1_error_t getNumFlexPlanes(buffer_handle_t buffer, |
| 156 | uint32_t* outNumPlanes); |
| 157 | |
| 158 | gralloc1_error_t lock(buffer_handle_t buffer, |
| 159 | gralloc1_producer_usage_t producerUsage, |
| 160 | gralloc1_consumer_usage_t consumerUsage, |
| 161 | const gralloc1_rect_t* accessRegion, void** outData, |
| 162 | const sp<Fence>& acquireFence); |
| 163 | gralloc1_error_t lockFlex(buffer_handle_t buffer, |
| 164 | gralloc1_producer_usage_t producerUsage, |
| 165 | gralloc1_consumer_usage_t consumerUsage, |
| 166 | const gralloc1_rect_t* accessRegion, |
| 167 | struct android_flex_layout* outData, const sp<Fence>& acquireFence); |
| 168 | gralloc1_error_t lockYCbCr(buffer_handle_t buffer, |
| 169 | gralloc1_producer_usage_t producerUsage, |
| 170 | gralloc1_consumer_usage_t consumerUsage, |
| 171 | const gralloc1_rect_t* accessRegion, struct android_ycbcr* outData, |
| 172 | const sp<Fence>& acquireFence); |
| 173 | |
| 174 | gralloc1_error_t unlock(buffer_handle_t buffer, sp<Fence>* outFence); |
| 175 | |
| 176 | private: |
| 177 | std::unordered_set<gralloc1_capability_t> loadCapabilities(); |
| 178 | |
| 179 | bool loadFunctions(); |
| 180 | |
| 181 | template <typename LockType, typename OutType> |
| 182 | gralloc1_error_t lockHelper(LockType pfn, buffer_handle_t buffer, |
| 183 | gralloc1_producer_usage_t producerUsage, |
| 184 | gralloc1_consumer_usage_t consumerUsage, |
| 185 | const gralloc1_rect_t* accessRegion, OutType* outData, |
| 186 | const sp<Fence>& acquireFence) { |
| 187 | int32_t intError = pfn(mDevice, buffer, |
| 188 | static_cast<uint64_t>(producerUsage), |
| 189 | static_cast<uint64_t>(consumerUsage), accessRegion, outData, |
| 190 | acquireFence->dup()); |
| 191 | return static_cast<gralloc1_error_t>(intError); |
| 192 | } |
| 193 | |
| 194 | gralloc1_device_t* const mDevice; |
| 195 | |
| 196 | const std::unordered_set<gralloc1_capability_t> mCapabilities; |
| 197 | |
| 198 | template <typename PFN, gralloc1_function_descriptor_t descriptor> |
| 199 | struct FunctionLoader { |
| 200 | FunctionLoader() : pfn(nullptr) {} |
| 201 | |
| 202 | bool load(gralloc1_device_t* device, bool errorIfNull) { |
| 203 | gralloc1_function_pointer_t rawPointer = |
| 204 | device->getFunction(device, descriptor); |
| 205 | pfn = reinterpret_cast<PFN>(rawPointer); |
| 206 | if (errorIfNull && !rawPointer) { |
| 207 | ALOG(LOG_ERROR, GRALLOC1_LOG_TAG, |
| 208 | "Failed to load function pointer %d", descriptor); |
| 209 | } |
| 210 | return rawPointer != nullptr; |
| 211 | } |
| 212 | |
| 213 | template <typename ...Args> |
| 214 | typename std::result_of<PFN(Args...)>::type operator()(Args... args) { |
| 215 | return pfn(args...); |
| 216 | } |
| 217 | |
| 218 | PFN pfn; |
| 219 | }; |
| 220 | |
| 221 | // Function pointers |
| 222 | struct Functions { |
| 223 | FunctionLoader<GRALLOC1_PFN_DUMP, GRALLOC1_FUNCTION_DUMP> dump; |
| 224 | FunctionLoader<GRALLOC1_PFN_CREATE_DESCRIPTOR, |
| 225 | GRALLOC1_FUNCTION_CREATE_DESCRIPTOR> createDescriptor; |
| 226 | FunctionLoader<GRALLOC1_PFN_DESTROY_DESCRIPTOR, |
| 227 | GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR> destroyDescriptor; |
| 228 | FunctionLoader<GRALLOC1_PFN_SET_CONSUMER_USAGE, |
| 229 | GRALLOC1_FUNCTION_SET_CONSUMER_USAGE> setConsumerUsage; |
| 230 | FunctionLoader<GRALLOC1_PFN_SET_DIMENSIONS, |
| 231 | GRALLOC1_FUNCTION_SET_DIMENSIONS> setDimensions; |
| 232 | FunctionLoader<GRALLOC1_PFN_SET_FORMAT, |
| 233 | GRALLOC1_FUNCTION_SET_FORMAT> setFormat; |
Craig Donner | 6ebc46a | 2016-10-21 15:23:44 -0700 | [diff] [blame] | 234 | FunctionLoader<GRALLOC1_PFN_SET_LAYER_COUNT, |
| 235 | GRALLOC1_FUNCTION_SET_LAYER_COUNT> setLayerCount; |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 236 | FunctionLoader<GRALLOC1_PFN_SET_PRODUCER_USAGE, |
| 237 | GRALLOC1_FUNCTION_SET_PRODUCER_USAGE> setProducerUsage; |
| 238 | FunctionLoader<GRALLOC1_PFN_GET_BACKING_STORE, |
| 239 | GRALLOC1_FUNCTION_GET_BACKING_STORE> getBackingStore; |
| 240 | FunctionLoader<GRALLOC1_PFN_GET_CONSUMER_USAGE, |
| 241 | GRALLOC1_FUNCTION_GET_CONSUMER_USAGE> getConsumerUsage; |
| 242 | FunctionLoader<GRALLOC1_PFN_GET_DIMENSIONS, |
| 243 | GRALLOC1_FUNCTION_GET_DIMENSIONS> getDimensions; |
| 244 | FunctionLoader<GRALLOC1_PFN_GET_FORMAT, |
| 245 | GRALLOC1_FUNCTION_GET_FORMAT> getFormat; |
Craig Donner | 6ebc46a | 2016-10-21 15:23:44 -0700 | [diff] [blame] | 246 | FunctionLoader<GRALLOC1_PFN_GET_LAYER_COUNT, |
| 247 | GRALLOC1_FUNCTION_GET_LAYER_COUNT> getLayerCount; |
Dan Stoza | 41b1261 | 2016-05-20 12:14:37 -0700 | [diff] [blame] | 248 | FunctionLoader<GRALLOC1_PFN_GET_PRODUCER_USAGE, |
| 249 | GRALLOC1_FUNCTION_GET_PRODUCER_USAGE> getProducerUsage; |
| 250 | FunctionLoader<GRALLOC1_PFN_GET_STRIDE, |
| 251 | GRALLOC1_FUNCTION_GET_STRIDE> getStride; |
| 252 | FunctionLoader<GRALLOC1_PFN_ALLOCATE, |
| 253 | GRALLOC1_FUNCTION_ALLOCATE> allocate; |
| 254 | FunctionLoader<GRALLOC1_PFN_RETAIN, |
| 255 | GRALLOC1_FUNCTION_RETAIN> retain; |
| 256 | FunctionLoader<GRALLOC1_PFN_RELEASE, |
| 257 | GRALLOC1_FUNCTION_RELEASE> release; |
| 258 | FunctionLoader<GRALLOC1_PFN_GET_NUM_FLEX_PLANES, |
| 259 | GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES> getNumFlexPlanes; |
| 260 | FunctionLoader<GRALLOC1_PFN_LOCK, |
| 261 | GRALLOC1_FUNCTION_LOCK> lock; |
| 262 | FunctionLoader<GRALLOC1_PFN_LOCK_FLEX, |
| 263 | GRALLOC1_FUNCTION_LOCK_FLEX> lockFlex; |
| 264 | FunctionLoader<GRALLOC1_PFN_LOCK_YCBCR, |
| 265 | GRALLOC1_FUNCTION_LOCK_YCBCR> lockYCbCr; |
| 266 | FunctionLoader<GRALLOC1_PFN_UNLOCK, |
| 267 | GRALLOC1_FUNCTION_UNLOCK> unlock; |
| 268 | |
| 269 | // Adapter-only functions |
| 270 | FunctionLoader<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER, |
| 271 | GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER> retainGraphicBuffer; |
| 272 | FunctionLoader<GRALLOC1_PFN_ALLOCATE_WITH_ID, |
| 273 | GRALLOC1_FUNCTION_ALLOCATE_WITH_ID> allocateWithId; |
| 274 | } mFunctions; |
| 275 | |
| 276 | }; // class android::Gralloc1::Device |
| 277 | |
| 278 | class Loader |
| 279 | { |
| 280 | public: |
| 281 | Loader(); |
| 282 | ~Loader(); |
| 283 | |
| 284 | std::unique_ptr<Device> getDevice(); |
| 285 | |
| 286 | private: |
| 287 | static std::unique_ptr<Gralloc1On0Adapter> mAdapter; |
| 288 | std::unique_ptr<Device> mDevice; |
| 289 | }; |
| 290 | |
| 291 | } // namespace android::Gralloc1 |
| 292 | |
| 293 | } // namespace android |
| 294 | |
| 295 | #endif |