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