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