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