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
Gralloc1Allocator(const hw_module_t * module)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
~Gralloc1Allocator()51 Gralloc1Allocator::~Gralloc1Allocator() {
52 gralloc1_close(mDevice);
53 }
54
initCapabilities()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>
initDispatch(gralloc1_function_descriptor_t desc,T * outPfn)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
initDispatch()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
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)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
allocate(const BufferDescriptor & descriptor,uint32_t count,allocate_cb hidl_cb)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
toError(int32_t error)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
toProducerUsage(uint64_t usage)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
toConsumerUsage(uint64_t usage)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
createDescriptor(const IMapper::BufferDescriptorInfo & info,gralloc1_buffer_descriptor_t * outDescriptor)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
allocateOne(gralloc1_buffer_descriptor_t descriptor,buffer_handle_t * outBuffer,uint32_t * outStride)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