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