1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "GrallocAndroid.hpp"
16 #include "Debug.hpp"
17
18 #ifdef HAVE_GRALLOC1
19 # include <sync/sync.h>
20 #endif
21 #ifdef HAVE_GRALLOC3
22 using V3Error = android::hardware::graphics::mapper::V3_0::Error;
23 using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
24 using android::hardware::hidl_handle;
25 #endif
26 #ifdef HAVE_GRALLOC4
27 using V4Error = android::hardware::graphics::mapper::V4_0::Error;
28 using V4Mapper = android::hardware::graphics::mapper::V4_0::IMapper;
29 using android::hardware::hidl_handle;
30 #endif
31
getInstance()32 GrallocModule *GrallocModule::getInstance()
33 {
34 static GrallocModule instance;
35 return &instance;
36 }
37
GrallocModule()38 GrallocModule::GrallocModule()
39 {
40 #ifdef HAVE_GRALLOC4
41 m_gralloc4_mapper = V4Mapper::getService();
42 if(m_gralloc4_mapper != nullptr)
43 {
44 return;
45 }
46 #endif
47
48 #ifdef HAVE_GRALLOC3
49 m_gralloc3_mapper = V3Mapper::getService();
50 if(m_gralloc3_mapper != nullptr)
51 {
52 return;
53 }
54 #endif
55
56 const hw_module_t *module = nullptr;
57 hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
58
59 m_major_version = (module->module_api_version >> 8) & 0xff;
60 switch(m_major_version)
61 {
62 case 0:
63 m_module = reinterpret_cast<const gralloc_module_t *>(module);
64 break;
65 case 1:
66 #ifdef HAVE_GRALLOC1
67 gralloc1_open(module, &m_gralloc1_device);
68 m_gralloc1_lock = (GRALLOC1_PFN_LOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_LOCK);
69 m_gralloc1_unlock = (GRALLOC1_PFN_UNLOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_UNLOCK);
70 break;
71 #endif
72 default:
73 TRACE("unknown gralloc major version (%d)", m_major_version);
74 break;
75 }
76 }
77
import(buffer_handle_t handle,buffer_handle_t * imported_handle)78 int GrallocModule::import(buffer_handle_t handle, buffer_handle_t *imported_handle)
79 {
80 #ifdef HAVE_GRALLOC4
81 if(m_gralloc4_mapper != nullptr)
82 {
83 V4Error error;
84 auto ret = m_gralloc4_mapper->importBuffer(handle,
85 [&](const auto &tmp_err, const auto &tmp_buf) {
86 error = tmp_err;
87 if(error == V4Error::NONE)
88 {
89 *imported_handle = static_cast<buffer_handle_t>(tmp_buf);
90 }
91 });
92 return ret.isOk() && error == V4Error::NONE ? 0 : -1;
93 }
94 #endif
95
96 #ifdef HAVE_GRALLOC3
97 if(m_gralloc3_mapper != nullptr)
98 {
99 V3Error error;
100 auto ret = m_gralloc3_mapper->importBuffer(handle,
101 [&](const auto &tmp_err, const auto &tmp_buf) {
102 error = tmp_err;
103 if(error == V3Error::NONE)
104 {
105 *imported_handle = static_cast<buffer_handle_t>(tmp_buf);
106 }
107 });
108 return ret.isOk() && error == V3Error::NONE ? 0 : -1;
109 }
110 #endif
111
112 *imported_handle = handle;
113 return 0;
114 }
115
release(buffer_handle_t handle)116 int GrallocModule::release(buffer_handle_t handle)
117 {
118 #ifdef HAVE_GRALLOC4
119 if(m_gralloc4_mapper != nullptr)
120 {
121 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
122 return m_gralloc4_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
123 }
124 #endif
125
126 #ifdef HAVE_GRALLOC3
127 if(m_gralloc3_mapper != nullptr)
128 {
129 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
130 return m_gralloc3_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
131 }
132 #endif
133
134 return 0;
135 }
136
lock(buffer_handle_t handle,int usage,int left,int top,int width,int height,void ** vaddr)137 int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
138 {
139 #ifdef HAVE_GRALLOC4
140 if(m_gralloc4_mapper != nullptr)
141 {
142 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
143
144 V4Mapper::Rect rect;
145 rect.left = left;
146 rect.top = top;
147 rect.width = width;
148 rect.height = height;
149
150 hidl_handle empty_fence_handle;
151
152 V4Error error;
153 auto ret = m_gralloc4_mapper->lock(native_handle, usage, rect, empty_fence_handle,
154 [&](const auto &tmp_err, const auto &tmp_vaddr) {
155 error = tmp_err;
156 if(tmp_err == V4Error::NONE)
157 {
158 *vaddr = tmp_vaddr;
159 }
160 });
161 return ret.isOk() && error == V4Error::NONE ? 0 : -1;
162 }
163 #endif
164
165 #ifdef HAVE_GRALLOC3
166 if(m_gralloc3_mapper != nullptr)
167 {
168 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
169
170 V3Mapper::Rect rect;
171 rect.left = left;
172 rect.top = top;
173 rect.width = width;
174 rect.height = height;
175
176 hidl_handle empty_fence_handle;
177
178 V3Error error;
179 auto ret = m_gralloc3_mapper->lock(native_handle, usage, rect, empty_fence_handle,
180 [&](const auto &tmp_err,
181 const auto &tmp_vaddr,
182 const auto & /*bytes_per_pixel*/,
183 const auto & /*bytes_per_stride*/) {
184 error = tmp_err;
185 if(tmp_err == V3Error::NONE)
186 {
187 *vaddr = tmp_vaddr;
188 }
189 });
190 return ret.isOk() && error == V3Error::NONE ? 0 : -1;
191 }
192 #endif
193
194 switch(m_major_version)
195 {
196 case 0:
197 {
198 return m_module->lock(m_module, handle, usage, left, top, width, height, vaddr);
199 }
200 case 1:
201 #ifdef HAVE_GRALLOC1
202 {
203 gralloc1_rect_t outRect{};
204 outRect.left = left;
205 outRect.top = top;
206 outRect.width = width;
207 outRect.height = height;
208 return m_gralloc1_lock(m_gralloc1_device, handle, usage, usage, &outRect, vaddr, -1);
209 }
210 #endif
211 default:
212 {
213 TRACE("no gralloc module to lock");
214 return -1;
215 }
216 }
217 }
218
unlock(buffer_handle_t handle)219 int GrallocModule::unlock(buffer_handle_t handle)
220 {
221 #ifdef HAVE_GRALLOC4
222 if(m_gralloc4_mapper != nullptr)
223 {
224 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
225
226 V4Error error;
227 auto ret = m_gralloc4_mapper->unlock(native_handle,
228 [&](const auto &tmp_err, const auto &) {
229 error = tmp_err;
230 });
231 return ret.isOk() && error == V4Error::NONE ? 0 : -1;
232 }
233 #endif
234
235 #ifdef HAVE_GRALLOC3
236 if(m_gralloc3_mapper != nullptr)
237 {
238 native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
239
240 V3Error error;
241 auto ret = m_gralloc3_mapper->unlock(native_handle,
242 [&](const auto &tmp_err, const auto &) {
243 error = tmp_err;
244 });
245 return ret.isOk() && error == V3Error::NONE ? 0 : -1;
246 }
247 #endif
248
249 switch(m_major_version)
250 {
251 case 0:
252 {
253 return m_module->unlock(m_module, handle);
254 }
255 case 1:
256 #ifdef HAVE_GRALLOC1
257 {
258 int32_t fenceFd = -1;
259 int error = m_gralloc1_unlock(m_gralloc1_device, handle, &fenceFd);
260 if(!error)
261 {
262 sync_wait(fenceFd, -1);
263 close(fenceFd);
264 }
265 return error;
266 }
267 #endif
268 default:
269 {
270 TRACE("no gralloc module to unlock");
271 return -1;
272 }
273 }
274 }
275