1 /*
2  * Copyright (C) 2016-2020 ARM Limited. All rights reserved.
3  *
4  * Copyright (C) 2008 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
20 
21 #include <inttypes.h>
22 #include <assert.h>
23 #include <atomic>
24 #include <algorithm>
25 #include <set>
26 #include <utils/Trace.h>
27 
28 #include <hardware/hardware.h>
29 #include <hardware/gralloc1.h>
30 
31 #include "mali_gralloc_bufferallocation.h"
32 #include "allocator/mali_gralloc_ion.h"
33 #include "mali_gralloc_buffer.h"
34 #include "mali_gralloc_bufferdescriptor.h"
35 #include "mali_gralloc_log.h"
36 #include "format_info.h"
37 #include <exynos_format.h>
38 #include "exynos_format_allocation.h"
39 
40 #define EXT_SIZE       256
41 #define INVALID_USAGE  (((1LL * 0xFFFE) << 32))
42 
43 /* HW needs extra padding bytes for its prefetcher does not check the picture boundary */
44 #define BW_EXT_SIZE (16 * 1024)
45 
46 /* Default align values for Exynos */
47 #define YUV_BYTE_ALIGN_DEFAULT 16
48 #define RGB_BYTE_ALIGN_DEFAULT 64
49 
50 /* IP-specific align values */
51 #define GPU_BYTE_ALIGN_DEFAULT 64
52 #define BIG_BYTE_ALIGN_DEFAULT 64
53 #ifdef SOC_ZUMA
54 #define CAMERA_RAW_BUFFER_BYTE_ALIGN 32
55 #define CAMERA_YUV_BUFFER_BYTE_ALIGN 64
56 #endif
57 
58 /* Realign YV12 format so that chroma stride is half of luma stride */
59 #define REALIGN_YV12 1
60 
61 /* TODO: set S10B format align in BoardConfig.mk */
62 #define BOARD_EXYNOS_S10B_FORMAT_ALIGN 64
63 #if 0
64 ifeq ($(BOARD_EXYNOS_S10B_FORMAT_ALIGN), 64)
65 LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=$(BOARD_EXYNOS_S10B_FORMAT_ALIGN)
66 else
67 LOCAL_CFLAGS += -DBOARD_EXYNOS_S10B_FORMAT_ALIGN=16
68 endif
69 #endif
70 
71 #define AFBC_PIXELS_PER_BLOCK 256
72 #define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16
73 
74 bool afbc_format_fallback(uint32_t * const format_idx, const uint64_t usage, bool force);
75 
76 
77 /*
78  * Get a global unique ID
79  */
getUniqueId()80 static uint64_t getUniqueId()
81 {
82 	static std::atomic<uint32_t> counter(0);
83 	uint64_t id = static_cast<uint64_t>(getpid()) << 32;
84 	return id | counter++;
85 }
86 
87 template<typename T>
afbc_buffer_align(const bool is_tiled,T * size)88 static void afbc_buffer_align(const bool is_tiled, T *size)
89 {
90 	constexpr T AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024;
91 	T buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
92 
93 	if (is_tiled)
94 	{
95 		buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
96 	}
97 
98 	*size = GRALLOC_ALIGN(*size, buffer_byte_alignment);
99 }
100 
101 /*
102  * Obtain AFBC superblock dimensions from type.
103  */
get_afbc_sb_size(AllocBaseType alloc_base_type)104 static rect_t get_afbc_sb_size(AllocBaseType alloc_base_type)
105 {
106 	const uint16_t AFBC_BASIC_BLOCK_WIDTH = 16;
107 	const uint16_t AFBC_BASIC_BLOCK_HEIGHT = 16;
108 	const uint16_t AFBC_WIDE_BLOCK_WIDTH = 32;
109 	const uint16_t AFBC_WIDE_BLOCK_HEIGHT = 8;
110 	const uint16_t AFBC_EXTRAWIDE_BLOCK_WIDTH = 64;
111 	const uint16_t AFBC_EXTRAWIDE_BLOCK_HEIGHT = 4;
112 
113 	rect_t sb = {0, 0};
114 
115 	switch(alloc_base_type)
116 	{
117 		case AllocBaseType::AFBC:
118 			sb.width = AFBC_BASIC_BLOCK_WIDTH;
119 			sb.height = AFBC_BASIC_BLOCK_HEIGHT;
120 			break;
121 		case AllocBaseType::AFBC_WIDEBLK:
122 			sb.width = AFBC_WIDE_BLOCK_WIDTH;
123 			sb.height = AFBC_WIDE_BLOCK_HEIGHT;
124 			break;
125 		case AllocBaseType::AFBC_EXTRAWIDEBLK:
126 			sb.width = AFBC_EXTRAWIDE_BLOCK_WIDTH;
127 			sb.height = AFBC_EXTRAWIDE_BLOCK_HEIGHT;
128 			break;
129 		default:
130 			break;
131 	}
132 	return sb;
133 }
134 
135 /*
136  * Obtain AFBC superblock dimensions for specific plane.
137  *
138  * See alloc_type_t for more information.
139  */
get_afbc_sb_size(alloc_type_t alloc_type,const uint8_t plane)140 static rect_t get_afbc_sb_size(alloc_type_t alloc_type, const uint8_t plane)
141 {
142 	if (plane > 0 && alloc_type.is_afbc() && alloc_type.is_multi_plane)
143 	{
144 		return get_afbc_sb_size(AllocBaseType::AFBC_EXTRAWIDEBLK);
145 	}
146 	else
147 	{
148 		return get_afbc_sb_size(alloc_type.primary_type);
149 	}
150 }
151 
get_alloc_type(const uint64_t format_ext,const uint32_t format_idx,const uint64_t usage,alloc_type_t * const alloc_type)152 bool get_alloc_type(const uint64_t format_ext,
153                     const uint32_t format_idx,
154                     const uint64_t usage,
155                     alloc_type_t * const alloc_type)
156 {
157 	alloc_type->primary_type = AllocBaseType::UNCOMPRESSED;
158 	alloc_type->is_multi_plane = formats[format_idx].npln > 1;
159 	alloc_type->is_tiled = false;
160 	alloc_type->is_padded = false;
161 	alloc_type->is_frontbuffer_safe = false;
162 
163 	/* Determine AFBC type for this format. This is used to decide alignment.
164 	   Split block does not affect alignment, and therefore doesn't affect the allocation type. */
165 	if (format_ext & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
166 	{
167 		/* YUV transform shall not be enabled for a YUV format */
168 		if ((formats[format_idx].is_yuv == true) && (format_ext & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM))
169 		{
170 			MALI_GRALLOC_LOGW("YUV Transform is incorrectly enabled for format = (%s 0x%x). Extended internal format = (%s 0x%" PRIx64 ")\n",
171 				format_name(formats[format_idx].id), formats[format_idx].id, format_name(format_ext), format_ext);
172 		}
173 
174 		/* Determine primary AFBC (superblock) type. */
175 		alloc_type->primary_type = AllocBaseType::AFBC;
176 		if (format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
177 		{
178 			alloc_type->primary_type = AllocBaseType::AFBC_WIDEBLK;
179 		}
180 		else if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
181 		{
182 			alloc_type->primary_type = AllocBaseType::AFBC_EXTRAWIDEBLK;
183 		}
184 
185 		if (format_ext & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
186 		{
187 			alloc_type->is_tiled = true;
188 
189 			if (formats[format_idx].npln > 1 &&
190 				(format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) == 0)
191 			{
192 				MALI_GRALLOC_LOGW("Extra-wide AFBC must be signalled for multi-plane formats. "
193 				      "Falling back to single plane AFBC.");
194 				alloc_type->is_multi_plane = false;
195 			}
196 
197 			if (format_ext & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY)
198 			{
199 				alloc_type->is_frontbuffer_safe = true;
200 			}
201 		}
202 		else
203 		{
204 			if (formats[format_idx].npln > 1)
205 			{
206 				MALI_GRALLOC_LOGW("Multi-plane AFBC is not supported without tiling. "
207 				      "Falling back to single plane AFBC.");
208 			}
209 			alloc_type->is_multi_plane = false;
210 		}
211 
212 		if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK &&
213 			!alloc_type->is_tiled)
214 		{
215 			/* Headers must be tiled for extra-wide. */
216 			MALI_GRALLOC_LOGE("ERROR: Invalid to specify extra-wide block without tiled headers.");
217 			return false;
218 		}
219 
220 		if (alloc_type->is_frontbuffer_safe &&
221 		    (format_ext & (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK | MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)))
222 		{
223 			MALI_GRALLOC_LOGE("ERROR: Front-buffer safe not supported with wide/extra-wide block.");
224 		}
225 
226 		if (formats[format_idx].npln == 1 &&
227 		    format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK &&
228 		    format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
229 		{
230 			/* "Wide + Extra-wide" implicitly means "multi-plane". */
231 			MALI_GRALLOC_LOGE("ERROR: Invalid to specify multiplane AFBC with single plane format.");
232 			return false;
233 		}
234 
235 		if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
236 		{
237 			alloc_type->is_padded = true;
238 		}
239 	}
240 	return true;
241 }
242 
243 /*
244  * Initialise AFBC header based on superblock layout.
245  * Width and height should already be AFBC aligned.
246  */
init_afbc(uint8_t * buf,const uint64_t alloc_format,const bool is_multi_plane,uint8_t bpp,const uint64_t w,const uint64_t h)247 void init_afbc(uint8_t *buf, const uint64_t alloc_format,
248                const bool is_multi_plane, uint8_t bpp,
249                const uint64_t w, const uint64_t h)
250 {
251 	ATRACE_CALL();
252 	const bool is_tiled = ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
253 	                         == MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS);
254 	const uint32_t n_headers = (w * h) / AFBC_PIXELS_PER_BLOCK;
255 	uint32_t body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
256 
257 	afbc_buffer_align(is_tiled, &body_offset);
258 
259 	/*
260 	 * Declare the AFBC header initialisation values for each superblock layout.
261 	 * Tiled headers (AFBC 1.2) can be initialised to zero for non-subsampled formats
262 	 * (SB layouts: 0, 3, 4, 7).
263 	 */
264 	uint32_t headers[][4] = {
265 		{ (uint32_t)body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4, 7 */
266 		{ ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */
267 	};
268 
269 	/* Map base format to AFBC header layout */
270 	const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
271 
272 	/* Sub-sampled formats use layouts 1 and 5 which is index 1 in the headers array.
273 	 * 1 = 4:2:0 16x16, 5 = 4:2:0 32x8.
274 	 *
275 	 * Non-subsampled use layouts 0, 3, 4 and 7, which is index 0.
276 	 * 0 = 16x16, 3 = 32x8 + split, 4 = 32x8, 7 = 64x4.
277 	 *
278 	 * When using separated planes for YUV formats, the header layout is the non-subsampled one
279 	 * as there is a header per-plane and there is no sub-sampling within the plane.
280 	 * Separated plane only supports 32x8 or 64x4 for the luma plane, so the first plane must be 4 or 7.
281 	 * Seperated plane only supports 64x4 for subsequent planes, so these must be header layout 7.
282 	 */
283 	const uint32_t layout = is_subsampled_yuv(base_format) && !is_multi_plane ? 1 : 0;
284 
285 	/*
286 	 * Solid colour blocks:  AFBC 1.2
287 	 * This storage method is permitted for superblock_layout 0, 3, 4, or 7 with 64 bits per pixel or less.
288 	 * In this case the value of the pixel is stored least significant bit aligned in bits[127:64] of the header, the payload is 0s.
289 	 */
290 	if (is_tiled && layout == 0 && bpp <= 64)
291 	{
292 		memset(headers[0], 0, sizeof(uint32_t) * 4);
293 	}
294 
295 	/* We initialize only linear layouts*/
296 	const size_t sb_bytes = is_tiled? 0 : GRALLOC_ALIGN((bpp * AFBC_PIXELS_PER_BLOCK) / 8, 128);
297 
298 	MALI_GRALLOC_LOGV("Writing AFBC header layout %d for format (%s %" PRIx32 ", n_headers: %d, "
299 		"body_offset: %" PRIx32 ", is_tiled %d, sb_bytes: %zu",
300 		layout, format_name(base_format), base_format,
301 		n_headers, body_offset, is_tiled, sb_bytes);
302 
303 	for (uint32_t i = 0; i < n_headers; i++)
304 	{
305 		memcpy(buf, headers[layout], sizeof(headers[layout]));
306 		buf += sizeof(headers[layout]);
307 		headers[layout][0] += sb_bytes;
308 	}
309 }
310 
311 /*
312  * Obtain plane allocation dimensions (in pixels).
313  *
314  * NOTE: pixel stride, where defined for format, is
315  * incorporated into allocation dimensions.
316  */
get_pixel_w_h(uint64_t * const width,uint64_t * const height,const format_info_t format,const alloc_type_t alloc_type,const uint8_t plane,bool has_cpu_usage)317 static void get_pixel_w_h(uint64_t * const width,
318                           uint64_t * const height,
319                           const format_info_t format,
320                           const alloc_type_t alloc_type,
321                           const uint8_t plane,
322                           bool has_cpu_usage)
323 {
324 	const rect_t sb = get_afbc_sb_size(alloc_type, plane);
325 	const bool is_primary_plane = (plane == 0 || !format.planes_contiguous);
326 
327 	/*
328 	 * Round-up plane dimensions, to multiple of:
329 	 * - Samples for all channels (sub-sampled formats)
330 	 * - Memory bytes/words (some packed formats)
331 	 */
332 	if (is_primary_plane)
333 	{
334 		*width = GRALLOC_ALIGN(*width, format.align_w);
335 		*height = GRALLOC_ALIGN(*height, format.align_h);
336 	}
337 
338 	/*
339 	 * Sub-sample (sub-sampled) planes.
340 	 */
341 	if (plane > 0)
342 	{
343 		*width /= format.hsub;
344 		*height /= format.vsub;
345 	}
346 
347 	/*
348 	 * Pixel alignment (width),
349 	 * where format stride is stated in pixels.
350 	 */
351 	uint32_t pixel_align_w = 1, pixel_align_h = 1;
352 	if (has_cpu_usage && is_primary_plane)
353 	{
354 		pixel_align_w = format.align_w_cpu;
355 	}
356 	else if (alloc_type.is_afbc())
357 	{
358 		constexpr uint32_t HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS = 0;
359 		uint32_t num_sb_align = 0;
360 		if (alloc_type.is_padded && !format.is_yuv)
361 		{
362 			/* Align to 4 superblocks in width --> 64-byte,
363 			 * assuming 16-byte header per superblock.
364 			 */
365 			num_sb_align = 4;
366 		}
367 		pixel_align_w = std::max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width;
368 
369 		/*
370 		 * Determine AFBC tile size when allocating tiled headers.
371 		 */
372 		rect_t afbc_tile = sb;
373 		if (alloc_type.is_tiled)
374 		{
375 			afbc_tile.width = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.width : 8 * afbc_tile.width;
376 			afbc_tile.height = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.height : 8 * afbc_tile.height;
377 		}
378 
379 		MALI_GRALLOC_LOGV("Plane[%hhu]: [SUB-SAMPLE] w:%" PRIu64 ", h:%" PRIu64 "\n", plane, *width, *height);
380 		MALI_GRALLOC_LOGV("Plane[%hhu]: [PIXEL_ALIGN] w:%d\n", plane, pixel_align_w);
381 		MALI_GRALLOC_LOGV("Plane[%hhu]: [LINEAR_TILE] w:%" PRIu16 "\n", plane, format.tile_size);
382 		MALI_GRALLOC_LOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu64 ", h:%" PRIu64 "\n", plane, afbc_tile.width, afbc_tile.height);
383 
384 		pixel_align_w = std::max(static_cast<uint64_t>(pixel_align_w), afbc_tile.width);
385 		pixel_align_h = std::max(static_cast<uint64_t>(pixel_align_h), afbc_tile.height);
386 
387 		if (AllocBaseType::AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled)
388 		{
389 			/*
390 			 * Special case for wide block (32x8) AFBC with linear (non-tiled)
391 			 * headers: hardware reads and writes 32x16 blocks so we need to
392 			 * pad the body buffer accordingly.
393 			 *
394 			 * Note that this branch will not be taken for multi-plane AFBC
395 			 * since that requires tiled headers.
396 			 */
397 			pixel_align_h = std::max(pixel_align_h, 16u);
398 		}
399 	}
400 	*width = GRALLOC_ALIGN(*width, std::max({1u, pixel_align_w, static_cast<uint32_t>(format.tile_size)}));
401 	*height = GRALLOC_ALIGN(*height, std::max({1u, pixel_align_h, static_cast<uint32_t>(format.tile_size)}));
402 }
403 
404 template<typename T>
gcd(T a,T b)405 static T gcd(T a, T b)
406 {
407 	T r, t;
408 
409 	if (a == b)
410 	{
411 		return a;
412 	}
413 	else if (a < b)
414 	{
415 		t = a;
416 		a = b;
417 		b = t;
418 	}
419 
420 	while (b != 0)
421 	{
422 		r = a % b;
423 		a = b;
424 		b = r;
425 	}
426 
427 	return a;
428 }
429 
430 template<typename T>
lcm(T a,T b)431 T lcm(T a, T b)
432 {
433 	if (a != 0 && b != 0)
434 	{
435 		return (a * b) / gcd(a, b);
436 	}
437 
438 	return std::max(a, b);
439 }
440 
441 
442 #if REALIGN_YV12 == 1
443 /*
444  * YV12 stride has additional complexity since chroma stride
445  * must conform to the following:
446  *
447  * c_stride = ALIGN(stride/2, 16)
448  *
449  * Since the stride alignment must satisfy both CPU and HW
450  * constraints, the luma stride must be doubled.
451  */
update_yv12_stride(int8_t plane,size_t luma_stride,uint32_t stride_align,uint64_t * byte_stride)452 static void update_yv12_stride(int8_t plane,
453                                size_t luma_stride,
454                                uint32_t stride_align,
455                                uint64_t * byte_stride)
456 {
457 	// https://developer.android.com/reference/android/graphics/ImageFormat#YV12
458 	if (plane == 0) {
459 		// stride_align has to be honored as GPU alignment still requires the format to be
460 		// 64 bytes aligned. Though that does not break the contract as long as the
461 		// horizontal stride for chroma is half the luma stride and aligned to 16.
462 		*byte_stride = GRALLOC_ALIGN(luma_stride, GRALLOC_ALIGN(stride_align, 16));
463 	} else {
464 		*byte_stride = GRALLOC_ALIGN(luma_stride / 2, 16);
465 	}
466 }
467 #endif
468 
469 /*
470  * Logs and returns false if deprecated usage bits are found
471  *
472  * At times, framework introduces new usage flags which are identical to what
473  * vendor has been using internally. This method logs those bits and returns
474  * true if there is any deprecated usage bit.
475  */
log_obsolete_usage_flags(uint64_t usage)476 static bool log_obsolete_usage_flags(uint64_t usage) {
477 	if (usage & DEPRECATED_MALI_GRALLOC_USAGE_FRONTBUFFER) {
478 		MALI_GRALLOC_LOGW("Using deprecated FRONTBUFFER usage bit, please upgrade to BufferUsage::FRONT_BUFFER");
479 		return false;
480 	}
481 	if (usage & UNSUPPORTED_MALI_GRALLOC_USAGE_CUBE_MAP) {
482 		MALI_GRALLOC_LOGW("BufferUsage::GPU_CUBE_MAP is unsupported");
483 		return false;
484 	}
485 	if (usage & UNSUPPORTED_MALI_GRALLOC_USAGE_MIPMAP_COMPLETE) {
486 		MALI_GRALLOC_LOGW("BufferUsage::GPU_MIPMAP_COMPLETE is unsupported");
487 		return false;
488 	}
489 
490 	return true;
491 }
492 
validate_size(uint32_t layer_count,uint32_t width,uint32_t height)493 static bool validate_size(uint32_t layer_count, uint32_t width, uint32_t height) {
494 	// The max size of an image can be from camera (50 Megapixels) and considering the max
495 	// depth of 4 bytes per pixel, we get an image of size 200MB.
496 	// We can keep twice the margin for a max size of 400MB.
497 	uint64_t overflow_limit = 400 * (1 << 20);
498 
499 	// Maximum 4 bytes per pixel buffers are supported (RGBA). This does not take care of
500 	// alignment, but 400MB is already very generous, so there should not be an issue.
501 	overflow_limit /= 4;
502 	overflow_limit /= layer_count;
503 
504 	if (width > overflow_limit) {
505 		MALI_GRALLOC_LOGE("Parameters layer: %" PRIu32 ", width: %" PRIu32 ", height: %" PRIu32 " are too big", layer_count, width, height);
506 		return false;
507 	}
508 	overflow_limit /= width;
509 
510 	if (height > overflow_limit) {
511 		MALI_GRALLOC_LOGE("Parameters layer: %" PRIu32 ", width: %" PRIu32 ", height: %" PRIu32 " are too big", layer_count, width, height);
512 		return false;
513 	}
514 
515 	return true;
516 }
517 
validate_descriptor(buffer_descriptor_t * const bufDescriptor)518 static bool validate_descriptor(buffer_descriptor_t * const bufDescriptor) {
519 	uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
520 	if (!log_obsolete_usage_flags(bufDescriptor->producer_usage | bufDescriptor->consumer_usage)) {
521 		return false;
522 	}
523 
524 	if (usage & INVALID_USAGE) {
525 		return false;
526 	}
527 
528 	if (!bufDescriptor->additional_options.empty()) {
529 		return false;
530 	}
531 
532 	// BLOB formats are used for some ML models whose size can be really large (up to 2GB)
533 	if (bufDescriptor->hal_format != MALI_GRALLOC_FORMAT_INTERNAL_BLOB &&
534 	    !validate_size(bufDescriptor->layer_count, bufDescriptor->width, bufDescriptor->height)) {
535 		return false;
536 	}
537 
538 	return true;
539 }
540 
541 /*
542  * Modify usage flag when BO/BW is the producer (decoder) or the consumer (encoder)
543  *
544  * BO/BW cannot use the flags CPU_READ_RARELY as Codec layer redefines those flags
545  * for some internal usage. So, when BO/BW is sending CPU_READ_OFTEN, it still
546  * expects to allocate an uncached buffer and this procedure convers the OFTEN
547  * flag to RARELY.
548  */
update_usage_for_BIG(uint64_t usage)549 static uint64_t update_usage_for_BIG(uint64_t usage) {
550 	MALI_GRALLOC_LOGV("Hacking CPU RW flags for BO/BW");
551 	if (usage & hidl_common::BufferUsage::CPU_READ_OFTEN) {
552 		usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_READ_OFTEN));
553 		usage |= hidl_common::BufferUsage::CPU_READ_RARELY;
554 	}
555 
556 	if (usage & hidl_common::BufferUsage::CPU_WRITE_OFTEN) {
557 		usage &= ~(static_cast<uint64_t>(hidl_common::BufferUsage::CPU_WRITE_OFTEN));
558 		usage |= hidl_common::BufferUsage::CPU_WRITE_RARELY;
559 	}
560 	return usage;
561 }
562 
align_plane_stride(plane_info_t * plane_info,uint8_t plane,const format_info_t format,uint32_t stride_align)563 static void align_plane_stride(plane_info_t *plane_info, uint8_t plane, const format_info_t format, uint32_t stride_align)
564 {
565 	plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride * format.tile_size, stride_align) / format.tile_size;
566 	plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane];
567 }
568 
569 /*
570  * Calculate allocation size.
571  *
572  * Determine the width and height of each plane based on pixel alignment for
573  * both uncompressed and AFBC allocations.
574  *
575  * @param width           [in]    Buffer width.
576  * @param height          [in]    Buffer height.
577  * @param alloc_type      [in]    Allocation type inc. whether tiled and/or multi-plane.
578  * @param format          [in]    Pixel format.
579  * @param has_cpu_usage   [in]    CPU usage requested (in addition to any other).
580  * @param has_hw_usage    [in]    HW usage requested.
581  * @param has_gpu_usage   [in]    GPU usage requested.
582  * @param has_video_usage [in]    Video usage requested.
583  * @param has_camera_usage[in]    Camera usage requested.
584  * @param pixel_stride    [out]   Calculated pixel stride.
585  * @param size            [out]   Total calculated buffer size including all planes.
586  * @param plane_info      [out]   Array of calculated information for each plane. Includes
587  *                                offset, byte stride and allocation width and height.
588  */
calc_allocation_size(const int width,const int height,const alloc_type_t alloc_type,const format_info_t format,const bool has_cpu_usage,const bool has_hw_usage,const bool has_gpu_usage,const bool has_BIG_usage,const bool has_camera_usage,uint64_t * const pixel_stride,uint64_t * const size,plane_info_t plane_info[MAX_PLANES])589 static void calc_allocation_size(const int width,
590                                  const int height,
591                                  const alloc_type_t alloc_type,
592                                  const format_info_t format,
593                                  const bool has_cpu_usage,
594                                  const bool has_hw_usage,
595                                  const bool has_gpu_usage,
596                                  const bool has_BIG_usage,
597                                  const bool has_camera_usage,
598                                  uint64_t * const pixel_stride,
599                                  uint64_t  * const size,
600                                  plane_info_t plane_info[MAX_PLANES])
601 {
602 	/* pixel_stride is set outside this function after this function is called */
603 	GRALLOC_UNUSED(pixel_stride);
604 #ifndef SOC_ZUMA
605 	GRALLOC_UNUSED(has_camera_usage);
606 #endif
607 
608 	plane_info[0].offset = 0;
609 
610 	*size = 0;
611 	for (uint8_t plane = 0; plane < format.npln; plane++)
612 	{
613 		plane_info[plane].alloc_width = width;
614 		plane_info[plane].alloc_height = height;
615 		get_pixel_w_h(&plane_info[plane].alloc_width,
616 		              &plane_info[plane].alloc_height,
617 		              format,
618 		              alloc_type,
619 		              plane,
620 		              has_cpu_usage);
621 		MALI_GRALLOC_LOGV("Aligned w=%" PRIu64 ", h=%" PRIu64 " (in pixels)",
622 		      plane_info[plane].alloc_width, plane_info[plane].alloc_height);
623 
624 		/*
625 		 * Calculate byte stride (per plane).
626 		 */
627 		if (alloc_type.is_afbc())
628 		{
629 			assert((plane_info[plane].alloc_width * format.bpp_afbc[plane]) % 8 == 0);
630 			plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp_afbc[plane]) / 8;
631 		}
632 		else
633 		{
634 			assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0);
635 			plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8;
636 
637 			/*
638 			 * Align byte stride (uncompressed allocations only).
639 			 *
640 			 * Find the lowest-common-multiple of:
641 			 * 1. hw_align: Minimum byte stride alignment for HW IP (has_hw_usage == true)
642 			 * 2. cpu_align: Byte equivalent of 'align_w_cpu' (has_cpu_usage == true)
643 			 *
644 			 * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'.
645 			 */
646 			uint32_t hw_align = 0;
647 			if (has_hw_usage)
648 			{
649 				static_assert(is_power2(YUV_BYTE_ALIGN_DEFAULT),
650 							  "YUV_BYTE_ALIGN_DEFAULT is not a power of 2");
651 				static_assert(is_power2(RGB_BYTE_ALIGN_DEFAULT),
652 							  "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
653 
654 				hw_align = format.is_yuv ?
655 					YUV_BYTE_ALIGN_DEFAULT :
656 					(format.is_rgb ? RGB_BYTE_ALIGN_DEFAULT : 0);
657 			}
658 
659 			if (has_gpu_usage)
660 			{
661 				static_assert(is_power2(GPU_BYTE_ALIGN_DEFAULT),
662 							  "RGB_BYTE_ALIGN_DEFAULT is not a power of 2");
663 
664 				/*
665 				 * The GPU requires stricter alignment on YUV and raw formats.
666 				 */
667 				hw_align = std::max(hw_align, static_cast<uint32_t>(GPU_BYTE_ALIGN_DEFAULT));
668 			}
669 
670 #ifdef SOC_ZUMA
671 			if (has_camera_usage && (format.id == MALI_GRALLOC_FORMAT_INTERNAL_RAW10 ||
672 						format.id == MALI_GRALLOC_FORMAT_INTERNAL_RAW12 ||
673 						format.id == MALI_GRALLOC_FORMAT_INTERNAL_RAW16)) {
674 				/*
675 				 * Camera ISP requires RAW buffers to have 32-byte aligned stride
676 				 */
677 				hw_align = std::max(hw_align, static_cast<uint32_t>(CAMERA_RAW_BUFFER_BYTE_ALIGN));
678 			}
679 
680 			if (has_camera_usage && format.is_yuv) {
681 				/* Camera ISP requires YUV buffers to have 64-byte aligned stride */
682 				hw_align = lcm(hw_align, static_cast<uint32_t>(CAMERA_YUV_BUFFER_BYTE_ALIGN));
683 			}
684 #endif
685 
686 			if (has_BIG_usage) {
687 				assert(has_hw_usage);
688 				hw_align = lcm(hw_align, static_cast<uint32_t>(BIG_BYTE_ALIGN_DEFAULT));
689 			}
690 
691 			uint32_t cpu_align = 0;
692 			if (has_cpu_usage && format.id != MALI_GRALLOC_FORMAT_INTERNAL_RAW10) {
693 				assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0);
694 				const bool is_primary_plane = (plane == 0 || !format.planes_contiguous);
695 				if (is_primary_plane) {
696 					cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8;
697 				}
698 			}
699 
700 			uint32_t stride_align = lcm(hw_align, cpu_align);
701 			if (stride_align)
702 			{
703 				align_plane_stride(plane_info, plane, format, stride_align);
704 			}
705 
706 #if REALIGN_YV12 == 1
707 			/*
708 			 * Update YV12 stride with both CPU & HW usage due to constraint of chroma stride.
709 			 * Width is anyway aligned to 16px for luma and chroma (has_cpu_usage).
710 			 *
711 			 * Note: To prevent luma stride misalignment with GPU stride alignment.
712 			 * The luma plane will maintain the same `stride` size, and the chroma plane
713 			 * will align to `stride/2`.
714 			 */
715 			if (format.id == MALI_GRALLOC_FORMAT_INTERNAL_YV12 && has_hw_usage && has_cpu_usage)
716 			{
717 				update_yv12_stride(plane,
718 				                   plane_info[0].byte_stride,
719 				                   stride_align,
720 				                   &plane_info[plane].byte_stride);
721 			}
722 #endif
723 		}
724 		MALI_GRALLOC_LOGV("Byte stride: %" PRIu64, plane_info[plane].byte_stride);
725 
726 		const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height)
727 		                      / AFBC_PIXELS_PER_BLOCK;
728 
729 		/*
730 		 * Calculate body size (per plane).
731 		 */
732 		size_t body_size = 0;
733 		if (alloc_type.is_afbc())
734 		{
735 			const rect_t sb = get_afbc_sb_size(alloc_type, plane);
736 			const size_t sb_bytes = GRALLOC_ALIGN((format.bpp_afbc[plane] * sb.width * sb.height) / 8, 128);
737 			body_size = sb_num * sb_bytes;
738 
739 			/* When AFBC planes are stored in separate buffers and this is not the last plane,
740 			   also align the body buffer to make the subsequent header aligned. */
741 			if (format.npln > 1 && plane < 2)
742 			{
743 				afbc_buffer_align(alloc_type.is_tiled, &body_size);
744 			}
745 
746 			if (alloc_type.is_frontbuffer_safe)
747 			{
748 				size_t back_buffer_size = body_size;
749 				afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size);
750 				body_size += back_buffer_size;
751 			}
752 		}
753 		else
754 		{
755 			if (has_BIG_usage && plane &&
756 			    (format.id == HAL_PIXEL_FORMAT_GOOGLE_NV12_SP ||
757 			     format.id == HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B))
758 			{
759 				/* Make luma and chroma planes have the same stride. */
760 				plane_info[plane].byte_stride = plane_info[0].byte_stride;
761 			}
762 			body_size = plane_info[plane].byte_stride * plane_info[plane].alloc_height;
763 		}
764 		MALI_GRALLOC_LOGV("Body size: %zu", body_size);
765 
766 
767 		/*
768 		 * Calculate header size (per plane).
769 		 */
770 		size_t header_size = 0;
771 		if (alloc_type.is_afbc())
772 		{
773 			/* As this is AFBC, calculate header size for this plane.
774 			 * Always align the header, which will make the body buffer aligned.
775 			 */
776 			header_size = sb_num * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
777 			afbc_buffer_align(alloc_type.is_tiled, &header_size);
778 		}
779 		MALI_GRALLOC_LOGV("AFBC Header size: %zu", header_size);
780 
781 		/*
782 		 * Set offset for separate chroma planes.
783 		 */
784 		if (plane > 0)
785 		{
786 			plane_info[plane].offset = *size;
787 		}
788 
789 		/*
790 		 * Set overall size.
791 		 * Size must be updated after offset.
792 		 */
793 		*size += body_size + header_size;
794 		MALI_GRALLOC_LOGV("size=%" PRIu64, *size);
795 	}
796 }
797 
798 
799 
800 /*
801  * Validate selected format against requested.
802  * Return true if valid, false otherwise.
803  */
validate_format(const format_info_t * const format,const alloc_type_t alloc_type,const buffer_descriptor_t * const bufDescriptor)804 static bool validate_format(const format_info_t * const format,
805                             const alloc_type_t alloc_type,
806                             const buffer_descriptor_t * const bufDescriptor)
807 {
808 	if (alloc_type.is_afbc())
809 	{
810 		/*
811 		 * Validate format is supported by AFBC specification and gralloc.
812 		 */
813 		if (format->afbc == false)
814 		{
815 			MALI_GRALLOC_LOGE("ERROR: AFBC selected but not supported for base format: (%s 0x%" PRIx32")",
816 				format_name(format->id), format->id);
817 			return false;
818 		}
819 
820 		/*
821 		 * Enforce consistency between number of format planes and
822 		 * request for single/multi-plane AFBC.
823 		 */
824 		if (((format->npln == 1 && alloc_type.is_multi_plane) ||
825 		    (format->npln > 1 && !alloc_type.is_multi_plane)))
826 		{
827 			MALI_GRALLOC_LOGE("ERROR: Format ((%s %" PRIx32 "), num planes: %u) is incompatible with %s-plane AFBC request",
828 				format_name(format->id), format->id, format->npln, (alloc_type.is_multi_plane) ? "multi" : "single");
829 			return false;
830 		}
831 	}
832 	else
833 	{
834 		if (format->linear == false)
835 		{
836 			MALI_GRALLOC_LOGE("ERROR: Uncompressed format requested but not supported for base format: (%s %" PRIx32 ")",
837 				format_name(format->id), format->id);
838 			return false;
839 		}
840 	}
841 
842 	if (format->id == MALI_GRALLOC_FORMAT_INTERNAL_BLOB &&
843 	    bufDescriptor->height != 1)
844 	{
845 		MALI_GRALLOC_LOGE("ERROR: Height for format BLOB must be 1.");
846 		return false;
847 	}
848 
849 	return true;
850 }
851 
prepare_descriptor_exynos_formats(buffer_descriptor_t * bufDescriptor,format_info_t format_info)852 static int prepare_descriptor_exynos_formats(
853 		buffer_descriptor_t *bufDescriptor,
854 		format_info_t format_info)
855 {
856 	int w = bufDescriptor->width;
857 	int h = bufDescriptor->height;
858 	uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
859 	int plane_count = 2;
860 	int format = MALI_GRALLOC_INTFMT_FMT_MASK & bufDescriptor->alloc_format;
861 	int fd_count = get_exynos_fd_count(format);
862 
863 	if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER))
864 	{
865 		usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
866 		bufDescriptor->producer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
867 		bufDescriptor->consumer_usage |= GRALLOC_USAGE_VIDEO_PRIVATE_DATA;
868 	}
869 
870 	/* SWBC Formats have special size requirements */
871 	switch (format)
872 	{
873 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
874 		case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
875 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
876 			plane_count = setup_sbwc_420_sp(w, h, fd_count, bufDescriptor->plane_info);
877 			break;
878 
879 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
880 		case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
881 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
882 			plane_count = setup_sbwc_420_sp_10bit(w, h, fd_count, bufDescriptor->plane_info);
883 			break;
884 
885 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
886 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
887 			plane_count = setup_sbwc_420_sp_lossy(w, h, 50, fd_count, bufDescriptor->plane_info);
888 			break;
889 
890 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
891 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
892 			plane_count = setup_sbwc_420_sp_lossy(w, h, 75, fd_count, bufDescriptor->plane_info);
893 			break;
894 
895 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
896 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
897 			plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 40, fd_count, bufDescriptor->plane_info);
898 			break;
899 
900 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
901 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
902 			plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 60, fd_count, bufDescriptor->plane_info);
903 			break;
904 
905 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
906 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
907 			plane_count = setup_sbwc_420_sp_10bit_lossy(w, h, 80, fd_count, bufDescriptor->plane_info);
908 			break;
909 
910 		case HAL_PIXEL_FORMAT_YCrCb_420_SP:
911 			h = GRALLOC_ALIGN(h, 2);
912 			plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
913 			break;
914 
915 		case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
916 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
917 			w = GRALLOC_ALIGN(w, 32);
918 			h = GRALLOC_ALIGN(h, 16);
919 			plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info);
920 			break;
921 
922 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
923 			w = GRALLOC_ALIGN(w, 16);
924 			h = GRALLOC_ALIGN(h, 32);
925 			plane_count = setup_420_sp_tiled(w, h, fd_count, bufDescriptor->plane_info);
926 			break;
927 
928 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
929 			w = GRALLOC_ALIGN(w, 16);
930 			plane_count = setup_420_p(w, h, fd_count, bufDescriptor->plane_info);
931 			break;
932 
933 		case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
934 		case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
935 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
936 			w = GRALLOC_ALIGN(w, 16);
937 			h = GRALLOC_ALIGN(h, 32);
938 			plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
939 			break;
940 
941 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
942 			w = GRALLOC_ALIGN(w, 64);
943 			h = GRALLOC_ALIGN(h, 16);
944 			plane_count = setup_420_sp(w, h, fd_count, bufDescriptor->plane_info);
945 			break;
946 
947 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
948 			/* This is 64 pixel align for now */
949 			w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
950 			h = GRALLOC_ALIGN(h, 16);
951 			plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info);
952 			break;
953 
954 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
955 			w = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
956 			h = GRALLOC_ALIGN(h, 16);
957 			plane_count = setup_420_sp_s10b(w, h, fd_count, bufDescriptor->plane_info);
958 			break;
959 
960 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
961 			w = GRALLOC_ALIGN(w, 16);
962 			h = GRALLOC_ALIGN(h, 16);
963 			plane_count = setup_p010_sp(w, h, fd_count, bufDescriptor->plane_info);
964 			break;
965 
966 		case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN:
967 			w = GRALLOC_ALIGN(w, 64);
968 			h = GRALLOC_ALIGN(h, 16);
969 			plane_count = setup_p010_sp(w, h, fd_count, bufDescriptor->plane_info);
970 			break;
971 
972 		default:
973 			MALI_GRALLOC_LOGE("invalid yuv format (%s %" PRIx64 ")", format_name(bufDescriptor->alloc_format),
974 				bufDescriptor->alloc_format);
975 			return -1;
976 	}
977 
978 	plane_info_t *plane = bufDescriptor->plane_info;
979 
980 	if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER))
981 	{
982 		if (is_sbwc_format(format))
983 		{
984 			MALI_GRALLOC_LOGE("using SBWC format (%s %" PRIx64 ") with GPU is invalid",
985 							  format_name(bufDescriptor->alloc_format),
986 							  bufDescriptor->alloc_format);
987 			return -1;
988 		}
989 		else
990 		{
991 			/*
992 			 * The GPU requires stricter alignment on YUV formats.
993 			 */
994 			for (int pidx = 0; pidx < plane_count; ++pidx)
995 			{
996 				if (plane[pidx].size == plane[pidx].byte_stride * plane[pidx].alloc_height)
997 				{
998 					align_plane_stride(plane, pidx, format_info, GPU_BYTE_ALIGN_DEFAULT);
999 					plane[pidx].size = plane[pidx].byte_stride * plane[pidx].alloc_height;
1000 				}
1001 				else
1002 				{
1003 					MALI_GRALLOC_LOGE("buffer with format (%s %" PRIx64
1004 									  ") has size %" PRIu64
1005 									  " != byte_stride %" PRIu64 " * alloc_height %" PRIu64,
1006 									  format_name(bufDescriptor->alloc_format),
1007 									  bufDescriptor->alloc_format,
1008 									  plane[pidx].size, plane[pidx].byte_stride, plane[pidx].alloc_height);
1009 				}
1010 			}
1011 		}
1012 	}
1013 
1014 	for (int fidx = 0; fidx < fd_count; fidx++)
1015 	{
1016 		uint64_t size = 0;
1017 
1018 		for (int pidx = 0; pidx < plane_count; pidx++)
1019 		{
1020 			if (plane[pidx].fd_idx == fidx)
1021 			{
1022 				size += plane[pidx].size;
1023 			}
1024 		}
1025 
1026 		/* TODO(b/183073089): Removing the following size hacks make video playback
1027 		 * fail. Need to investigate more for the root cause. Copying the original
1028 		 * comment from upstream below */
1029 		/* is there a need to check the condition for padding like in older gralloc? */
1030 		/* Add MSCL_EXT_SIZE */
1031 		/* MSCL_EXT_SIZE + MSCL_EXT_SIZE/2 + ext_size */
1032 		size += 1024;
1033 
1034 		size = size < SZ_4K ? SZ_4K : size;
1035 
1036 		bufDescriptor->alloc_sizes[fidx] = size;
1037 	}
1038 
1039 	bufDescriptor->fd_count = fd_count;
1040 	bufDescriptor->plane_count = plane_count;
1041 
1042 	return 0;
1043 }
1044 
mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor)1045 int mali_gralloc_derive_format_and_size(buffer_descriptor_t * const bufDescriptor)
1046 {
1047 	ATRACE_CALL();
1048 	alloc_type_t alloc_type{};
1049 
1050 	uint64_t alloc_width = bufDescriptor->width;
1051 	uint64_t alloc_height = bufDescriptor->height;
1052 	uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
1053 
1054 	if (!validate_descriptor(bufDescriptor)) {
1055 		return -EINVAL;
1056 	}
1057 	/*
1058 	* Select optimal internal pixel format based upon
1059 	* usage and requested format.
1060 	*/
1061 	bufDescriptor->alloc_format = mali_gralloc_select_format(bufDescriptor->hal_format,
1062 	                                                         bufDescriptor->format_type,
1063 	                                                         usage);
1064 
1065 	int base_format = bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
1066 
1067 	// TODO(b/182885532): Delete all multi-fd related dead code from gralloc
1068 	if (is_exynos_format(base_format) && get_exynos_fd_count(base_format) != 1)
1069 	{
1070 		static std::set<uint32_t> seen_formats;
1071 		if (seen_formats.find(base_format) == seen_formats.end()) {
1072 			MALI_GRALLOC_LOGW("Multi-fd format (%s 0x%" PRIx64 ") have been deprecated. Requested format: %s 0x%" PRIx64
1073 					". Consider changing the format to one of the single-fd options.",
1074 					format_name(base_format), static_cast<uint64_t>(base_format),
1075 					format_name(bufDescriptor->hal_format), bufDescriptor->hal_format);
1076 			seen_formats.insert(base_format);
1077 		}
1078 	}
1079 
1080 	if (bufDescriptor->alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED)
1081 	{
1082 		MALI_GRALLOC_LOGE("ERROR: Unrecognized and/or unsupported format (%s 0x%" PRIx64 ") and usage (%s 0x%" PRIx64 ")",
1083 				format_name(bufDescriptor->hal_format), bufDescriptor->hal_format,
1084 				describe_usage(usage).c_str(), usage);
1085 		return -EINVAL;
1086 	}
1087 
1088 	int32_t format_idx = get_format_index(base_format);
1089 	if (format_idx == -1)
1090 	{
1091 		return -EINVAL;
1092 	}
1093 	MALI_GRALLOC_LOGV("alloc_format: (%s 0x%" PRIx64 ") format_idx: %d",
1094 		format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, format_idx);
1095 
1096 	/*
1097 	 * Obtain allocation type (uncompressed, AFBC basic, etc...)
1098 	 */
1099 	if (!get_alloc_type(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK,
1100 	    format_idx, usage, &alloc_type))
1101 	{
1102 		return -EINVAL;
1103 	}
1104 
1105 	if (!validate_format(&formats[format_idx], alloc_type, bufDescriptor))
1106 	{
1107 		return -EINVAL;
1108 	}
1109 
1110 	if (is_exynos_format(base_format))
1111 	{
1112 		prepare_descriptor_exynos_formats(bufDescriptor, formats[format_idx]);
1113 	}
1114 	else
1115 	{
1116 		/*
1117 		 * Resolution of frame (allocation width and height) might require adjustment.
1118 		 * This adjustment is only based upon specific usage and pixel format.
1119 		 * If using AFBC, further adjustments to the allocation width and height will be made later
1120 		 * based on AFBC alignment requirements and, for YUV, the plane properties.
1121 		 */
1122 		mali_gralloc_adjust_dimensions(bufDescriptor->alloc_format,
1123 		                               usage,
1124 		                               &alloc_width,
1125 		                               &alloc_height);
1126 
1127 		/* Obtain buffer size and plane information. */
1128 		calc_allocation_size(alloc_width,
1129 		                     alloc_height,
1130 		                     alloc_type,
1131 		                     formats[format_idx],
1132 		                     usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
1133 		                     usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
1134 		                     usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER),
1135 		                     (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER)) && (usage & GRALLOC_USAGE_GOOGLE_IP_BIG),
1136 		                     usage & (GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_HW_CAMERA_READ),
1137 		                     &bufDescriptor->pixel_stride,
1138 		                     &bufDescriptor->alloc_sizes[0],
1139 		                     bufDescriptor->plane_info);
1140 	}
1141 
1142 	/* Set pixel stride differently for RAW formats */
1143 	switch (base_format)
1144 	{
1145 		case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
1146 		case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
1147 			bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].byte_stride;
1148 			break;
1149 		default:
1150 			bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].alloc_width;
1151 	}
1152 
1153 	/*
1154 	 * Each layer of a multi-layer buffer must be aligned so that
1155 	 * it is accessible by both producer and consumer. In most cases,
1156 	 * the stride alignment is also sufficient for each layer, however
1157 	 * for AFBC the header buffer alignment is more constrained (see
1158 	 * AFBC specification v3.4, section 2.15: "Alignment requirements").
1159 	 * Also update the buffer size to accommodate all layers.
1160 	 */
1161 	if (bufDescriptor->layer_count > 1)
1162 	{
1163 		if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
1164 		{
1165 			if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
1166 			{
1167 				bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 4096);
1168 			}
1169 			else
1170 			{
1171 				bufDescriptor->alloc_sizes[0] = GRALLOC_ALIGN(bufDescriptor->alloc_sizes[0], 128);
1172 			}
1173 		}
1174 
1175 		bufDescriptor->alloc_sizes[0] *= bufDescriptor->layer_count;
1176 	}
1177 
1178 	/* MFC requires EXT_SIZE padding */
1179 	bufDescriptor->alloc_sizes[0] += EXT_SIZE;
1180 
1181 	if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & GRALLOC_USAGE_GOOGLE_IP_BW))
1182 	{
1183 		/* BW HW requires extra padding bytes */
1184 		bufDescriptor->alloc_sizes[0] += BW_EXT_SIZE;
1185 	}
1186 
1187 	return 0;
1188 }
1189 
mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t * descriptors,uint32_t numDescriptors,buffer_handle_t * pHandle,bool * shared_backend,bool use_placeholder)1190 int mali_gralloc_buffer_allocate(const gralloc_buffer_descriptor_t *descriptors,
1191                                  uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend,
1192                                  bool use_placeholder)
1193 {
1194 	std::string atrace_log = __FUNCTION__;
1195 	if (ATRACE_ENABLED()) {
1196 		buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[0]);
1197 		std::stringstream ss;
1198 		ss << __FUNCTION__ << "(f=0x" << std::hex << bufDescriptor->hal_format << ", u=0x" <<
1199 			bufDescriptor->producer_usage << ", w=" << std::dec << bufDescriptor->width << ", h=" << bufDescriptor->height << ")";
1200 		atrace_log = ss.str();
1201 	}
1202 	ATRACE_NAME(atrace_log.c_str());
1203 
1204 	bool shared = false;
1205 	uint64_t backing_store_id = 0x0;
1206 	int err;
1207 
1208 	for (uint32_t i = 0; i < numDescriptors; i++)
1209 	{
1210 		buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
1211 
1212 		assert(bufDescriptor->producer_usage == bufDescriptor->consumer_usage);
1213 		uint64_t usage = bufDescriptor->producer_usage;
1214 		if (((usage & hidl_common::BufferUsage::VIDEO_DECODER)||(usage & hidl_common::BufferUsage::VIDEO_ENCODER)) &&
1215 		    (usage & GRALLOC_USAGE_GOOGLE_IP_BIG))
1216 		{
1217 			usage = update_usage_for_BIG(usage);
1218 			bufDescriptor->producer_usage = usage;
1219 			bufDescriptor->consumer_usage = usage;
1220 		}
1221 
1222 		/* Derive the buffer size from descriptor parameters */
1223 		err = mali_gralloc_derive_format_and_size(bufDescriptor);
1224 		if (err != 0)
1225 		{
1226 			return err;
1227 		}
1228 	}
1229 
1230 	/* Allocate ION backing store memory */
1231 	err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared, use_placeholder);
1232 	if (err < 0)
1233 	{
1234 		return err;
1235 	}
1236 
1237 	if (shared)
1238 	{
1239 		backing_store_id = getUniqueId();
1240 	}
1241 
1242 	for (uint32_t i = 0; i < numDescriptors; i++)
1243 	{
1244 		private_handle_t *hnd = (private_handle_t *)pHandle[i];
1245 
1246 		if (shared)
1247 		{
1248 			/*each buffer will share the same backing store id.*/
1249 			hnd->backing_store_id = backing_store_id;
1250 		}
1251 		else
1252 		{
1253 			/* each buffer will have an unique backing store id.*/
1254 			hnd->backing_store_id = getUniqueId();
1255 		}
1256 	}
1257 
1258 	if (NULL != shared_backend)
1259 	{
1260 		*shared_backend = shared;
1261 	}
1262 
1263 	return 0;
1264 }
1265 
mali_gralloc_buffer_free(buffer_handle_t pHandle)1266 int mali_gralloc_buffer_free(buffer_handle_t pHandle)
1267 {
1268 	auto *hnd = const_cast<private_handle_t *>(
1269 	    reinterpret_cast<const private_handle_t *>(pHandle));
1270 
1271 	if (hnd == nullptr)
1272 	{
1273 		return -1;
1274 	}
1275 
1276 	native_handle_close(hnd);
1277 	native_handle_delete(hnd);
1278 
1279 	return 0;
1280 }
1281