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 "hidl_common/SharedMetadata_struct.h"
28 #include "hidl_common/hidl_common.h"
29 #include "exynos_format.h"
30 
31 #include <pixel-gralloc/metadata.h>
32 #include <pixel-gralloc/mapper.h>
33 
34 using namespace android;
35 using namespace vendor::graphics;
36 
37 using arm::mapper::common::shared_metadata;
38 using aidl::android::hardware::graphics::common::Dataspace;
39 using android::gralloc4::encodeDataspace;
40 using android::gralloc4::decodeDataspace;
41 using android::gralloc4::decodePixelFormatFourCC;
42 using android::gralloc4::decodePixelFormatModifier;
43 using android::hardware::graphics::mapper::V4_0::IMapper;
44 using android::hardware::graphics::mapper::V4_0::Error;
45 using MapperMetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
46 
47 #define UNUSED(x) ((void)x)
48 #define SZ_4k 0x1000
49 
50 // TODO(b/191912915): This is a non-thread safe version of the validate function
51 // from mapper-4.0-impl library. Ideally this should be decoupled from `impl`
52 // libraries and should depend upon HAL (and it's extension) to call into
53 // Gralloc.
mali_gralloc_reference_validate(buffer_handle_t handle)54 int mali_gralloc_reference_validate(buffer_handle_t handle) {
55 	return private_handle_t::validate(handle);
56 }
57 
convertNativeHandleToPrivateHandle(buffer_handle_t handle)58 const private_handle_t * convertNativeHandleToPrivateHandle(buffer_handle_t handle) {
59 	if (mali_gralloc_reference_validate(handle) < 0)
60 		return nullptr;
61 
62 	return static_cast<const private_handle_t *>(handle);
63 }
64 
get_mapper()65 android::sp<IMapper> get_mapper() {
66 	static android::sp<IMapper> mapper = []() {
67 		auto mapper = IMapper::getService();
68 		if (!mapper) {
69 			ALOGE("Failed to get mapper service");
70 		}
71 		return mapper;
72 	}();
73 
74 	return mapper;
75 }
76 
get_video_metadata_fd(buffer_handle_t)77 int VendorGraphicBufferMeta::get_video_metadata_fd(buffer_handle_t /*hnd*/)
78 {
79 	ALOGE("%s function is obsolete and should not be used", __FUNCTION__);
80 	__builtin_trap();
81 }
82 
get_dataspace(buffer_handle_t hnd)83 int VendorGraphicBufferMeta::get_dataspace(buffer_handle_t hnd)
84 {
85 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
86 	if (!handle) {
87 		return -EINVAL;
88 	}
89 
90 	Error error = Error::NONE;
91 	Dataspace dataspace;
92 	get_mapper()->get(handle, android::gralloc4::MetadataType_Dataspace,
93 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
94 	                  	error = tmpError;
95 	                  	if (error != Error::NONE) {
96 	                  		return;
97 	                  	}
98 	                  	error = static_cast<Error>(decodeDataspace(tmpVec, &dataspace));
99 	                  });
100 
101 
102 	if (error != Error::NONE) {
103 		ALOGE("Failed to get datasapce");
104 		return -EINVAL;
105 	}
106 
107 	return static_cast<int>(dataspace);
108 }
109 
set_dataspace(buffer_handle_t hnd,android_dataspace_t dataspace)110 int VendorGraphicBufferMeta::set_dataspace(buffer_handle_t hnd, android_dataspace_t dataspace)
111 {
112 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
113 	if (!handle) {
114 		return -EINVAL;
115 	}
116 
117 	Error error = Error::NONE;
118 	android::hardware::hidl_vec<uint8_t> vec;
119 	error = static_cast<Error>(encodeDataspace(static_cast<Dataspace>(dataspace), &vec));
120 	if (error != Error::NONE) {
121 		ALOGE("Error encoding dataspace");
122 		return -EINVAL;
123 	}
124 	error = get_mapper()->set(handle, android::gralloc4::MetadataType_Dataspace, vec);
125 
126 	if (error != Error::NONE) {
127 		ALOGE("Failed to set datasapce");
128 		return -EINVAL;
129 	}
130 
131 	return 0;
132 }
133 
is_afbc(buffer_handle_t hnd)134 int VendorGraphicBufferMeta::is_afbc(buffer_handle_t hnd)
135 {
136 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
137 
138 	if (!gralloc_hnd)
139 		return 0;
140 
141 	if (gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
142 		return 1;
143 
144 	return 0;
145 }
146 
is_sbwc(buffer_handle_t hnd)147 int VendorGraphicBufferMeta::is_sbwc(buffer_handle_t hnd)
148 {
149 	return is_sbwc_format(VendorGraphicBufferMeta::get_internal_format(hnd));
150 }
151 
152 #define GRALLOC_META_GETTER(__type__, __name__, __member__) \
153 __type__ VendorGraphicBufferMeta::get_##__name__(buffer_handle_t hnd) \
154 { \
155 	const private_handle_t *gralloc_hnd = static_cast<const private_handle_t *>(hnd); \
156 	if (!gralloc_hnd) return 0; \
157 	return gralloc_hnd->__member__; \
158 } \
159 
160 
get_format(buffer_handle_t hnd)161 uint32_t VendorGraphicBufferMeta::get_format(buffer_handle_t hnd)
162 {
163 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
164 
165 	if (!gralloc_hnd)
166 		return 0;
167 
168 	return static_cast<uint32_t>(gralloc_hnd->alloc_format);
169 }
170 
get_internal_format(buffer_handle_t hnd)171 uint64_t VendorGraphicBufferMeta::get_internal_format(buffer_handle_t hnd)
172 {
173 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);;
174 
175 	if (!gralloc_hnd)
176 		return 0;
177 
178 	return static_cast<uint64_t>(gralloc_hnd->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
179 }
180 
181 GRALLOC_META_GETTER(uint64_t, frameworkFormat, req_format);
182 
183 GRALLOC_META_GETTER(int, width, width);
184 GRALLOC_META_GETTER(int, height, height);
185 GRALLOC_META_GETTER(uint32_t, stride, stride);
186 GRALLOC_META_GETTER(uint32_t, stride_in_bytes, plane_info[0].byte_stride);
187 GRALLOC_META_GETTER(uint32_t, vstride, plane_info[0].alloc_height);
188 
189 GRALLOC_META_GETTER(uint64_t, producer_usage, producer_usage);
190 GRALLOC_META_GETTER(uint64_t, consumer_usage, consumer_usage);
191 
192 GRALLOC_META_GETTER(uint64_t, flags, flags);
193 
194 
get_fd(buffer_handle_t hnd,int num)195 int VendorGraphicBufferMeta::get_fd(buffer_handle_t hnd, int num)
196 {
197 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
198 
199 	if (!gralloc_hnd)
200 		return -1;
201 
202 	if (num > 2)
203 		return -1;
204 
205 	return gralloc_hnd->fds[num];
206 }
207 
get_size(buffer_handle_t hnd,int num)208 int VendorGraphicBufferMeta::get_size(buffer_handle_t hnd, int num)
209 {
210 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
211 
212 	if (!gralloc_hnd)
213 		return 0;
214 
215 	if (num > 2)
216 		return 0;
217 
218 	return gralloc_hnd->alloc_sizes[num];
219 }
220 
221 
get_usage(buffer_handle_t hnd)222 uint64_t VendorGraphicBufferMeta::get_usage(buffer_handle_t hnd)
223 {
224 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(hnd);
225 
226 	if (!gralloc_hnd)
227 		return 0;
228 
229 	return gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
230 }
231 
decodePointer(const android::hardware::hidl_vec<uint8_t> & tmpVec)232 void* decodePointer(const android::hardware::hidl_vec<uint8_t>& tmpVec) {
233 	constexpr uint8_t kPtrSize = sizeof(void*);
234 	assert(tmpVec.size() == kPtrSize);
235 
236 	void* data_ptr;
237 	std::memcpy(&data_ptr, tmpVec.data(), kPtrSize);
238 
239 	return data_ptr;
240 }
241 
get_video_metadata(buffer_handle_t hnd)242 void* VendorGraphicBufferMeta::get_video_metadata(buffer_handle_t hnd)
243 {
244 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
245 	if (!handle) {
246 		return nullptr;
247 	}
248 
249 	auto out_oe = ::pixel::graphics::mapper::get<::pixel::graphics::MetadataType::VIDEO_HDR>(handle);
250 
251 	if (!out_oe.has_value()) {
252 		ALOGE("Failed to get video HDR metadata");
253 		return nullptr;
254 	}
255 
256 	return out_oe.value();
257 }
258 
get_video_metadata_roiinfo(buffer_handle_t hnd)259 void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd)
260 {
261 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
262 	if (!handle) {
263 		return nullptr;
264 	}
265 
266 	auto out_oe = ::pixel::graphics::mapper::get<::pixel::graphics::MetadataType::VIDEO_ROI>(handle);
267 
268 	if (!out_oe.has_value()) {
269 		ALOGE("Failed to get video ROI metadata");
270 		return nullptr;
271 	}
272 
273 	return out_oe.value();
274 }
275 
get_format_fourcc(buffer_handle_t hnd)276 uint32_t VendorGraphicBufferMeta::get_format_fourcc(buffer_handle_t hnd) {
277 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
278 	if (!handle) {
279 		return DRM_FORMAT_INVALID;
280 	}
281 
282 	Error error = Error::NONE;
283 	uint32_t fourcc;
284 	get_mapper()->get(handle, android::gralloc4::MetadataType_PixelFormatFourCC,
285 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
286 	                  	error = tmpError;
287 	                  	if (error != Error::NONE) {
288 	                  		return;
289 	                  	}
290 	                  	error = static_cast<Error>(decodePixelFormatFourCC(tmpVec, &fourcc));
291 	                  });
292 
293 
294 	if (error != Error::NONE) {
295 		ALOGE("Failed to get fourcc");
296 		return DRM_FORMAT_INVALID;
297 	}
298 
299 	return fourcc;
300 }
301 
get_format_modifier(buffer_handle_t hnd)302 uint64_t VendorGraphicBufferMeta::get_format_modifier(buffer_handle_t hnd) {
303 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
304 	if (!handle) {
305 		return DRM_FORMAT_MOD_INVALID;
306 	}
307 
308 	Error error = Error::NONE;
309 	uint64_t modifier;
310 	get_mapper()->get(handle, android::gralloc4::MetadataType_PixelFormatModifier,
311 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
312 	                  	error = tmpError;
313 	                  	if (error != Error::NONE) {
314 	                  		return;
315 	                  	}
316 	                  	error = static_cast<Error>(decodePixelFormatModifier(tmpVec, &modifier));
317 	                  });
318 
319 
320 	if (error != Error::NONE) {
321 		ALOGE("Failed to get format modifier");
322 		return DRM_FORMAT_MOD_INVALID;
323 	}
324 
325 	return modifier;
326 }
327 
init(const buffer_handle_t handle)328 void VendorGraphicBufferMeta::init(const buffer_handle_t handle)
329 {
330 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(handle);
331 
332 	if (!gralloc_hnd)
333 		return;
334 
335 	fd = gralloc_hnd->fds[0];
336 	fd1 = gralloc_hnd->fds[1];
337 	fd2 = gralloc_hnd->fds[2];
338 
339 	size   = gralloc_hnd->alloc_sizes[0];
340 	size1  = gralloc_hnd->alloc_sizes[1];
341 	size2  = gralloc_hnd->alloc_sizes[2];
342 
343 	offsets[0] = gralloc_hnd->plane_info[0].offset;
344 	offsets[1] = gralloc_hnd->plane_info[1].offset;
345 	offsets[2] = gralloc_hnd->plane_info[2].offset;
346 
347 	uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
348 	if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA) {
349 		switch (gralloc_hnd->get_share_attr_fd_index()) {
350 		case 1:
351 			size1 = gralloc_hnd->attr_size;
352 			break;
353 		case 2:
354 			size2 = gralloc_hnd->attr_size;
355 			break;
356 		}
357 	}
358 
359 	internal_format = gralloc_hnd->alloc_format;
360 	frameworkFormat = gralloc_hnd->req_format;
361 
362 	width  = gralloc_hnd->width;
363 	height = gralloc_hnd->height;
364 	stride = gralloc_hnd->stride;
365 	vstride = gralloc_hnd->plane_info[0].alloc_height;
366 
367 	producer_usage = gralloc_hnd->producer_usage;
368 	consumer_usage = gralloc_hnd->consumer_usage;
369 
370 	flags = gralloc_hnd->flags;
371 
372 	unique_id = gralloc_hnd->backing_store_id;
373 }
374 
import_buffer(buffer_handle_t hnd)375 buffer_handle_t VendorGraphicBufferMeta::import_buffer(buffer_handle_t hnd)
376 {
377 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
378 	if (!handle) {
379 		return nullptr;
380 	}
381 
382 	native_handle_t* bufferHandle = nullptr;
383 	Error error = Error::NONE;
384 	get_mapper()->importBuffer(handle, [&](const auto& tmpError, const auto& tmpBuffer) {
385 				error = tmpError;
386 				if (error != Error::NONE) {
387 					return;
388 				}
389 				bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
390 			});
391 
392 	if (error != Error::NONE) {
393 		ALOGE("[%s] Unable to import buffer", __FUNCTION__);
394 		return nullptr;
395 	}
396 
397 	return bufferHandle;
398 }
399 
free_buffer(buffer_handle_t hnd)400 int VendorGraphicBufferMeta::free_buffer(buffer_handle_t hnd)
401 {
402 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
403 	if (!handle) {
404 		return -EINVAL;
405 	}
406 	Error error = get_mapper()->freeBuffer(handle);
407 	if (error != Error::NONE) {
408 		ALOGE("[%s] Failed to free buffer", __FUNCTION__);
409 		return -EINVAL;
410 	}
411 	return 0;
412 }
413 
VendorGraphicBufferMeta(buffer_handle_t handle)414 VendorGraphicBufferMeta::VendorGraphicBufferMeta(buffer_handle_t handle)
415 {
416 	init(handle);
417 }
418 
419