• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	using namespace ::pixel::graphics;
250 	auto out_oe = mapper::get<MetadataType::VIDEO_HDR>(handle);
251 
252 	if (!out_oe.has_value()) {
253 		ALOGE("Failed to get video HDR metadata");
254 		return nullptr;
255 	}
256 
257 	return out_oe.value();
258 }
259 
get_video_metadata_roiinfo(buffer_handle_t hnd)260 void* VendorGraphicBufferMeta::get_video_metadata_roiinfo(buffer_handle_t hnd)
261 {
262 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
263 	if (!handle) {
264 		return nullptr;
265 	}
266 
267 	using namespace ::pixel::graphics;
268 	auto out_oe = mapper::get<MetadataType::VIDEO_ROI>(handle);
269 
270 	if (!out_oe.has_value()) {
271 		ALOGE("Failed to get video ROI metadata");
272 		return nullptr;
273 	}
274 
275 	return out_oe.value();
276 }
277 
get_format_fourcc(buffer_handle_t hnd)278 uint32_t VendorGraphicBufferMeta::get_format_fourcc(buffer_handle_t hnd) {
279 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
280 	if (!handle) {
281 		return DRM_FORMAT_INVALID;
282 	}
283 
284 	Error error = Error::NONE;
285 	uint32_t fourcc;
286 	get_mapper()->get(handle, android::gralloc4::MetadataType_PixelFormatFourCC,
287 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
288 	                  	error = tmpError;
289 	                  	if (error != Error::NONE) {
290 	                  		return;
291 	                  	}
292 	                  	error = static_cast<Error>(decodePixelFormatFourCC(tmpVec, &fourcc));
293 	                  });
294 
295 
296 	if (error != Error::NONE) {
297 		ALOGE("Failed to get fourcc");
298 		return DRM_FORMAT_INVALID;
299 	}
300 
301 	return fourcc;
302 }
303 
get_format_modifier(buffer_handle_t hnd)304 uint64_t VendorGraphicBufferMeta::get_format_modifier(buffer_handle_t hnd) {
305 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
306 	if (!handle) {
307 		return DRM_FORMAT_MOD_INVALID;
308 	}
309 
310 	Error error = Error::NONE;
311 	uint64_t modifier;
312 	get_mapper()->get(handle, android::gralloc4::MetadataType_PixelFormatModifier,
313 	                  [&](const auto& tmpError, const android::hardware::hidl_vec<uint8_t>& tmpVec) {
314 	                  	error = tmpError;
315 	                  	if (error != Error::NONE) {
316 	                  		return;
317 	                  	}
318 	                  	error = static_cast<Error>(decodePixelFormatModifier(tmpVec, &modifier));
319 	                  });
320 
321 
322 	if (error != Error::NONE) {
323 		ALOGE("Failed to get format modifier");
324 		return DRM_FORMAT_MOD_INVALID;
325 	}
326 
327 	return modifier;
328 }
329 
init(const buffer_handle_t handle)330 void VendorGraphicBufferMeta::init(const buffer_handle_t handle)
331 {
332 	const auto *gralloc_hnd = convertNativeHandleToPrivateHandle(handle);
333 
334 	if (!gralloc_hnd)
335 		return;
336 
337 	fd = gralloc_hnd->fds[0];
338 	fd1 = gralloc_hnd->fds[1];
339 	fd2 = gralloc_hnd->fds[2];
340 
341 	size   = gralloc_hnd->alloc_sizes[0];
342 	size1  = gralloc_hnd->alloc_sizes[1];
343 	size2  = gralloc_hnd->alloc_sizes[2];
344 
345 	offsets[0] = gralloc_hnd->plane_info[0].offset;
346 	offsets[1] = gralloc_hnd->plane_info[1].offset;
347 	offsets[2] = gralloc_hnd->plane_info[2].offset;
348 
349 	uint64_t usage = gralloc_hnd->producer_usage | gralloc_hnd->consumer_usage;
350 	if (usage & VendorGraphicBufferUsage::VIDEO_PRIVATE_DATA) {
351 		switch (gralloc_hnd->get_share_attr_fd_index()) {
352 		case 1:
353 			size1 = gralloc_hnd->attr_size;
354 			break;
355 		case 2:
356 			size2 = gralloc_hnd->attr_size;
357 			break;
358 		}
359 	}
360 
361 	internal_format = gralloc_hnd->alloc_format;
362 	frameworkFormat = gralloc_hnd->req_format;
363 
364 	width  = gralloc_hnd->width;
365 	height = gralloc_hnd->height;
366 	stride = gralloc_hnd->stride;
367 	vstride = gralloc_hnd->plane_info[0].alloc_height;
368 
369 	producer_usage = gralloc_hnd->producer_usage;
370 	consumer_usage = gralloc_hnd->consumer_usage;
371 
372 	flags = gralloc_hnd->flags;
373 
374 	unique_id = gralloc_hnd->backing_store_id;
375 }
376 
import_buffer(buffer_handle_t hnd)377 buffer_handle_t VendorGraphicBufferMeta::import_buffer(buffer_handle_t hnd)
378 {
379 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
380 	if (!handle) {
381 		return nullptr;
382 	}
383 
384 	native_handle_t* bufferHandle = nullptr;
385 	Error error = Error::NONE;
386 	get_mapper()->importBuffer(handle, [&](const auto& tmpError, const auto& tmpBuffer) {
387 				error = tmpError;
388 				if (error != Error::NONE) {
389 					return;
390 				}
391 				bufferHandle = static_cast<native_handle_t*>(tmpBuffer);
392 			});
393 
394 	if (error != Error::NONE) {
395 		ALOGE("[%s] Unable to import buffer", __FUNCTION__);
396 		return nullptr;
397 	}
398 
399 	return bufferHandle;
400 }
401 
free_buffer(buffer_handle_t hnd)402 int VendorGraphicBufferMeta::free_buffer(buffer_handle_t hnd)
403 {
404 	native_handle_t* handle = const_cast<native_handle_t*>(hnd);
405 	if (!handle) {
406 		return -EINVAL;
407 	}
408 	Error error = get_mapper()->freeBuffer(handle);
409 	if (error != Error::NONE) {
410 		ALOGE("[%s] Failed to free buffer", __FUNCTION__);
411 		return -EINVAL;
412 	}
413 	return 0;
414 }
415 
VendorGraphicBufferMeta(buffer_handle_t handle)416 VendorGraphicBufferMeta::VendorGraphicBufferMeta(buffer_handle_t handle)
417 {
418 	init(handle);
419 }
420 
421