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