• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 #pragma once
18 
19 #ifndef LOG_TAG
20 #warning "GrallocLoader.h included without LOG_TAG"
21 #endif
22 
23 #include <memory>
24 #include <mutex>
25 #include <unordered_set>
26 
27 #include <hardware/gralloc.h>
28 #include <hardware/hardware.h>
29 #include <log/log.h>
30 #include <mapper-hal/2.0/Mapper.h>
31 #include <mapper-passthrough/2.0/Gralloc0Hal.h>
32 #include <mapper-passthrough/2.0/Gralloc1Hal.h>
33 
34 namespace android {
35 namespace hardware {
36 namespace graphics {
37 namespace mapper {
38 namespace V2_0 {
39 namespace passthrough {
40 
41 class GrallocImportedBufferPool {
42    public:
getInstance()43     static GrallocImportedBufferPool& getInstance() {
44         // GraphicBufferMapper in framework is expected to be valid (and
45         // leaked) during process termination.  We need to make sure IMapper,
46         // and in turn, GrallocImportedBufferPool is valid as well.  Create
47         // imported buffer pool on the heap (and let it leak) for the purpose.
48         // Besides, all IMapper instances must share the same pool.  Make it a
49         // singleton.
50         //
51         // However, there is no way to make sure gralloc0/gralloc1 are valid
52         // during process termination.  Any use of static/global object in
53         // gralloc0/gralloc1 that may be destructed during process termination
54         // is potentially broken.
55         static GrallocImportedBufferPool* singleton = new GrallocImportedBufferPool;
56         return *singleton;
57     }
58 
add(native_handle_t * bufferHandle)59     void* add(native_handle_t* bufferHandle) {
60         std::lock_guard<std::mutex> lock(mMutex);
61         return mBufferHandles.insert(bufferHandle).second ? bufferHandle : nullptr;
62     }
63 
remove(void * buffer)64     native_handle_t* remove(void* buffer) {
65         auto bufferHandle = static_cast<native_handle_t*>(buffer);
66 
67         std::lock_guard<std::mutex> lock(mMutex);
68         return mBufferHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
69     }
70 
get(void * buffer)71     const native_handle_t* get(void* buffer) {
72         auto bufferHandle = static_cast<const native_handle_t*>(buffer);
73 
74         std::lock_guard<std::mutex> lock(mMutex);
75         return mBufferHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr;
76     }
77 
78    private:
79     std::mutex mMutex;
80     std::unordered_set<const native_handle_t*> mBufferHandles;
81 };
82 
83 // Inherit from V2_*::hal::Mapper and override imported buffer management functions
84 template <typename T>
85 class GrallocMapper : public T {
86    protected:
addImportedBuffer(native_handle_t * bufferHandle)87     void* addImportedBuffer(native_handle_t* bufferHandle) override {
88         return GrallocImportedBufferPool::getInstance().add(bufferHandle);
89     }
90 
removeImportedBuffer(void * buffer)91     native_handle_t* removeImportedBuffer(void* buffer) override {
92         return GrallocImportedBufferPool::getInstance().remove(buffer);
93     }
94 
getImportedBuffer(void * buffer)95     const native_handle_t* getImportedBuffer(void* buffer) const override {
96         return GrallocImportedBufferPool::getInstance().get(buffer);
97     }
98 };
99 
100 class GrallocLoader {
101    public:
load()102     static IMapper* load() {
103         const hw_module_t* module = loadModule();
104         if (!module) {
105             return nullptr;
106         }
107         auto hal = createHal(module);
108         if (!hal) {
109             return nullptr;
110         }
111         return createMapper(std::move(hal));
112     }
113 
114     // load the gralloc module
loadModule()115     static const hw_module_t* loadModule() {
116         const hw_module_t* module;
117         int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
118         if (error) {
119             ALOGE("failed to get gralloc module");
120             return nullptr;
121         }
122 
123         return module;
124     }
125 
126     // return the major api version of the module
getModuleMajorApiVersion(const hw_module_t * module)127     static int getModuleMajorApiVersion(const hw_module_t* module) {
128         return (module->module_api_version >> 8) & 0xff;
129     }
130 
131     // create a MapperHal instance
createHal(const hw_module_t * module)132     static std::unique_ptr<hal::MapperHal> createHal(const hw_module_t* module) {
133         int major = getModuleMajorApiVersion(module);
134         switch (major) {
135             case 1: {
136                 auto hal = std::make_unique<Gralloc1Hal>();
137                 return hal->initWithModule(module) ? std::move(hal) : nullptr;
138             }
139             case 0: {
140                 auto hal = std::make_unique<Gralloc0Hal>();
141                 return hal->initWithModule(module) ? std::move(hal) : nullptr;
142             }
143             default:
144                 ALOGE("unknown gralloc module major version %d", major);
145                 return nullptr;
146         }
147     }
148 
149     // create an IAllocator instance
createMapper(std::unique_ptr<hal::MapperHal> hal)150     static IMapper* createMapper(std::unique_ptr<hal::MapperHal> hal) {
151         auto mapper = std::make_unique<GrallocMapper<hal::Mapper>>();
152         return mapper->init(std::move(hal)) ? mapper.release() : nullptr;
153     }
154 };
155 
156 }  // namespace passthrough
157 }  // namespace V2_0
158 }  // namespace mapper
159 }  // namespace graphics
160 }  // namespace hardware
161 }  // namespace android
162