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