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 #pragma once 18 19 #ifndef LOG_TAG 20 #warning "Gralloc1Hal.h included without LOG_TAG" 21 #endif 22 23 #include <cstring> // for strerror 24 25 #include <allocator-hal/2.0/AllocatorHal.h> 26 #include <hardware/gralloc1.h> 27 #include <log/log.h> 28 #include <mapper-passthrough/2.0/GrallocBufferDescriptor.h> 29 30 namespace android { 31 namespace hardware { 32 namespace graphics { 33 namespace allocator { 34 namespace V2_0 { 35 namespace passthrough { 36 37 namespace detail { 38 39 using common::V1_0::BufferUsage; 40 using mapper::V2_0::BufferDescriptor; 41 using mapper::V2_0::Error; 42 using mapper::V2_0::passthrough::grallocDecodeBufferDescriptor; 43 44 // Gralloc1HalImpl implements V2_*::hal::AllocatorHal on top of gralloc1 45 template <typename Hal> 46 class Gralloc1HalImpl : public Hal { 47 public: ~Gralloc1HalImpl()48 ~Gralloc1HalImpl() { 49 if (mDevice) { 50 gralloc1_close(mDevice); 51 } 52 } 53 initWithModule(const hw_module_t * module)54 bool initWithModule(const hw_module_t* module) { 55 int result = gralloc1_open(module, &mDevice); 56 if (result) { 57 ALOGE("failed to open gralloc1 device: %s", strerror(-result)); 58 mDevice = nullptr; 59 return false; 60 } 61 62 initCapabilities(); 63 if (!initDispatch()) { 64 gralloc1_close(mDevice); 65 mDevice = nullptr; 66 return false; 67 } 68 69 return true; 70 } 71 dumpDebugInfo()72 std::string dumpDebugInfo() override { 73 uint32_t len = 0; 74 mDispatch.dump(mDevice, &len, nullptr); 75 76 std::vector<char> buf(len + 1); 77 mDispatch.dump(mDevice, &len, buf.data()); 78 buf.resize(len + 1); 79 buf[len] = '\0'; 80 81 return buf.data(); 82 } 83 allocateBuffers(const BufferDescriptor & descriptor,uint32_t count,uint32_t * outStride,std::vector<const native_handle_t * > * outBuffers)84 Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride, 85 std::vector<const native_handle_t*>* outBuffers) override { 86 mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo; 87 if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) { 88 return Error::BAD_DESCRIPTOR; 89 } 90 91 gralloc1_buffer_descriptor_t desc; 92 Error error = createDescriptor(descriptorInfo, &desc); 93 if (error != Error::NONE) { 94 return error; 95 } 96 97 uint32_t stride = 0; 98 std::vector<const native_handle_t*> buffers; 99 buffers.reserve(count); 100 101 // allocate the buffers 102 for (uint32_t i = 0; i < count; i++) { 103 const native_handle_t* tmpBuffer; 104 uint32_t tmpStride; 105 error = allocateOneBuffer(desc, &tmpBuffer, &tmpStride); 106 if (error != Error::NONE) { 107 break; 108 } 109 110 buffers.push_back(tmpBuffer); 111 112 if (stride == 0) { 113 stride = tmpStride; 114 } else if (stride != tmpStride) { 115 // non-uniform strides 116 error = Error::UNSUPPORTED; 117 break; 118 } 119 } 120 121 mDispatch.destroyDescriptor(mDevice, desc); 122 123 if (error != Error::NONE) { 124 freeBuffers(buffers); 125 return error; 126 } 127 128 *outStride = stride; 129 *outBuffers = std::move(buffers); 130 131 return Error::NONE; 132 } 133 freeBuffers(const std::vector<const native_handle_t * > & buffers)134 void freeBuffers(const std::vector<const native_handle_t*>& buffers) override { 135 for (auto buffer : buffers) { 136 int32_t error = mDispatch.release(mDevice, buffer); 137 if (error != GRALLOC1_ERROR_NONE) { 138 ALOGE("failed to free buffer %p: %d", buffer, error); 139 } 140 } 141 } 142 143 protected: initCapabilities()144 virtual void initCapabilities() { 145 uint32_t count = 0; 146 mDevice->getCapabilities(mDevice, &count, nullptr); 147 148 std::vector<int32_t> capabilities(count); 149 mDevice->getCapabilities(mDevice, &count, capabilities.data()); 150 capabilities.resize(count); 151 152 for (auto capability : capabilities) { 153 if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) { 154 mCapabilities.layeredBuffers = true; 155 break; 156 } 157 } 158 } 159 160 template <typename T> initDispatch(gralloc1_function_descriptor_t desc,T * outPfn)161 bool initDispatch(gralloc1_function_descriptor_t desc, T* outPfn) { 162 auto pfn = mDevice->getFunction(mDevice, desc); 163 if (pfn) { 164 *outPfn = reinterpret_cast<T>(pfn); 165 return true; 166 } else { 167 ALOGE("failed to get gralloc1 function %d", desc); 168 return false; 169 } 170 } 171 initDispatch()172 virtual bool initDispatch() { 173 if (!initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump) || 174 !initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, &mDispatch.createDescriptor) || 175 !initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, &mDispatch.destroyDescriptor) || 176 !initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions) || 177 !initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat) || 178 !initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, &mDispatch.setConsumerUsage) || 179 !initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, &mDispatch.setProducerUsage) || 180 !initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride) || 181 !initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate) || 182 !initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release)) { 183 return false; 184 } 185 186 if (mCapabilities.layeredBuffers) { 187 if (!initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT, &mDispatch.setLayerCount)) { 188 return false; 189 } 190 } 191 192 return true; 193 } 194 toError(int32_t error)195 static Error toError(int32_t error) { 196 switch (error) { 197 case GRALLOC1_ERROR_NONE: 198 return Error::NONE; 199 case GRALLOC1_ERROR_BAD_DESCRIPTOR: 200 return Error::BAD_DESCRIPTOR; 201 case GRALLOC1_ERROR_BAD_HANDLE: 202 return Error::BAD_BUFFER; 203 case GRALLOC1_ERROR_BAD_VALUE: 204 return Error::BAD_VALUE; 205 case GRALLOC1_ERROR_NOT_SHARED: 206 return Error::NONE; // this is fine 207 case GRALLOC1_ERROR_NO_RESOURCES: 208 return Error::NO_RESOURCES; 209 case GRALLOC1_ERROR_UNDEFINED: 210 case GRALLOC1_ERROR_UNSUPPORTED: 211 default: 212 return Error::UNSUPPORTED; 213 } 214 } 215 toProducerUsage(uint64_t usage)216 static uint64_t toProducerUsage(uint64_t usage) { 217 // this is potentially broken as we have no idea which private flags 218 // should be filtered out 219 uint64_t producerUsage = usage & ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | 220 BufferUsage::CPU_WRITE_MASK | 221 BufferUsage::GPU_DATA_BUFFER); 222 223 switch (usage & BufferUsage::CPU_WRITE_MASK) { 224 case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY): 225 producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE; 226 break; 227 case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN): 228 producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN; 229 break; 230 default: 231 break; 232 } 233 234 switch (usage & BufferUsage::CPU_READ_MASK) { 235 case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY): 236 producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ; 237 break; 238 case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN): 239 producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN; 240 break; 241 default: 242 break; 243 } 244 245 // BufferUsage::GPU_DATA_BUFFER is always filtered out 246 247 return producerUsage; 248 } 249 toConsumerUsage(uint64_t usage)250 static uint64_t toConsumerUsage(uint64_t usage) { 251 // this is potentially broken as we have no idea which private flags 252 // should be filtered out 253 uint64_t consumerUsage = 254 usage & 255 ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK | 256 BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER); 257 258 switch (usage & BufferUsage::CPU_READ_MASK) { 259 case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY): 260 consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ; 261 break; 262 case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN): 263 consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN; 264 break; 265 default: 266 break; 267 } 268 269 // BufferUsage::SENSOR_DIRECT_DATA is always filtered out 270 271 if (usage & BufferUsage::GPU_DATA_BUFFER) { 272 consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER; 273 } 274 275 return consumerUsage; 276 } 277 createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo & info,gralloc1_buffer_descriptor_t * outDescriptor)278 Error createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo& info, 279 gralloc1_buffer_descriptor_t* outDescriptor) { 280 gralloc1_buffer_descriptor_t descriptor; 281 282 int32_t error = mDispatch.createDescriptor(mDevice, &descriptor); 283 284 if (error == GRALLOC1_ERROR_NONE) { 285 error = mDispatch.setDimensions(mDevice, descriptor, info.width, info.height); 286 } 287 if (error == GRALLOC1_ERROR_NONE) { 288 error = mDispatch.setFormat(mDevice, descriptor, static_cast<int32_t>(info.format)); 289 } 290 if (error == GRALLOC1_ERROR_NONE) { 291 if (mCapabilities.layeredBuffers) { 292 error = mDispatch.setLayerCount(mDevice, descriptor, info.layerCount); 293 } else if (info.layerCount > 1) { 294 error = GRALLOC1_ERROR_UNSUPPORTED; 295 } 296 } 297 if (error == GRALLOC1_ERROR_NONE) { 298 error = mDispatch.setProducerUsage(mDevice, descriptor, toProducerUsage(info.usage)); 299 } 300 if (error == GRALLOC1_ERROR_NONE) { 301 error = mDispatch.setConsumerUsage(mDevice, descriptor, toConsumerUsage(info.usage)); 302 } 303 304 if (error == GRALLOC1_ERROR_NONE) { 305 *outDescriptor = descriptor; 306 } else { 307 mDispatch.destroyDescriptor(mDevice, descriptor); 308 } 309 310 return toError(error); 311 } 312 allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor,const native_handle_t ** outBuffer,uint32_t * outStride)313 Error allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor, 314 const native_handle_t** outBuffer, uint32_t* outStride) { 315 const native_handle_t* buffer = nullptr; 316 int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer); 317 if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) { 318 return toError(error); 319 } 320 321 uint32_t stride = 0; 322 error = mDispatch.getStride(mDevice, buffer, &stride); 323 if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) { 324 mDispatch.release(mDevice, buffer); 325 return toError(error); 326 } 327 328 *outBuffer = buffer; 329 *outStride = stride; 330 331 return Error::NONE; 332 } 333 334 gralloc1_device_t* mDevice = nullptr; 335 336 struct { 337 bool layeredBuffers; 338 } mCapabilities = {}; 339 340 struct { 341 GRALLOC1_PFN_DUMP dump; 342 GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor; 343 GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor; 344 GRALLOC1_PFN_SET_DIMENSIONS setDimensions; 345 GRALLOC1_PFN_SET_FORMAT setFormat; 346 GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount; 347 GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage; 348 GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage; 349 GRALLOC1_PFN_GET_STRIDE getStride; 350 GRALLOC1_PFN_ALLOCATE allocate; 351 GRALLOC1_PFN_RELEASE release; 352 } mDispatch = {}; 353 }; 354 355 } // namespace detail 356 357 using Gralloc1Hal = detail::Gralloc1HalImpl<hal::AllocatorHal>; 358 359 } // namespace passthrough 360 } // namespace V2_0 361 } // namespace allocator 362 } // namespace graphics 363 } // namespace hardware 364 } // namespace android 365