1 /*
2  * Copyright (C) 2020 Samsung Electronics Co. Ltd.
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 #define LOG_TAG "VendorGraphicBuffer"
18 
19 #include <log/log.h>
20 #include <gralloctypes/Gralloc4.h>
21 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
22 
23 #include "VendorGraphicBuffer.h"
24 #include "mali_gralloc_buffer.h"
25 #include "mali_gralloc_formats.h"
26 #include "hidl_common/SharedMetadata.h"
27 #include "exynos_format.h"
28 
29 using namespace android;
30 using namespace vendor::graphics;
31 
32 using arm::mapper::common::shared_metadata;
33 using aidl::android::hardware::graphics::common::Dataspace;
34 using android::gralloc4::encodeDataspace;
35 using android::gralloc4::decodeDataspace;
36 using android::hardware::graphics::mapper::V4_0::IMapper;
37 using android::hardware::graphics::mapper::V4_0::Error;
38 
39 #define UNUSED(x) ((void)x)
40 #define SZ_4k 0x1000
41 
42 // TODO(b/191912915): This is a non-thread safe version of the validate function
43 // from mapper-4.0-impl library. Ideally this should be decoupled from `impl`
44 // libraries and should depend upon HAL (and it's extension) to call into
45 // Gralloc.
mali_gralloc_reference_validate(buffer_handle_t handle)46 int mali_gralloc_reference_validate(buffer_handle_t handle) {
47 	auto hnd = static_cast<const private_handle_t *>(handle);
48 
49 	if (hnd->allocating_pid != getpid() && hnd->remote_pid != getpid()) {
50 		return -EINVAL;
51 	}
52 
53 	return 0;
54 }
55 
convertNativeHandleToPrivateHandle(buffer_handle_t handle)56 const private_handle_t * convertNativeHandleToPrivateHandle(buffer_handle_t handle) {
57 	if (mali_gralloc_reference_validate(handle) < 0)
58 		return nullptr;
59 
60 	return static_cast<const private_handle_t *>(handle);
61 }
62 
get_mapper()63 android::sp<IMapper> get_mapper() {
64 	static android::sp<IMapper> mapper = []() {
65 		auto mapper = IMapper::getService();
66 		if (!mapper) {
67 			ALOGE("Failed to get mapper service");
68 		}
69 		return mapper;
70 	}();
71 
72 	return mapper;
73 }
74 
get_video_metadata_fd(buffer_handle_t hnd)75 int VendorGraphicBufferMeta::get_video_metadata_fd(buffer_handle_t hnd)
76 {
77 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
78 
79 	if (!gralloc_hnd)
80 		return -EINVAL;
81 
82 	uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
83 
84 	if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA)
85 		return gralloc_hnd->get_share_attr_fd();
86 	else
87 		return -EINVAL;
88 }
89 
get_dataspace(buffer_handle_t hnd)90 int VendorGraphicBufferMeta::get_dataspace(buffer_handle_t hnd)
91 {
92 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
93 	if (!handle) {
94 		return -EINVAL;
95 	}
96 
97 	Error error = Error::NONE;
98 	Dataspace dataspace;
99 	get_mapper()->get(handle, android::gralloc4::MetadataType_Dataspace,
100 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
101 	                  	error = tmpError;
102 	                  	if (error != Error::NONE) {
103 	                  		return;
104 	                  	}
105 	                  	error = static_cast<Error>(decodeDataspace(tmpVec, &dataspace));
106 	                  });
107 
108 
109 	if (error != Error::NONE) {
110 		ALOGE("Failed to get datasapce");
111 		return -EINVAL;
112 	}
113 
114 	return static_cast<int>(dataspace);
115 }
116 
set_dataspace(buffer_handle_t hnd,android_dataspace_t dataspace)117 int VendorGraphicBufferMeta::set_dataspace(buffer_handle_t hnd, android_dataspace_t dataspace)
118 {
119 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
120 	if (!handle) {
121 		return -EINVAL;
122 	}
123 
124 	Error error = Error::NONE;
125 	android::hardware::hidl_vec<uint8_t> vec;
126 	error = static_cast<Error>(encodeDataspace(static_cast<Dataspace>(dataspace), &vec));
127 	if (error != Error::NONE) {
128 		ALOGE("Error encoding dataspace");
129 		return -EINVAL;
130 	}
131 	error = get_mapper()->set(handle, android::gralloc4::MetadataType_Dataspace, vec);
132 
133 	if (error != Error::NONE) {
134 		ALOGE("Failed to set datasapce");
135 		return -EINVAL;
136 	}
137 
138 	return 0;
139 }
140 
is_afbc(buffer_handle_t hnd)141 int VendorGraphicBufferMeta::is_afbc(buffer_handle_t hnd)
142 {
143 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
144 
145 	if (!gralloc_hnd)
146 		return 0;
147 
148 	if (gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
149 		return 1;
150 
151 	return 0;
152 }
153 
is_sbwc(buffer_handle_t buffer_hnd_p)154 int VendorGraphicBufferMeta::is_sbwc(buffer_handle_t buffer_hnd_p)
155 {
156 	const private_handle_t *hnd = static_cast<const private_handle_t *>(buffer_hnd_p);
157 
158 	return is_sbwc_format(static_cast<uint32_t>(hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK));
159 }
160 
161 #define GRALLOC_META_GETTER(__type__, __name__, __member__) \
162 __type__ VendorGraphicBufferMeta::get_##__name__(buffer_handle_t hnd) \
163 { \
164 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); \
165 	if (!gralloc_hnd) return 0; \
166 	return gralloc_hnd->__member__; \
167 } \
168 
169 
get_format(buffer_handle_t hnd)170 uint32_t VendorGraphicBufferMeta::get_format(buffer_handle_t hnd)
171 {
172 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
173 	if (!gralloc_hnd)
174 		return 0;
175 
176 	return static_cast<uint32_t>(gralloc_hnd->alloc_format);
177 }
178 
get_internal_format(buffer_handle_t hnd)179 uint64_t VendorGraphicBufferMeta::get_internal_format(buffer_handle_t hnd)
180 {
181 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
182 	if (!gralloc_hnd)
183 		return 0;
184 
185 	return static_cast<uint64_t>(gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
186 }
187 
188 GRALLOC_META_GETTER(uint64_t, frameworkFormat, req_format);
189 
190 GRALLOC_META_GETTER(int, width, width);
191 GRALLOC_META_GETTER(int, height, height);
192 GRALLOC_META_GETTER(uint32_t, stride, stride);
193 GRALLOC_META_GETTER(uint32_t, vstride, plane_info[0].alloc_height);
194 
195 GRALLOC_META_GETTER(uint64_t, producer_usage, producer_usage);
196 GRALLOC_META_GETTER(uint64_t, consumer_usage, consumer_usage);
197 
198 GRALLOC_META_GETTER(uint64_t, flags, flags);
199 
200 
get_fd(buffer_handle_t hnd,int num)201 int VendorGraphicBufferMeta::get_fd(buffer_handle_t hnd, int num)
202 {
203 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
204 
205 	if (!gralloc_hnd)
206 		return -1;
207 
208 	if (num > 2)
209 		return -1;
210 
211 	return gralloc_hnd->fds[num];
212 }
213 
get_size(buffer_handle_t hnd,int num)214 int VendorGraphicBufferMeta::get_size(buffer_handle_t hnd, int num)
215 {
216 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
217 
218 	if (!gralloc_hnd)
219 		return 0;
220 
221 	if (num > 2)
222 		return 0;
223 
224 	return gralloc_hnd->alloc_sizes[num];
225 }
226 
227 
get_usage(buffer_handle_t hnd)228 uint64_t VendorGraphicBufferMeta::get_usage(buffer_handle_t hnd)
229 {
230 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd);
231 
232 	if (!gralloc_hnd)
233 		return 0;
234 
235 	return gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
236 }
237 
get_video_metadata(buffer_handle_t hnd)238 void* VendorGraphicBufferMeta::get_video_metadata(buffer_handle_t hnd)
239 {
240 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
241 
242 	if (gralloc_hnd == nullptr)
243 		return nullptr;
244 
245 	return gralloc_hnd->attr_base;
246 }
247 
get_video_metadata_roiinfo(buffer_handle_t hnd)248 void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd)
249 {
250 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
251 
252 	if (gralloc_hnd == nullptr)
253 		return nullptr;
254 
255 	if (gralloc_hnd->get_usage() & VendorGraphicBufferUsage::ROIINFO)
256 		return static_cast<char*>(gralloc_hnd->attr_base) + SZ_4k * 2;
257 
258 	return nullptr;
259 }
260 
init(const buffer_handle_t handle)261 void VendorGraphicBufferMeta::init(const buffer_handle_t handle)
262 {
263 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(handle);
264 
265 	if (!gralloc_hnd)
266 		return;
267 
268 	fd = gralloc_hnd->fds[0];
269 	fd1 = gralloc_hnd->fds[1];
270 	fd2 = gralloc_hnd->fds[2];
271 
272 	size   = gralloc_hnd->alloc_sizes[0];
273 	size1  = gralloc_hnd->alloc_sizes[1];
274 	size2  = gralloc_hnd->alloc_sizes[2];
275 
276 	offsets[0] = gralloc_hnd->plane_info[0].offset;
277 	offsets[1] = gralloc_hnd->plane_info[1].offset;
278 	offsets[2] = gralloc_hnd->plane_info[2].offset;
279 
280 	uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
281 	if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA) {
282 		switch (gralloc_hnd->get_share_attr_fd_index()) {
283 		case 1:
284 			size1 = gralloc_hnd->attr_size;
285 			break;
286 		case 2:
287 			size2 = gralloc_hnd->attr_size;
288 			break;
289 		}
290 	}
291 
292 	internal_format = gralloc_hnd->alloc_format;
293 	frameworkFormat = gralloc_hnd->req_format;
294 
295 	width  = gralloc_hnd->width;
296 	height = gralloc_hnd->height;
297 	stride = gralloc_hnd->stride;
298 	vstride = gralloc_hnd->plane_info[0].alloc_height;
299 
300 	producer_usage = gralloc_hnd->producer_usage;
301 	consumer_usage = gralloc_hnd->consumer_usage;
302 
303 	flags = gralloc_hnd->flags;
304 
305 	unique_id = gralloc_hnd->backing_store_id;
306 }
307 
import_buffer(buffer_handle_t hnd)308 buffer_handle_t VendorGraphicBufferMeta::import_buffer(buffer_handle_t hnd)
309 {
310 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
311 	if (!handle) {
312 		return nullptr;
313 	}
314 
315 	native_handle_t* bufferHandle = nullptr;
316 	Error error = Error::NONE;
317 	get_mapper()->importBuffer(handle, [&](const auto& tmpError, const auto& tmpBuffer) {
318 				error = tmpError;
319 				if (error != Error::NONE) {
320 					return;
321 				}
322 				bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
323 			});
324 
325 	if (error != Error::NONE) {
326 		ALOGE("[%s] Unable to import buffer", __FUNCTION__);
327 		return nullptr;
328 	}
329 
330 	return bufferHandle;
331 }
332 
free_buffer(buffer_handle_t hnd)333 int VendorGraphicBufferMeta::free_buffer(buffer_handle_t hnd)
334 {
335 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
336 	if (!handle) {
337 		return -EINVAL;
338 	}
339 	Error error = get_mapper()->freeBuffer(handle);
340 	if (error != Error::NONE) {
341 		ALOGE("[%s] Failed to free buffer", __FUNCTION__);
342 		return -EINVAL;
343 	}
344 	return 0;
345 }
346 
VendorGraphicBufferMeta(buffer_handle_t handle)347 VendorGraphicBufferMeta::VendorGraphicBufferMeta(buffer_handle_t handle)
348 {
349 	init(handle);
350 }
351 
352