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>
CallBufferDescriptorFunction(gralloc1_buffer_descriptor_t descriptor_id,void (BufferDescriptor::* member)(Args...),Args...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 
GetInstance()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):
handleBuffer107         handle(h),
108         ion_handle_main(ih_main),
109         ion_handle_meta(ih_meta) {
110     }
IncRefBuffer111     void IncRef() { ++ref_count; }
DecRefBuffer112     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   Allocator *allocator_ = NULL;
122   std::mutex buffer_lock_;
123   std::mutex descriptor_lock_;
124   // TODO(user): The private_handle_t is used as a key because the unique ID generated
125   // from next_id_ is not unique across processes. The correct way to resolve this would
126   // be to use the allocator over hwbinder
127   std::unordered_map<const private_handle_t*, std::shared_ptr<Buffer>> handles_map_ = {};
128   std::unordered_map<gralloc1_buffer_descriptor_t,
129                      std::shared_ptr<BufferDescriptor>> descriptors_map_ = {};
130   std::atomic<uint64_t> next_id_;
131 };
132 
133 }  // namespace gralloc1
134 
135 #endif  // __GR_BUF_MGR_H__
136