blob: 0083f58aca8603248eba58343b86f09fea6bd2d1 [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
Dan Stoza41b12612016-05-20 12:14:37 -0700143static inline bool allocationSucceded(gralloc1_error_t error)
144{
145 return error == GRALLOC1_ERROR_NONE || error == GRALLOC1_ERROR_NOT_SHARED;
146}
147
148gralloc1_error_t Device::allocate(
149 const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
150 std::vector<buffer_handle_t>* outBuffers)
151{
152 if (mFunctions.allocate.pfn == nullptr) {
153 // Allocation is not supported on this device
154 return GRALLOC1_ERROR_UNSUPPORTED;
155 }
156
157 std::vector<gralloc1_buffer_descriptor_t> deviceIds;
158 for (const auto& descriptor : descriptors) {
159 deviceIds.emplace_back(descriptor->getDeviceId());
160 }
161
162 std::vector<buffer_handle_t> buffers(descriptors.size());
163 int32_t intError = mFunctions.allocate(mDevice,
164 static_cast<uint32_t>(descriptors.size()), deviceIds.data(),
165 buffers.data());
166 auto error = static_cast<gralloc1_error_t>(intError);
167 if (allocationSucceded(error)) {
168 *outBuffers = std::move(buffers);
169 }
170
171 return error;
172}
173
174gralloc1_error_t Device::allocate(
175 const std::shared_ptr<const Descriptor>& descriptor,
176 gralloc1_backing_store_t id, buffer_handle_t* outBuffer)
177{
178 gralloc1_error_t error = GRALLOC1_ERROR_NONE;
179
180 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
181 buffer_handle_t buffer = nullptr;
182 int32_t intError = mFunctions.allocateWithId(mDevice,
183 descriptor->getDeviceId(), id, &buffer);
184 error = static_cast<gralloc1_error_t>(intError);
185 if (allocationSucceded(error)) {
186 *outBuffer = buffer;
187 }
188 } else {
189 std::vector<std::shared_ptr<const Descriptor>> descriptors;
190 descriptors.emplace_back(descriptor);
191 std::vector<buffer_handle_t> buffers;
192 error = allocate(descriptors, &buffers);
193 if (allocationSucceded(error)) {
194 *outBuffer = buffers[0];
195 }
196 }
197
198 return error;
199}
200
201gralloc1_error_t Device::retain(buffer_handle_t buffer)
202{
203 int32_t intError = mFunctions.retain(mDevice, buffer);
204 return static_cast<gralloc1_error_t>(intError);
205}
206
207gralloc1_error_t Device::retain(const GraphicBuffer* buffer)
208{
209 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
210 return mFunctions.retainGraphicBuffer(mDevice, buffer);
211 } else {
212 return retain(buffer->getNativeBuffer()->handle);
213 }
214}
215
216gralloc1_error_t Device::release(buffer_handle_t buffer)
217{
218 int32_t intError = mFunctions.release(mDevice, buffer);
219 return static_cast<gralloc1_error_t>(intError);
220}
221
Craig Donner58a1ef22017-02-02 12:40:05 -0800222gralloc1_error_t Device::getDimensions(buffer_handle_t buffer,
223 uint32_t* outWidth, uint32_t* outHeight)
224{
225 uint32_t width = 0;
226 uint32_t height = 0;
227 int32_t intError = mFunctions.getDimensions(mDevice, buffer, &width,
228 &height);
229 auto error = static_cast<gralloc1_error_t>(intError);
230 if (error == GRALLOC1_ERROR_NONE) {
231 *outWidth = width;
232 *outHeight = height;
233 }
234 return error;
235}
236
237gralloc1_error_t Device::getFormat(buffer_handle_t buffer,
238 int32_t* outFormat)
239{
240 int32_t format = 0;
241 int32_t intError = mFunctions.getFormat(mDevice, buffer, &format);
242 auto error = static_cast<gralloc1_error_t>(intError);
243 if (error == GRALLOC1_ERROR_NONE) {
244 *outFormat = format;
245 }
246 return error;
247}
248
249gralloc1_error_t Device::getLayerCount(buffer_handle_t buffer,
250 uint32_t* outLayerCount)
251{
252 if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
253 uint32_t layerCount = 0;
254 int32_t intError = mFunctions.getLayerCount(mDevice, buffer,
255 &layerCount);
256 auto error = static_cast<gralloc1_error_t>(intError);
257 if (error == GRALLOC1_ERROR_NONE) {
258 *outLayerCount = layerCount;
259 }
260 return error;
261 } else {
262 // Layered buffers are not supported on this device.
263 return GRALLOC1_ERROR_UNSUPPORTED;
264 }
265}
266
267gralloc1_error_t Device::getProducerUsage(buffer_handle_t buffer,
268 uint64_t* outProducerUsage)
269{
270 uint64_t usage = 0;
271 int32_t intError = mFunctions.getProducerUsage(mDevice, buffer, &usage);
272 auto error = static_cast<gralloc1_error_t>(intError);
273 if (error == GRALLOC1_ERROR_NONE) {
274 *outProducerUsage = usage;
275 }
276 return error;
277}
278
279gralloc1_error_t Device::getConsumerUsage(buffer_handle_t buffer,
280 uint64_t* outConsumerUsage)
281{
282 uint64_t usage = 0;
283 int32_t intError = mFunctions.getConsumerUsage(mDevice, buffer, &usage);
284 auto error = static_cast<gralloc1_error_t>(intError);
285 if (error == GRALLOC1_ERROR_NONE) {
286 *outConsumerUsage = usage;
287 }
288 return error;
289}
290
291gralloc1_error_t Device::getBackingStore(buffer_handle_t buffer,
292 uint64_t* outBackingStore)
293{
294 uint64_t store = 0;
295 int32_t intError = mFunctions.getBackingStore(mDevice, buffer, &store);
296 auto error = static_cast<gralloc1_error_t>(intError);
297 if (error == GRALLOC1_ERROR_NONE) {
298 *outBackingStore = store;
299 }
300 return error;
301}
302
303gralloc1_error_t Device::getStride(buffer_handle_t buffer,
304 uint32_t* outStride)
305{
306 uint32_t stride = 0;
307 int32_t intError = mFunctions.getStride(mDevice, buffer, &stride);
308 auto error = static_cast<gralloc1_error_t>(intError);
309 if (error == GRALLOC1_ERROR_NONE) {
310 *outStride = stride;
311 }
312 return error;
313}
314
Dan Stoza41b12612016-05-20 12:14:37 -0700315gralloc1_error_t Device::getNumFlexPlanes(buffer_handle_t buffer,
316 uint32_t* outNumPlanes)
317{
318 uint32_t numPlanes = 0;
319 int32_t intError = mFunctions.getNumFlexPlanes(mDevice, buffer, &numPlanes);
320 auto error = static_cast<gralloc1_error_t>(intError);
321 if (error == GRALLOC1_ERROR_NONE) {
322 *outNumPlanes = numPlanes;
323 }
324 return error;
325}
326
327gralloc1_error_t Device::lock(buffer_handle_t buffer,
328 gralloc1_producer_usage_t producerUsage,
329 gralloc1_consumer_usage_t consumerUsage,
330 const gralloc1_rect_t* accessRegion, void** outData,
331 const sp<Fence>& acquireFence)
332{
333 ALOGV("Calling lock(%p)", buffer);
Craig Donner58a1ef22017-02-02 12:40:05 -0800334 return lockHelper(mFunctions.lock, buffer, producerUsage,
Dan Stoza41b12612016-05-20 12:14:37 -0700335 consumerUsage, accessRegion, outData, acquireFence);
336}
337
338gralloc1_error_t Device::lockFlex(buffer_handle_t buffer,
339 gralloc1_producer_usage_t producerUsage,
340 gralloc1_consumer_usage_t consumerUsage,
341 const gralloc1_rect_t* accessRegion,
342 struct android_flex_layout* outData,
343 const sp<Fence>& acquireFence)
344{
345 ALOGV("Calling lockFlex(%p)", buffer);
Craig Donner58a1ef22017-02-02 12:40:05 -0800346 return lockHelper(mFunctions.lockFlex, buffer, producerUsage,
Dan Stoza41b12612016-05-20 12:14:37 -0700347 consumerUsage, accessRegion, outData, acquireFence);
348}
349
350gralloc1_error_t Device::lockYCbCr(buffer_handle_t buffer,
351 gralloc1_producer_usage_t producerUsage,
352 gralloc1_consumer_usage_t consumerUsage,
353 const gralloc1_rect_t* accessRegion,
354 struct android_ycbcr* outData,
355 const sp<Fence>& acquireFence)
356{
357 ALOGV("Calling lockYCbCr(%p)", buffer);
Craig Donner58a1ef22017-02-02 12:40:05 -0800358 return lockHelper(mFunctions.lockYCbCr, buffer, producerUsage,
Dan Stoza41b12612016-05-20 12:14:37 -0700359 consumerUsage, accessRegion, outData, acquireFence);
360}
361
362gralloc1_error_t Device::unlock(buffer_handle_t buffer, sp<Fence>* outFence)
363{
364 int32_t fenceFd = -1;
365 int32_t intError = mFunctions.unlock(mDevice, buffer, &fenceFd);
366 auto error = static_cast<gralloc1_error_t>(intError);
367 if (error == GRALLOC1_ERROR_NONE) {
368 *outFence = new Fence(fenceFd);
369 }
370 return error;
371}
372
373std::unordered_set<gralloc1_capability_t> Device::loadCapabilities()
374{
375 std::vector<int32_t> intCapabilities;
376 uint32_t numCapabilities = 0;
377 mDevice->getCapabilities(mDevice, &numCapabilities, nullptr);
378
379 intCapabilities.resize(numCapabilities);
380 mDevice->getCapabilities(mDevice, &numCapabilities, intCapabilities.data());
381
382 std::unordered_set<gralloc1_capability_t> capabilities;
383 for (const auto intCapability : intCapabilities) {
384 capabilities.emplace(static_cast<gralloc1_capability_t>(intCapability));
385 }
386 return capabilities;
387}
388
389bool Device::loadFunctions()
390{
391 // Functions which must always be present
392 if (!mFunctions.dump.load(mDevice, true)) {
393 return false;
394 }
395 if (!mFunctions.createDescriptor.load(mDevice, true)) {
396 return false;
397 }
398 if (!mFunctions.destroyDescriptor.load(mDevice, true)) {
399 return false;
400 }
401 if (!mFunctions.setConsumerUsage.load(mDevice, true)) {
402 return false;
403 }
404 if (!mFunctions.setDimensions.load(mDevice, true)) {
405 return false;
406 }
407 if (!mFunctions.setFormat.load(mDevice, true)) {
408 return false;
409 }
410 if (!mFunctions.setProducerUsage.load(mDevice, true)) {
411 return false;
412 }
413 if (!mFunctions.getBackingStore.load(mDevice, true)) {
414 return false;
415 }
416 if (!mFunctions.getConsumerUsage.load(mDevice, true)) {
417 return false;
418 }
419 if (!mFunctions.getDimensions.load(mDevice, true)) {
420 return false;
421 }
422 if (!mFunctions.getFormat.load(mDevice, true)) {
423 return false;
424 }
425 if (!mFunctions.getProducerUsage.load(mDevice, true)) {
426 return false;
427 }
428 if (!mFunctions.getStride.load(mDevice, true)) {
429 return false;
430 }
431 if (!mFunctions.retain.load(mDevice, true)) {
432 return false;
433 }
434 if (!mFunctions.release.load(mDevice, true)) {
435 return false;
436 }
437 if (!mFunctions.getNumFlexPlanes.load(mDevice, true)) {
438 return false;
439 }
440 if (!mFunctions.lock.load(mDevice, true)) {
441 return false;
442 }
443 if (!mFunctions.lockFlex.load(mDevice, true)) {
444 return false;
445 }
446 if (!mFunctions.unlock.load(mDevice, true)) {
447 return false;
448 }
449
450 if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
451 // These should always be present on the adapter
452 if (!mFunctions.retainGraphicBuffer.load(mDevice, true)) {
453 return false;
454 }
455 if (!mFunctions.lockYCbCr.load(mDevice, true)) {
456 return false;
457 }
458
459 // allocateWithId may not be present if we're only able to map in this
460 // process
461 mFunctions.allocateWithId.load(mDevice, false);
462 } else {
463 // allocate may not be present if we're only able to map in this process
464 mFunctions.allocate.load(mDevice, false);
465 }
466
Craig Donner6ebc46a2016-10-21 15:23:44 -0700467 if (hasCapability(GRALLOC1_CAPABILITY_LAYERED_BUFFERS)) {
468 if (!mFunctions.setLayerCount.load(mDevice, true)) {
469 return false;
470 }
471 if (!mFunctions.getLayerCount.load(mDevice, true)) {
472 return false;
473 }
474 }
475
Dan Stoza41b12612016-05-20 12:14:37 -0700476 return true;
477}
478
479std::unique_ptr<Gralloc1On0Adapter> Loader::mAdapter = nullptr;
480
481Loader::Loader()
482 : mDevice(nullptr)
483{
484 hw_module_t const* module;
485 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
486 uint8_t majorVersion = (module->module_api_version >> 8) & 0xFF;
487 uint8_t minorVersion = module->module_api_version & 0xFF;
488 gralloc1_device_t* device = nullptr;
489 if (majorVersion == 1) {
490 gralloc1_open(module, &device);
491 } else {
492 if (!mAdapter) {
493 mAdapter = std::make_unique<Gralloc1On0Adapter>(module);
494 }
495 device = mAdapter->getDevice();
496 }
497 mDevice = std::make_unique<Gralloc1::Device>(device);
498}
499
500Loader::~Loader() {}
501
502std::unique_ptr<Device> Loader::getDevice()
503{
504 return std::move(mDevice);
505}
506
507} // namespace android::Gralloc1
508
509} // namespace android