Home | History | Annotate | Download | only in ui
      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 
     67     gralloc1_device_t* getDevice() {
     68         return static_cast<gralloc1_device_t*>(this);
     69     }
     70 
     71 private:
     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);
     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);
     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);
     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);
    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);
    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> {
    127         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 
    137         gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
    138             width = w;
    139             height = h;
    140             return GRALLOC1_ERROR_NONE;
    141         }
    142 
    143         gralloc1_error_t setFormat(int32_t f) {
    144             format = f;
    145             return GRALLOC1_ERROR_NONE;
    146         }
    147 
    148         gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
    149             producerUsage = usage;
    150             return GRALLOC1_ERROR_NONE;
    151         }
    152 
    153         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>
    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 
    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 
    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 
    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 
    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 
    215         buffer_handle_t getHandle() const { return mHandle; }
    216 
    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
    221         bool release() { return --mReferenceCount == 0; }
    222 
    223         bool wasAllocated() const { return mWasAllocated; }
    224 
    225         gralloc1_error_t getBackingStore(
    226                 gralloc1_backing_store_t* outStore) const {
    227             *outStore = mStore;
    228             return GRALLOC1_ERROR_NONE;
    229         }
    230 
    231         gralloc1_error_t getConsumerUsage(
    232                 gralloc1_consumer_usage_t* outUsage) const {
    233             *outUsage = mDescriptor.consumerUsage;
    234             return GRALLOC1_ERROR_NONE;
    235         }
    236 
    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 
    244         gralloc1_error_t getFormat(int32_t* outFormat) const {
    245             *outFormat = mDescriptor.format;
    246             return GRALLOC1_ERROR_NONE;
    247         }
    248 
    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 
    256         gralloc1_error_t getProducerUsage(
    257                 gralloc1_producer_usage_t* outUsage) const {
    258             *outUsage = mDescriptor.producerUsage;
    259             return GRALLOC1_ERROR_NONE;
    260         }
    261 
    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>
    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>
    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 
    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 
    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)>
    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);
    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>&)>
    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);
    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