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