• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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