Home | History | Annotate | Download | only in libgralloc1
      1 /*
      2  * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
      3  * Not a Contribution
      4  *
      5  * Copyright (C) 2008 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  */
     19 
     20 #ifndef __GR_BUF_MGR_H__
     21 #define __GR_BUF_MGR_H__
     22 
     23 #include <pthread.h>
     24 #include <unordered_map>
     25 #include <unordered_set>
     26 #include <utility>
     27 #include <mutex>
     28 
     29 #include "gralloc_priv.h"
     30 #include "gr_allocator.h"
     31 #include "gr_buf_descriptor.h"
     32 
     33 namespace gralloc1 {
     34 
     35 class BufferManager {
     36  public:
     37   ~BufferManager();
     38   gralloc1_error_t CreateBufferDescriptor(gralloc1_buffer_descriptor_t *descriptor_id);
     39   gralloc1_error_t DestroyBufferDescriptor(gralloc1_buffer_descriptor_t descriptor_id);
     40   gralloc1_error_t AllocateBuffers(uint32_t num_descriptors,
     41                                    const gralloc1_buffer_descriptor_t *descriptor_ids,
     42                                    buffer_handle_t *out_buffers);
     43   gralloc1_error_t RetainBuffer(private_handle_t const *hnd);
     44   gralloc1_error_t ReleaseBuffer(private_handle_t const *hnd);
     45   gralloc1_error_t LockBuffer(const private_handle_t *hnd, gralloc1_producer_usage_t prod_usage,
     46                               gralloc1_consumer_usage_t cons_usage);
     47   gralloc1_error_t UnlockBuffer(const private_handle_t *hnd);
     48   gralloc1_error_t Perform(int operation, va_list args);
     49   gralloc1_error_t GetFlexLayout(const private_handle_t *hnd, struct android_flex_layout *layout);
     50   gralloc1_error_t GetNumFlexPlanes(const private_handle_t *hnd, uint32_t *out_num_planes);
     51   gralloc1_error_t Dump(std::ostringstream *os);
     52 
     53   template <typename... Args>
     54   gralloc1_error_t CallBufferDescriptorFunction(gralloc1_buffer_descriptor_t descriptor_id,
     55                                                 void (BufferDescriptor::*member)(Args...),
     56                                                 Args... args) {
     57     std::lock_guard<std::mutex> lock(descriptor_lock_);
     58     const auto map_descriptor = descriptors_map_.find(descriptor_id);
     59     if (map_descriptor == descriptors_map_.end()) {
     60       return GRALLOC1_ERROR_BAD_DESCRIPTOR;
     61     }
     62     const auto descriptor = map_descriptor->second;
     63     (descriptor.get()->*member)(std::forward<Args>(args)...);
     64     return GRALLOC1_ERROR_NONE;
     65   }
     66 
     67   static BufferManager* GetInstance() {
     68     static BufferManager *instance = new BufferManager();
     69     return instance;
     70   }
     71 
     72  private:
     73   BufferManager();
     74   gralloc1_error_t MapBuffer(private_handle_t const *hnd);
     75   int GetBufferType(int format);
     76   int AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
     77                      unsigned int bufferSize = 0);
     78   uint32_t GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
     79                        gralloc1_consumer_usage_t cons_usage);
     80   int GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
     81                      gralloc1_consumer_usage_t cons_usage);
     82   void CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
     83                           buffer_handle_t *out_buffer);
     84 
     85   // Imports the ion fds into the current process. Returns an error for invalid handles
     86   gralloc1_error_t ImportHandleLocked(private_handle_t *hnd);
     87 
     88   // Creates a Buffer from the valid private handle and adds it to the map
     89   void RegisterHandleLocked(const private_handle_t *hnd, int ion_handle, int ion_handle_meta);
     90 
     91   // Wrapper structure over private handle
     92   // Values associated with the private handle
     93   // that do not need to go over IPC can be placed here
     94   // This structure is also not expected to be ABI stable
     95   // unlike private_handle_t
     96   struct Buffer {
     97     const private_handle_t *handle = nullptr;
     98     int ref_count = 1;
     99     // Hold the main and metadata ion handles
    100     // Freed from the allocator process
    101     // and unused in the mapping process
    102     int ion_handle_main = -1;
    103     int ion_handle_meta = -1;
    104 
    105     Buffer() = delete;
    106     explicit Buffer(const private_handle_t* h, int ih_main = -1, int ih_meta = -1):
    107         handle(h),
    108         ion_handle_main(ih_main),
    109         ion_handle_meta(ih_meta) {
    110     }
    111     void IncRef() { ++ref_count; }
    112     bool DecRef() { return --ref_count == 0; }
    113   };
    114 
    115   gralloc1_error_t FreeBuffer(std::shared_ptr<Buffer> buf);
    116 
    117   // Get the wrapper Buffer object from the handle, returns nullptr if handle is not found
    118   std::shared_ptr<Buffer> GetBufferFromHandleLocked(const private_handle_t *hnd);
    119 
    120   bool map_fb_mem_ = false;
    121   bool ubwc_for_fb_ = false;
    122   Allocator *allocator_ = NULL;
    123   std::mutex buffer_lock_;
    124   std::mutex descriptor_lock_;
    125   // TODO(user): The private_handle_t is used as a key because the unique ID generated
    126   // from next_id_ is not unique across processes. The correct way to resolve this would
    127   // be to use the allocator over hwbinder
    128   std::unordered_map<const private_handle_t*, std::shared_ptr<Buffer>> handles_map_ = {};
    129   std::unordered_map<gralloc1_buffer_descriptor_t,
    130                      std::shared_ptr<BufferDescriptor>> descriptors_map_ = {};
    131   std::atomic<uint64_t> next_id_;
    132 };
    133 
    134 }  // namespace gralloc1
    135 
    136 #endif  // __GR_BUF_MGR_H__
    137