• 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 #ifndef ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
18 #define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
19 
20 #include <ui/Fence.h>
21 #include <ui/GraphicBuffer.h>
22 
23 #include <hardware/gralloc1.h>
24 
25 #include <mutex>
26 #include <string>
27 #include <unordered_map>
28 #include <vector>
29 
30 struct gralloc_module_t;
31 
32 // This is not an "official" capability (i.e., it is not found in gralloc1.h),
33 // but we will use it to detect that we are running through the adapter, which
34 // is capable of collaborating with GraphicBuffer such that queries on a
35 // buffer_handle_t succeed
36 static const auto GRALLOC1_CAPABILITY_ON_ADAPTER =
37         static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1);
38 
39 static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER =
40         static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1);
41 static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID =
42         static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2);
43 static const auto GRALLOC1_FUNCTION_LOCK_YCBCR =
44         static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3);
45 static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR;
46 
47 typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)(
48         gralloc1_device_t* device, const android::GraphicBuffer* buffer);
49 typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)(
50         gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
51         gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
52 typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)(
53         gralloc1_device_t* device, buffer_handle_t buffer,
54         uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
55         uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
56         const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr,
57         int32_t acquireFence);
58 
59 namespace android {
60 
61 class Gralloc1On0Adapter : public gralloc1_device_t
62 {
63 public:
64     Gralloc1On0Adapter(const hw_module_t* module);
65     ~Gralloc1On0Adapter();
66 
getDevice()67     gralloc1_device_t* getDevice() {
68         return static_cast<gralloc1_device_t*>(this);
69     }
70 
71 private:
getAdapter(gralloc1_device_t * device)72     static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) {
73         return static_cast<Gralloc1On0Adapter*>(device);
74     }
75 
76     // getCapabilities
77 
78     void doGetCapabilities(uint32_t* outCount,
79             int32_t* /*gralloc1_capability_t*/ outCapabilities);
getCapabilitiesHook(gralloc1_device_t * device,uint32_t * outCount,int32_t * outCapabilities)80     static void getCapabilitiesHook(gralloc1_device_t* device,
81             uint32_t* outCount,
82             int32_t* /*gralloc1_capability_t*/ outCapabilities) {
83         getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
84     };
85 
86     // getFunction
87 
88     gralloc1_function_pointer_t doGetFunction(
89             int32_t /*gralloc1_function_descriptor_t*/ descriptor);
getFunctionHook(gralloc1_device_t * device,int32_t descriptor)90     static gralloc1_function_pointer_t getFunctionHook(
91             gralloc1_device_t* device,
92             int32_t /*gralloc1_function_descriptor_t*/ descriptor) {
93         return getAdapter(device)->doGetFunction(descriptor);
94     }
95 
96     // dump
97 
98     void dump(uint32_t* outSize, char* outBuffer);
dumpHook(gralloc1_device_t * device,uint32_t * outSize,char * outBuffer)99     static void dumpHook(gralloc1_device_t* device, uint32_t* outSize,
100             char* outBuffer) {
101         return getAdapter(device)->dump(outSize, outBuffer);
102     }
103     std::string mCachedDump;
104 
105     // Buffer descriptor lifecycle functions
106 
107     class Descriptor;
108 
109     gralloc1_error_t createDescriptor(
110             gralloc1_buffer_descriptor_t* outDescriptor);
createDescriptorHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t * outDescriptor)111     static int32_t createDescriptorHook(gralloc1_device_t* device,
112             gralloc1_buffer_descriptor_t* outDescriptor) {
113         auto error = getAdapter(device)->createDescriptor(outDescriptor);
114         return static_cast<int32_t>(error);
115     }
116 
117     gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor);
destroyDescriptorHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptor)118     static int32_t destroyDescriptorHook(gralloc1_device_t* device,
119             gralloc1_buffer_descriptor_t descriptor) {
120         auto error = getAdapter(device)->destroyDescriptor(descriptor);
121         return static_cast<int32_t>(error);
122     }
123 
124     // Buffer descriptor modification functions
125 
126     struct Descriptor : public std::enable_shared_from_this<Descriptor> {
DescriptorDescriptor127         Descriptor(Gralloc1On0Adapter* adapter,
128                 gralloc1_buffer_descriptor_t id)
129           : adapter(adapter),
130             id(id),
131             width(0),
132             height(0),
133             format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
134             producerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
135             consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
136 
setDimensionsDescriptor137         gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
138             width = w;
139             height = h;
140             return GRALLOC1_ERROR_NONE;
141         }
142 
setFormatDescriptor143         gralloc1_error_t setFormat(int32_t f) {
144             format = f;
145             return GRALLOC1_ERROR_NONE;
146         }
147 
setProducerUsageDescriptor148         gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
149             producerUsage = usage;
150             return GRALLOC1_ERROR_NONE;
151         }
152 
setConsumerUsageDescriptor153         gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) {
154             consumerUsage = usage;
155             return GRALLOC1_ERROR_NONE;
156         }
157 
158         Gralloc1On0Adapter* const adapter;
159         const gralloc1_buffer_descriptor_t id;
160 
161         uint32_t width;
162         uint32_t height;
163         int32_t format;
164         gralloc1_producer_usage_t producerUsage;
165         gralloc1_consumer_usage_t consumerUsage;
166     };
167 
168     template <typename ...Args>
callDescriptorFunction(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,gralloc1_error_t (Descriptor::* member)(Args...),Args...args)169     static int32_t callDescriptorFunction(gralloc1_device_t* device,
170             gralloc1_buffer_descriptor_t descriptorId,
171             gralloc1_error_t (Descriptor::*member)(Args...), Args... args) {
172         auto descriptor = getAdapter(device)->getDescriptor(descriptorId);
173         if (!descriptor) {
174             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
175         }
176         auto error = ((*descriptor).*member)(std::forward<Args>(args)...);
177         return static_cast<int32_t>(error);
178     }
179 
setConsumerUsageHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint64_t intUsage)180     static int32_t setConsumerUsageHook(gralloc1_device_t* device,
181             gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
182         auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage);
183         return callDescriptorFunction(device, descriptorId,
184                 &Descriptor::setConsumerUsage, usage);
185     }
186 
setDimensionsHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint32_t width,uint32_t height)187     static int32_t setDimensionsHook(gralloc1_device_t* device,
188             gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
189             uint32_t height) {
190         return callDescriptorFunction(device, descriptorId,
191                 &Descriptor::setDimensions, width, height);
192     }
193 
setFormatHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,int32_t format)194     static int32_t setFormatHook(gralloc1_device_t* device,
195             gralloc1_buffer_descriptor_t descriptorId, int32_t format) {
196         return callDescriptorFunction(device, descriptorId,
197                 &Descriptor::setFormat, format);
198     }
199 
setProducerUsageHook(gralloc1_device_t * device,gralloc1_buffer_descriptor_t descriptorId,uint64_t intUsage)200     static int32_t setProducerUsageHook(gralloc1_device_t* device,
201             gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
202         auto usage = static_cast<gralloc1_producer_usage_t>(intUsage);
203         return callDescriptorFunction(device, descriptorId,
204                 &Descriptor::setProducerUsage, usage);
205     }
206 
207     // Buffer handle query functions
208 
209     class Buffer {
210     public:
211         Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
212                 const Descriptor& descriptor, uint32_t stride,
213                 bool wasAllocated);
214 
getHandle()215         buffer_handle_t getHandle() const { return mHandle; }
216 
retain()217         void retain() { ++mReferenceCount; }
218 
219         // Returns true if the reference count has dropped to 0, indicating that
220         // the buffer needs to be released
release()221         bool release() { return --mReferenceCount == 0; }
222 
wasAllocated()223         bool wasAllocated() const { return mWasAllocated; }
224 
getBackingStore(gralloc1_backing_store_t * outStore)225         gralloc1_error_t getBackingStore(
226                 gralloc1_backing_store_t* outStore) const {
227             *outStore = mStore;
228             return GRALLOC1_ERROR_NONE;
229         }
230 
getConsumerUsage(gralloc1_consumer_usage_t * outUsage)231         gralloc1_error_t getConsumerUsage(
232                 gralloc1_consumer_usage_t* outUsage) const {
233             *outUsage = mDescriptor.consumerUsage;
234             return GRALLOC1_ERROR_NONE;
235         }
236 
getDimensions(uint32_t * outWidth,uint32_t * outHeight)237         gralloc1_error_t getDimensions(uint32_t* outWidth,
238                 uint32_t* outHeight) const {
239             *outWidth = mDescriptor.width;
240             *outHeight = mDescriptor.height;
241             return GRALLOC1_ERROR_NONE;
242         }
243 
getFormat(int32_t * outFormat)244         gralloc1_error_t getFormat(int32_t* outFormat) const {
245             *outFormat = mDescriptor.format;
246             return GRALLOC1_ERROR_NONE;
247         }
248 
getNumFlexPlanes(uint32_t * outNumPlanes)249         gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
250             // TODO: This is conservative, and we could do better by examining
251             // the format, but it won't hurt anything for now
252             *outNumPlanes = 4;
253             return GRALLOC1_ERROR_NONE;
254         }
255 
getProducerUsage(gralloc1_producer_usage_t * outUsage)256         gralloc1_error_t getProducerUsage(
257                 gralloc1_producer_usage_t* outUsage) const {
258             *outUsage = mDescriptor.producerUsage;
259             return GRALLOC1_ERROR_NONE;
260         }
261 
getStride(uint32_t * outStride)262         gralloc1_error_t getStride(uint32_t* outStride) const {
263             *outStride = mStride;
264             return GRALLOC1_ERROR_NONE;
265         }
266 
267     private:
268 
269         const buffer_handle_t mHandle;
270         size_t mReferenceCount;
271 
272         // Since we're adapting to gralloc0, there will always be a 1:1
273         // correspondence between buffer handles and backing stores, and the
274         // backing store ID will be the same as the GraphicBuffer unique ID
275         const gralloc1_backing_store_t mStore;
276 
277         const Descriptor mDescriptor;
278         const uint32_t mStride;
279 
280         // Whether this buffer allocated in this process (as opposed to just
281         // being retained here), which determines whether to free or unregister
282         // the buffer when this Buffer is released
283         const bool mWasAllocated;
284     };
285 
286     template <typename ...Args>
callBufferFunction(gralloc1_device_t * device,buffer_handle_t bufferHandle,gralloc1_error_t (Buffer::* member)(Args...)const,Args...args)287     static int32_t callBufferFunction(gralloc1_device_t* device,
288             buffer_handle_t bufferHandle,
289             gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) {
290         auto buffer = getAdapter(device)->getBuffer(bufferHandle);
291         if (!buffer) {
292             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
293         }
294         auto error = ((*buffer).*member)(std::forward<Args>(args)...);
295         return static_cast<int32_t>(error);
296     }
297 
298     template <typename MF, MF memFunc, typename ...Args>
bufferHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,Args...args)299     static int32_t bufferHook(gralloc1_device_t* device,
300             buffer_handle_t bufferHandle, Args... args) {
301         return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle,
302                 memFunc, std::forward<Args>(args)...);
303     }
304 
getConsumerUsageHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t * outUsage)305     static int32_t getConsumerUsageHook(gralloc1_device_t* device,
306             buffer_handle_t bufferHandle, uint64_t* outUsage) {
307         auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
308         auto error = callBufferFunction(device, bufferHandle,
309                 &Buffer::getConsumerUsage, &usage);
310         if (error != GRALLOC1_ERROR_NONE) {
311             *outUsage = static_cast<uint64_t>(usage);
312         }
313         return error;
314     }
315 
getProducerUsageHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t * outUsage)316     static int32_t getProducerUsageHook(gralloc1_device_t* device,
317             buffer_handle_t bufferHandle, uint64_t* outUsage) {
318         auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
319         auto error = callBufferFunction(device, bufferHandle,
320                 &Buffer::getProducerUsage, &usage);
321         if (error != GRALLOC1_ERROR_NONE) {
322             *outUsage = static_cast<uint64_t>(usage);
323         }
324         return error;
325     }
326 
327     // Buffer management functions
328 
329     // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be
330     // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID
331     gralloc1_error_t allocate(
332             const std::shared_ptr<Descriptor>& descriptor,
333             gralloc1_backing_store_t id,
334             buffer_handle_t* outBufferHandle);
335     static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device,
336             gralloc1_buffer_descriptor_t descriptors,
337             gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
338 
339     gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
340     gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
341 
342     // Member function pointer 'member' will either be retain or release
343     template <gralloc1_error_t (Gralloc1On0Adapter::*member)(
344             const std::shared_ptr<Buffer>& buffer)>
managementHook(gralloc1_device_t * device,buffer_handle_t bufferHandle)345     static int32_t managementHook(gralloc1_device_t* device,
346             buffer_handle_t bufferHandle) {
347         auto adapter = getAdapter(device);
348 
349         auto buffer = adapter->getBuffer(bufferHandle);
350         if (!buffer) {
351             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
352         }
353 
354         auto error = ((*adapter).*member)(buffer);
355         return static_cast<int32_t>(error);
356     }
357 
358     gralloc1_error_t retain(const GraphicBuffer* buffer);
retainGraphicBufferHook(gralloc1_device_t * device,const GraphicBuffer * buffer)359     static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device,
360             const GraphicBuffer* buffer) {
361         auto adapter = getAdapter(device);
362         return adapter->retain(buffer);
363     }
364 
365     // Buffer access functions
366 
367     gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
368             gralloc1_producer_usage_t producerUsage,
369             gralloc1_consumer_usage_t consumerUsage,
370             const gralloc1_rect_t& accessRegion, void** outData,
371             const sp<Fence>& acquireFence);
372     gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
373             gralloc1_producer_usage_t producerUsage,
374             gralloc1_consumer_usage_t consumerUsage,
375             const gralloc1_rect_t& accessRegion,
376             struct android_flex_layout* outFlex,
377             const sp<Fence>& acquireFence);
378     gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer,
379             gralloc1_producer_usage_t producerUsage,
380             gralloc1_consumer_usage_t consumerUsage,
381             const gralloc1_rect_t& accessRegion,
382             struct android_ycbcr* outFlex,
383             const sp<Fence>& acquireFence);
384 
385     template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
386             const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
387             gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
388             const sp<Fence>&)>
lockHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,uint64_t uintProducerUsage,uint64_t uintConsumerUsage,const gralloc1_rect_t * accessRegion,OUT * outData,int32_t acquireFenceFd)389     static int32_t lockHook(gralloc1_device_t* device,
390             buffer_handle_t bufferHandle,
391             uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
392             uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage,
393             const gralloc1_rect_t* accessRegion, OUT* outData,
394             int32_t acquireFenceFd) {
395         auto adapter = getAdapter(device);
396 
397         // Exactly one of producer and consumer usage must be *_USAGE_NONE,
398         // but we can't check this until the upper levels of the framework
399         // correctly distinguish between producer and consumer usage
400         /*
401         bool hasProducerUsage =
402                 uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE;
403         bool hasConsumerUsage =
404                 uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE;
405         if (hasProducerUsage && hasConsumerUsage ||
406                 !hasProducerUsage && !hasConsumerUsage) {
407             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
408         }
409         */
410 
411         auto producerUsage =
412                 static_cast<gralloc1_producer_usage_t>(uintProducerUsage);
413         auto consumerUsage =
414                 static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage);
415 
416         if (!outData) {
417             const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ |
418                     GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
419             if (producerUsage & producerCpuUsage != 0) {
420                 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
421             }
422             if (consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ != 0) {
423                 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
424             }
425         }
426 
427         auto buffer = adapter->getBuffer(bufferHandle);
428         if (!buffer) {
429             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
430         }
431 
432         if (!accessRegion) {
433             ALOGE("accessRegion is null");
434             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
435         }
436 
437         sp<Fence> acquireFence{new Fence(acquireFenceFd)};
438         auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
439                 *accessRegion, outData, acquireFence);
440         return static_cast<int32_t>(error);
441     }
442 
443     gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
444             sp<Fence>* outReleaseFence);
unlockHook(gralloc1_device_t * device,buffer_handle_t bufferHandle,int32_t * outReleaseFenceFd)445     static int32_t unlockHook(gralloc1_device_t* device,
446             buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
447         auto adapter = getAdapter(device);
448 
449         auto buffer = adapter->getBuffer(bufferHandle);
450         if (!buffer) {
451             return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
452         }
453 
454         sp<Fence> releaseFence = Fence::NO_FENCE;
455         auto error = adapter->unlock(buffer, &releaseFence);
456         if (error == GRALLOC1_ERROR_NONE) {
457             *outReleaseFenceFd = releaseFence->dup();
458         }
459         return static_cast<int32_t>(error);
460     }
461 
462     // Adapter internals
463     const gralloc_module_t* mModule;
464     uint8_t mMinorVersion;
465     alloc_device_t* mDevice;
466 
467     std::shared_ptr<Descriptor> getDescriptor(
468             gralloc1_buffer_descriptor_t descriptorId);
469     std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle);
470 
471     static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId;
472     std::mutex mDescriptorMutex;
473     std::unordered_map<gralloc1_buffer_descriptor_t,
474             std::shared_ptr<Descriptor>> mDescriptors;
475     std::mutex mBufferMutex;
476     std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
477 };
478 
479 } // namespace android
480 
481 #endif
482