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