blob: 367d1ce58bf8b319f791315b80470411f982629e [file] [log] [blame]
Dan Stoza41b12612016-05-20 12:14:37 -07001/*
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_NDEBUG 0
18
19#include <ui/Gralloc1.h>
20
21#include <vector>
22
23#undef LOG_TAG
24#define LOG_TAG GRALLOC1_LOG_TAG
25
26namespace android {
27
28namespace Gralloc1 {
29
30Descriptor::~Descriptor()
31{
32 int32_t intError = mShimDevice.mFunctions.destroyDescriptor(
33 mShimDevice.mDevice, mDeviceId);
34 auto error = static_cast<gralloc1_error_t>(intError);
35 if (error != GRALLOC1_ERROR_NONE) {
36 ALOGE("destroyDescriptor failed: %d", intError);
37 }
38}
39
40gralloc1_error_t Descriptor::setDimensions(uint32_t width, uint32_t height)
41{
42 int32_t intError = mShimDevice.mFunctions.setDimensions(mShimDevice.mDevice,
43 mDeviceId, width, height);
44 auto error = static_cast<gralloc1_error_t>(intError);
45 if (error != GRALLOC1_ERROR_NONE) {
46 return error;
47 }
48 mWidth = width;
49 mHeight = height;
50 return error;
51}
52
53template <typename ApiType>
54struct Setter {
55 typedef int32_t (*Type)(gralloc1_device_t*, gralloc1_buffer_descriptor_t,
56 ApiType);
57};
58
59template <typename ApiType, typename ValueType>
60static inline gralloc1_error_t setHelper(
61 typename Setter<ApiType>::Type setter, gralloc1_device_t* device,
62 gralloc1_buffer_descriptor_t id, ValueType newValue,
63 ValueType* cacheVariable)
64{
65 int32_t intError = setter(device, id, static_cast<ApiType>(newValue));
66 auto error = static_cast<gralloc1_error_t>(intError);
67 if (error != GRALLOC1_ERROR_NONE) {
68 return error;
69 }
70 *cacheVariable = newValue;
71 return error;
72}
73
74gralloc1_error_t Descriptor::setFormat(android_pixel_format_t format)
75{
76 return setHelper<int32_t>(mShimDevice.mFunctions.setFormat.pfn,
77 mShimDevice.mDevice, mDeviceId, format, &mFormat);
78}
79
Craig Donner6ebc46a2016-10-21 15:23:44 -070080gralloc1_error_t Descriptor::setLayerCount(uint32_t layerCount)
81{
82 if (mShimDevice.hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
83 return setHelper<uint32_t>(mShimDevice.mFunctions.setLayerCount.pfn,
84 mShimDevice.mDevice, mDeviceId, layerCount, &mLayerCount);
85 } else {
86 // Layered buffers are not supported on this device.
87 return GRALLOC1_ERROR_UNSUPPORTED;
88 }
89}
90
Dan Stoza41b12612016-05-20 12:14:37 -070091gralloc1_error_t Descriptor::setProducerUsage(gralloc1_producer_usage_t usage)
92{
93 return setHelper<uint64_t>(mShimDevice.mFunctions.setProducerUsage.pfn,
94 mShimDevice.mDevice, mDeviceId, usage, &mProducerUsage);
95}
96
97gralloc1_error_t Descriptor::setConsumerUsage(gralloc1_consumer_usage_t usage)
98{
99 return setHelper<uint64_t>(mShimDevice.mFunctions.setConsumerUsage.pfn,
100 mShimDevice.mDevice, mDeviceId, usage, &mConsumerUsage);
101}
102
103Device::Device(gralloc1_device_t* device)
104 : mDevice(device),
105 mCapabilities(loadCapabilities()),
106 mFunctions()
107{
108 if (!loadFunctions()) {
109 ALOGE("Failed to load a required function, aborting");
110 abort();
111 }
112}
113
114bool Device::hasCapability(gralloc1_capability_t capability) const
115{
116 return mCapabilities.count(capability) > 0;
117}
118
119std::string Device::dump()
120{
121 uint32_t length = 0;
122 mFunctions.dump(mDevice, &length, nullptr);
123
124 std::vector<char> output;
125 output.resize(length);
126 mFunctions.dump(mDevice, &length, output.data());
127
128 return std::string(output.cbegin(), output.cend());
129}
130
131std::shared_ptr<Descriptor> Device::createDescriptor()
132{
133 gralloc1_buffer_descriptor_t descriptorId;
134 int32_t intError = mFunctions.createDescriptor(mDevice, &descriptorId);
135 auto error = static_cast<gralloc1_error_t>(intError);
136 if (error != GRALLOC1_ERROR_NONE) {
137 return nullptr;
138 }
139 auto descriptor = std::make_shared<Descriptor>(*this, descriptorId);
140 return descriptor;
141}
142
143gralloc1_error_t Device::getStride(buffer_handle_t buffer, uint32_t* outStride)
144{
145 int32_t intError = mFunctions.getStride(mDevice, buffer, outStride);
146 return static_cast<gralloc1_error_t>(intError);
147}
148
149static inline bool allocationSucceded(gralloc1_error_t error)
150{
151 return error == GRALLOC1_ERROR_NONE || error == GRALLOC1_ERROR_NOT_SHARED;
152}
153
154gralloc1_error_t Device::allocate(
155 const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
156 std::vector<buffer_handle_t>* outBuffers)
157{
158 if (mFunctions.allocate.pfn == nullptr) {
159 // Allocation is not supported on this device
160 return GRALLOC1_ERROR_UNSUPPORTED;
161 }
162
163 std::vector<gralloc1_buffer_descriptor_t> deviceIds;
164 for (const auto& descriptor : descriptors) {
165 deviceIds.emplace_back(descriptor->getDeviceId());
166 }
167
168 std::vector<buffer_handle_t> buffers(descriptors.size());
169 int32_t intError = mFunctions.allocate(mDevice,
170 static_cast<uint32_t>(descriptors.size()), deviceIds.data(),
171 buffers.data());
172 auto error = static_cast<gralloc1_error_t>(intError);
173 if (allocationSucceded(error)) {
174 *outBuffers = std::move(buffers);
175 }
176
177 return error;
178}
179
180gralloc1_error_t Device::allocate(
181 const std::shared_ptr<const Descriptor>& descriptor,
182 gralloc1_backing_store_t id, buffer_handle_t* outBuffer)
183{
184 gralloc1_error_t error = GRALLOC1_ERROR_NONE;
185
186 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
187 buffer_handle_t buffer = nullptr;
188 int32_t intError = mFunctions.allocateWithId(mDevice,
189 descriptor->getDeviceId(), id, &buffer);
190 error = static_cast<gralloc1_error_t>(intError);
191 if (allocationSucceded(error)) {
192 *outBuffer = buffer;
193 }
194 } else {
195 std::vector<std::shared_ptr<const Descriptor>> descriptors;
196 descriptors.emplace_back(descriptor);
197 std::vector<buffer_handle_t> buffers;
198 error = allocate(descriptors, &buffers);
199 if (allocationSucceded(error)) {
200 *outBuffer = buffers[0];
201 }
202 }
203
204 return error;
205}
206
207gralloc1_error_t Device::retain(buffer_handle_t buffer)
208{
209 int32_t intError = mFunctions.retain(mDevice, buffer);
210 return static_cast<gralloc1_error_t>(intError);
211}
212
213gralloc1_error_t Device::retain(const GraphicBuffer* buffer)
214{
215 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
216 return mFunctions.retainGraphicBuffer(mDevice, buffer);
217 } else {
218 return retain(buffer->getNativeBuffer()->handle);
219 }
220}
221
222gralloc1_error_t Device::release(buffer_handle_t buffer)
223{
224 int32_t intError = mFunctions.release(mDevice, buffer);
225 return static_cast<gralloc1_error_t>(intError);
226}
227
228gralloc1_error_t Device::getNumFlexPlanes(buffer_handle_t buffer,
229 uint32_t* outNumPlanes)
230{
231 uint32_t numPlanes = 0;
232 int32_t intError = mFunctions.getNumFlexPlanes(mDevice, buffer, &numPlanes);
233 auto error = static_cast<gralloc1_error_t>(intError);
234 if (error == GRALLOC1_ERROR_NONE) {
235 *outNumPlanes = numPlanes;
236 }
237 return error;
238}
239
240gralloc1_error_t Device::lock(buffer_handle_t buffer,
241 gralloc1_producer_usage_t producerUsage,
242 gralloc1_consumer_usage_t consumerUsage,
243 const gralloc1_rect_t* accessRegion, void** outData,
244 const sp<Fence>& acquireFence)
245{
246 ALOGV("Calling lock(%p)", buffer);
247 return lockHelper(mFunctions.lock.pfn, buffer, producerUsage,
248 consumerUsage, accessRegion, outData, acquireFence);
249}
250
251gralloc1_error_t Device::lockFlex(buffer_handle_t buffer,
252 gralloc1_producer_usage_t producerUsage,
253 gralloc1_consumer_usage_t consumerUsage,
254 const gralloc1_rect_t* accessRegion,
255 struct android_flex_layout* outData,
256 const sp<Fence>& acquireFence)
257{
258 ALOGV("Calling lockFlex(%p)", buffer);
259 return lockHelper(mFunctions.lockFlex.pfn, buffer, producerUsage,
260 consumerUsage, accessRegion, outData, acquireFence);
261}
262
263gralloc1_error_t Device::lockYCbCr(buffer_handle_t buffer,
264 gralloc1_producer_usage_t producerUsage,
265 gralloc1_consumer_usage_t consumerUsage,
266 const gralloc1_rect_t* accessRegion,
267 struct android_ycbcr* outData,
268 const sp<Fence>& acquireFence)
269{
270 ALOGV("Calling lockYCbCr(%p)", buffer);
271 return lockHelper(mFunctions.lockYCbCr.pfn, buffer, producerUsage,
272 consumerUsage, accessRegion, outData, acquireFence);
273}
274
275gralloc1_error_t Device::unlock(buffer_handle_t buffer, sp<Fence>* outFence)
276{
277 int32_t fenceFd = -1;
278 int32_t intError = mFunctions.unlock(mDevice, buffer, &fenceFd);
279 auto error = static_cast<gralloc1_error_t>(intError);
280 if (error == GRALLOC1_ERROR_NONE) {
281 *outFence = new Fence(fenceFd);
282 }
283 return error;
284}
285
286std::unordered_set<gralloc1_capability_t> Device::loadCapabilities()
287{
288 std::vector<int32_t> intCapabilities;
289 uint32_t numCapabilities = 0;
290 mDevice->getCapabilities(mDevice, &numCapabilities, nullptr);
291
292 intCapabilities.resize(numCapabilities);
293 mDevice->getCapabilities(mDevice, &numCapabilities, intCapabilities.data());
294
295 std::unordered_set<gralloc1_capability_t> capabilities;
296 for (const auto intCapability : intCapabilities) {
297 capabilities.emplace(static_cast<gralloc1_capability_t>(intCapability));
298 }
299 return capabilities;
300}
301
302bool Device::loadFunctions()
303{
304 // Functions which must always be present
305 if (!mFunctions.dump.load(mDevice, true)) {
306 return false;
307 }
308 if (!mFunctions.createDescriptor.load(mDevice, true)) {
309 return false;
310 }
311 if (!mFunctions.destroyDescriptor.load(mDevice, true)) {
312 return false;
313 }
314 if (!mFunctions.setConsumerUsage.load(mDevice, true)) {
315 return false;
316 }
317 if (!mFunctions.setDimensions.load(mDevice, true)) {
318 return false;
319 }
320 if (!mFunctions.setFormat.load(mDevice, true)) {
321 return false;
322 }
323 if (!mFunctions.setProducerUsage.load(mDevice, true)) {
324 return false;
325 }
326 if (!mFunctions.getBackingStore.load(mDevice, true)) {
327 return false;
328 }
329 if (!mFunctions.getConsumerUsage.load(mDevice, true)) {
330 return false;
331 }
332 if (!mFunctions.getDimensions.load(mDevice, true)) {
333 return false;
334 }
335 if (!mFunctions.getFormat.load(mDevice, true)) {
336 return false;
337 }
338 if (!mFunctions.getProducerUsage.load(mDevice, true)) {
339 return false;
340 }
341 if (!mFunctions.getStride.load(mDevice, true)) {
342 return false;
343 }
344 if (!mFunctions.retain.load(mDevice, true)) {
345 return false;
346 }
347 if (!mFunctions.release.load(mDevice, true)) {
348 return false;
349 }
350 if (!mFunctions.getNumFlexPlanes.load(mDevice, true)) {
351 return false;
352 }
353 if (!mFunctions.lock.load(mDevice, true)) {
354 return false;
355 }
356 if (!mFunctions.lockFlex.load(mDevice, true)) {
357 return false;
358 }
359 if (!mFunctions.unlock.load(mDevice, true)) {
360 return false;
361 }
362
363 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
364 // These should always be present on the adapter
365 if (!mFunctions.retainGraphicBuffer.load(mDevice, true)) {
366 return false;
367 }
368 if (!mFunctions.lockYCbCr.load(mDevice, true)) {
369 return false;
370 }
371
372 // allocateWithId may not be present if we're only able to map in this
373 // process
374 mFunctions.allocateWithId.load(mDevice, false);
375 } else {
376 // allocate may not be present if we're only able to map in this process
377 mFunctions.allocate.load(mDevice, false);
378 }
379
Craig Donner6ebc46a2016-10-21 15:23:44 -0700380 if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
381 if (!mFunctions.setLayerCount.load(mDevice, true)) {
382 return false;
383 }
384 if (!mFunctions.getLayerCount.load(mDevice, true)) {
385 return false;
386 }
387 }
388
Dan Stoza41b12612016-05-20 12:14:37 -0700389 return true;
390}
391
392std::unique_ptr<Gralloc1On0Adapter> Loader::mAdapter = nullptr;
393
394Loader::Loader()
395 : mDevice(nullptr)
396{
397 hw_module_t const* module;
398 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
399 uint8_t majorVersion = (module->module_api_version >> 8) & 0xFF;
400 uint8_t minorVersion = module->module_api_version & 0xFF;
401 gralloc1_device_t* device = nullptr;
402 if (majorVersion == 1) {
403 gralloc1_open(module, &device);
404 } else {
405 if (!mAdapter) {
406 mAdapter = std::make_unique<Gralloc1On0Adapter>(module);
407 }
408 device = mAdapter->getDevice();
409 }
410 mDevice = std::make_unique<Gralloc1::Device>(device);
411}
412
413Loader::~Loader() {}
414
415std::unique_ptr<Device> Loader::getDevice()
416{
417 return std::move(mDevice);
418}
419
420} // namespace android::Gralloc1
421
422} // namespace android