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