1 /*
2 * Copyright (C) 2016-2019 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 #include <inttypes.h>
20 #include <assert.h>
21 #include <atomic>
22
23 #include <cutils/properties.h>
24
25 #if GRALLOC_VERSION_MAJOR <= 1
26 #include <hardware/hardware.h>
27 #endif
28
29 #if GRALLOC_VERSION_MAJOR == 1
30 #include <hardware/gralloc1.h>
31 #elif GRALLOC_VERSION_MAJOR == 0
32 #include <hardware/gralloc.h>
33 #endif
34
35 #include "mali_gralloc_module.h"
36 #include "mali_gralloc_bufferallocation.h"
37 #include "mali_gralloc_ion.h"
38 #include "mali_gralloc_private_interface_types.h"
39 #include "mali_gralloc_buffer.h"
40 #include "gralloc_buffer_priv.h"
41 #include "mali_gralloc_bufferdescriptor.h"
42 #include "mali_gralloc_debug.h"
43 #include "format_info.h"
44
45 #define AFBC_PIXELS_PER_BLOCK 256
46 #define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY 16
47 #define EXT_SIZE 256
48
49 bool afbc_format_fallback(uint32_t * const format_idx, const uint64_t usage, bool force);
50
51
52 /*
53 * Get a global unique ID
54 */
getUniqueId()55 static uint64_t getUniqueId()
56 {
57 static std::atomic<uint32_t> counter(0);
58 uint64_t id = static_cast<uint64_t>(getpid()) << 32;
59 return id | counter++;
60 }
61
afbc_buffer_align(const bool is_tiled,int * size)62 static void afbc_buffer_align(const bool is_tiled, int *size)
63 {
64 const uint16_t AFBC_BODY_BUFFER_BYTE_ALIGNMENT = 1024;
65
66 int buffer_byte_alignment = AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
67
68 if (is_tiled)
69 {
70 buffer_byte_alignment = 4 * AFBC_BODY_BUFFER_BYTE_ALIGNMENT;
71 }
72
73 *size = GRALLOC_ALIGN(*size, buffer_byte_alignment);
74 }
75
76 /*
77 * Obtain AFBC superblock dimensions from type.
78 */
get_afbc_sb_size(AllocBaseType alloc_base_type)79 static rect_t get_afbc_sb_size(AllocBaseType alloc_base_type)
80 {
81 const uint16_t AFBC_BASIC_BLOCK_WIDTH = 16;
82 const uint16_t AFBC_BASIC_BLOCK_HEIGHT = 16;
83 const uint16_t AFBC_WIDE_BLOCK_WIDTH = 32;
84 const uint16_t AFBC_WIDE_BLOCK_HEIGHT = 8;
85 const uint16_t AFBC_EXTRAWIDE_BLOCK_WIDTH = 64;
86 const uint16_t AFBC_EXTRAWIDE_BLOCK_HEIGHT = 4;
87
88 rect_t sb = {0, 0};
89
90 switch(alloc_base_type)
91 {
92 case UNCOMPRESSED:
93 break;
94 case AFBC:
95 sb.width = AFBC_BASIC_BLOCK_WIDTH;
96 sb.height = AFBC_BASIC_BLOCK_HEIGHT;
97 break;
98 case AFBC_WIDEBLK:
99 sb.width = AFBC_WIDE_BLOCK_WIDTH;
100 sb.height = AFBC_WIDE_BLOCK_HEIGHT;
101 break;
102 case AFBC_EXTRAWIDEBLK:
103 sb.width = AFBC_EXTRAWIDE_BLOCK_WIDTH;
104 sb.height = AFBC_EXTRAWIDE_BLOCK_HEIGHT;
105 break;
106 }
107 return sb;
108 }
109
110 /*
111 * Obtain AFBC superblock dimensions for specific plane.
112 *
113 * See alloc_type_t for more information.
114 */
get_afbc_sb_size(alloc_type_t alloc_type,const uint8_t plane)115 static rect_t get_afbc_sb_size(alloc_type_t alloc_type, const uint8_t plane)
116 {
117 if (plane > 0 && alloc_type.is_afbc() && alloc_type.is_multi_plane)
118 {
119 return get_afbc_sb_size(AFBC_EXTRAWIDEBLK);
120 }
121 else
122 {
123 return get_afbc_sb_size(alloc_type.primary_type);
124 }
125 }
126
127
get_alloc_type(const uint64_t format_ext,const uint32_t format_idx,const uint64_t usage,alloc_type_t * const alloc_type)128 bool get_alloc_type(const uint64_t format_ext,
129 const uint32_t format_idx,
130 const uint64_t usage,
131 alloc_type_t * const alloc_type)
132 {
133 alloc_type->primary_type = UNCOMPRESSED;
134 alloc_type->is_multi_plane = formats[format_idx].npln > 1;
135 alloc_type->is_tiled = false;
136 alloc_type->is_padded = false;
137 alloc_type->is_frontbuffer_safe = false;
138
139 /* Determine AFBC type for this format. This is used to decide alignment.
140 Split block does not affect alignment, and therefore doesn't affect the allocation type. */
141 if (format_ext & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
142 {
143 /* YUV transform shall not be enabled for a YUV format */
144 if ((formats[format_idx].is_yuv == true) && (format_ext & MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM))
145 {
146 ALOGW("YUV Transform is incorrectly enabled for format = (%s 0x%x). Extended internal format = (%s 0x%" PRIx64 ")\n",
147 format_name(formats[format_idx].id), formats[format_idx].id, format_name(format_ext), format_ext);
148 }
149
150 /* Determine primary AFBC (superblock) type. */
151 alloc_type->primary_type = AFBC;
152 if (format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK)
153 {
154 alloc_type->primary_type = AFBC_WIDEBLK;
155 }
156 else if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
157 {
158 alloc_type->primary_type = AFBC_EXTRAWIDEBLK;
159 }
160
161 if (format_ext & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
162 {
163 alloc_type->is_tiled = true;
164
165 if (formats[format_idx].npln > 1 &&
166 (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK) == 0)
167 {
168 ALOGW("Extra-wide AFBC must be signalled for multi-plane formats. "
169 "Falling back to single plane AFBC.");
170 alloc_type->is_multi_plane = false;
171 }
172
173 if (format_ext & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY)
174 {
175 alloc_type->is_frontbuffer_safe = true;
176 }
177 }
178 else
179 {
180 if (formats[format_idx].npln > 1)
181 {
182 ALOGW("Multi-plane AFBC is not supported without tiling. "
183 "Falling back to single plane AFBC.");
184 }
185 alloc_type->is_multi_plane = false;
186 }
187
188 if (format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK &&
189 !alloc_type->is_tiled)
190 {
191 /* Headers must be tiled for extra-wide. */
192 ALOGE("ERROR: Invalid to specify extra-wide block without tiled headers.");
193 return false;
194 }
195
196 if (alloc_type->is_frontbuffer_safe &&
197 (format_ext & (MALI_GRALLOC_INTFMT_AFBC_WIDEBLK | MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)))
198 {
199 ALOGE("ERROR: Front-buffer safe not supported with wide/extra-wide block.");
200 }
201
202 if (formats[format_idx].npln == 1 &&
203 format_ext & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK &&
204 format_ext & MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK)
205 {
206 /* "Wide + Extra-wide" implicitly means "multi-plane". */
207 ALOGE("ERROR: Invalid to specify multiplane AFBC with single plane format.");
208 return false;
209 }
210
211 if (usage & MALI_GRALLOC_USAGE_AFBC_PADDING)
212 {
213 alloc_type->is_padded = true;
214 }
215 }
216
217 return true;
218 }
219
220 /*
221 * Initialise AFBC header based on superblock layout.
222 * Width and height should already be AFBC aligned.
223 */
init_afbc(uint8_t * buf,const uint64_t alloc_format,const bool is_multi_plane,const int w,const int h)224 void init_afbc(uint8_t *buf, const uint64_t alloc_format,
225 const bool is_multi_plane,
226 const int w, const int h)
227 {
228 const bool is_tiled = ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
229 == MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS);
230 const uint32_t n_headers = (w * h) / AFBC_PIXELS_PER_BLOCK;
231 int body_offset = n_headers * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
232
233 afbc_buffer_align(is_tiled, &body_offset);
234
235 /*
236 * Declare the AFBC header initialisation values for each superblock layout.
237 * Tiled headers (AFBC 1.2) can be initialised to zero for non-subsampled formats
238 * (SB layouts: 0, 3, 4, 7).
239 */
240 uint32_t headers[][4] = {
241 { (uint32_t)body_offset, 0x1, 0x10000, 0x0 }, /* Layouts 0, 3, 4, 7 */
242 { ((uint32_t)body_offset + (1 << 28)), 0x80200040, 0x1004000, 0x20080 } /* Layouts 1, 5 */
243 };
244 if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS))
245 {
246 /* Zero out body_offset for non-subsampled formats. */
247 memset(headers[0], 0, sizeof(uint32_t) * 4);
248 }
249
250 /* Map base format to AFBC header layout */
251 const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
252
253 /* Sub-sampled formats use layouts 1 and 5 which is index 1 in the headers array.
254 * 1 = 4:2:0 16x16, 5 = 4:2:0 32x8.
255 *
256 * Non-subsampled use layouts 0, 3, 4 and 7, which is index 0.
257 * 0 = 16x16, 3 = 32x8 + split, 4 = 32x8, 7 = 64x4.
258 *
259 * When using separated planes for YUV formats, the header layout is the non-subsampled one
260 * as there is a header per-plane and there is no sub-sampling within the plane.
261 * Separated plane only supports 32x8 or 64x4 for the luma plane, so the first plane must be 4 or 7.
262 * Seperated plane only supports 64x4 for subsequent planes, so these must be header layout 7.
263 */
264 const uint32_t layout = is_subsampled_yuv(base_format) && !is_multi_plane ? 1 : 0;
265
266 ALOGV("Writing AFBC header layout %d for format (%s %" PRIx32 ")", layout, format_name(base_format), base_format);
267
268 for (uint32_t i = 0; i < n_headers; i++)
269 {
270 memcpy(buf, headers[layout], sizeof(headers[layout]));
271 buf += sizeof(headers[layout]);
272 }
273 }
274
max(int a,int b)275 static int max(int a, int b)
276 {
277 return a > b ? a : b;
278 }
279
max(int a,int b,int c)280 static int max(int a, int b, int c)
281 {
282 return c > max(a, b) ? c : max(a, b);
283 }
284
max(int a,int b,int c,int d)285 static int max(int a, int b, int c, int d)
286 {
287 return d > max(a, b, c) ? d : max(a, b, c);
288 }
289
290 /*
291 * Obtain plane allocation dimensions (in pixels).
292 *
293 * NOTE: pixel stride, where defined for format, is
294 * incorporated into allocation dimensions.
295 */
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)296 static void get_pixel_w_h(uint32_t * const width,
297 uint32_t * const height,
298 const format_info_t format,
299 const alloc_type_t alloc_type,
300 const uint8_t plane,
301 bool has_cpu_usage)
302 {
303 const rect_t sb = get_afbc_sb_size(alloc_type, plane);
304
305 /*
306 * Round-up plane dimensions, to multiple of:
307 * - Samples for all channels (sub-sampled formats)
308 * - Memory bytes/words (some packed formats)
309 */
310 if (plane == 0 || !format.planes_contiguous)
311 {
312 *width = GRALLOC_ALIGN(*width, format.align_w);
313 *height = GRALLOC_ALIGN(*height, format.align_h);
314 }
315
316 /*
317 * Sub-sample (sub-sampled) planes.
318 */
319 if (plane > 0)
320 {
321 *width /= format.hsub;
322 *height /= format.vsub;
323 }
324
325 /*
326 * Pixel alignment (width),
327 * where format stride is stated in pixels.
328 */
329 int pixel_align_w = 0, pixel_align_h = 0;
330 if (has_cpu_usage && (plane == 0 || !format.planes_contiguous))
331 {
332 pixel_align_w = format.align_w_cpu;
333 }
334 else if (alloc_type.is_afbc())
335 {
336 #define HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS (0)
337 uint32_t num_sb_align = 0;
338 if (alloc_type.is_padded && !format.is_yuv)
339 {
340 /* Align to 4 superblocks in width --> 64-byte,
341 * assuming 16-byte header per superblock.
342 */
343 num_sb_align = 4;
344 }
345 pixel_align_w = max(HEADER_STRIDE_ALIGN_IN_SUPER_BLOCKS, num_sb_align) * sb.width;
346 }
347
348 /*
349 * Determine AFBC tile size when allocating tiled headers.
350 */
351 rect_t afbc_tile = sb;
352 if (alloc_type.is_tiled)
353 {
354 afbc_tile.width = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.width : 8 * afbc_tile.width;
355 afbc_tile.height = format.bpp_afbc[plane] > 32 ? 4 * afbc_tile.height : 8 * afbc_tile.height;
356 }
357
358 if (AFBC_WIDEBLK == alloc_type.primary_type && !alloc_type.is_tiled)
359 {
360 /*
361 * Special case for wide block (32x8) AFBC with linear (non-tiled)
362 * headers: hardware reads and writes 32x16 blocks so we need to
363 * pad the body buffer accordingly.
364 *
365 * Note that this branch will not be taken for multi-plane AFBC
366 * since that requires tiled headers.
367 */
368 pixel_align_h = max(pixel_align_h, 16);
369 }
370
371 ALOGV("Plane[%hhu]: [SUB-SAMPLE] w:%d, h:%d\n", plane, *width, *height);
372 ALOGV("Plane[%hhu]: [PIXEL_ALIGN] w:%d, h:%d\n", plane, pixel_align_w, pixel_align_h);
373 ALOGV("Plane[%hhu]: [LINEAR_TILE] w:%" PRIu16 "\n", plane, format.tile_size);
374 ALOGV("Plane[%hhu]: [AFBC_TILE] w:%" PRIu16 ", h:%" PRIu16 "\n", plane, afbc_tile.width, afbc_tile.height);
375
376 *width = GRALLOC_ALIGN(*width, max(1, pixel_align_w, format.tile_size, afbc_tile.width));
377 *height = GRALLOC_ALIGN(*height, max(1, pixel_align_h, format.tile_size, afbc_tile.height));
378
379 }
380
381
382
gcd(uint32_t a,uint32_t b)383 static uint32_t gcd(uint32_t a, uint32_t b)
384 {
385 uint32_t r, t;
386
387 if (a == b)
388 {
389 return a;
390 }
391 else if (a < b)
392 {
393 t = a;
394 a = b;
395 b = t;
396 }
397
398 while (b != 0)
399 {
400 r = a % b;
401 a = b;
402 b = r;
403 }
404
405 return a;
406 }
407
lcm(uint32_t a,uint32_t b)408 uint32_t lcm(uint32_t a, uint32_t b)
409 {
410 if (a != 0 && b != 0)
411 {
412 return (a * b) / gcd(a, b);
413 }
414
415 return max(a, b);
416 }
417
418
419 /*
420 * YV12 stride has additional complexity since chroma stride
421 * must conform to the following:
422 *
423 * c_stride = ALIGN(stride/2, 16)
424 *
425 * Since the stride alignment must satisfy both CPU and HW
426 * constraints, the luma stride must be doubled.
427 */
update_yv12_stride(int8_t plane,uint32_t luma_stride,uint32_t stride_align,uint32_t * byte_stride)428 static void update_yv12_stride(int8_t plane,
429 uint32_t luma_stride,
430 uint32_t stride_align,
431 uint32_t * byte_stride)
432 {
433 if (plane == 0)
434 {
435 /*
436 * Ensure luma stride is aligned to "2*lcm(hw_align, cpu_align)" so
437 * that chroma stride can satisfy both CPU and HW alignment
438 * constraints when only half luma stride (as mandated for format).
439 */
440 *byte_stride = GRALLOC_ALIGN(luma_stride, 2 * stride_align);
441 }
442 else
443 {
444 /*
445 * Derive chroma stride from luma and verify it is:
446 * 1. Aligned to lcm(hw_align, cpu_align)
447 * 2. Multiple of 16px (16 bytes)
448 */
449 *byte_stride = luma_stride / 2;
450 assert(*byte_stride == GRALLOC_ALIGN(*byte_stride, stride_align));
451 assert(*byte_stride & 15 == 0);
452 }
453 }
454
455
456 /*
457 * Calculate allocation size.
458 *
459 * Determine the width and height of each plane based on pixel alignment for
460 * both uncompressed and AFBC allocations.
461 *
462 * @param width [in] Buffer width.
463 * @param height [in] Buffer height.
464 * @param alloc_type [in] Allocation type inc. whether tiled and/or multi-plane.
465 * @param format [in] Pixel format.
466 * @param has_cpu_usage [in] CPU usage requested (in addition to any other).
467 * @param size [out] Total calculated buffer size including all planes.
468 * @param plane_info [out] Array of calculated information for each plane. Includes
469 * offset, byte stride and allocation width and height.
470 */
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,size_t * const size,plane_info_t plane_info[MAX_PLANES])471 static void calc_allocation_size(const int width,
472 const int height,
473 const alloc_type_t alloc_type,
474 const format_info_t format,
475 const bool has_cpu_usage,
476 const bool has_hw_usage,
477 size_t * const size,
478 plane_info_t plane_info[MAX_PLANES])
479 {
480 plane_info[0].offset = 0;
481
482 *size = 0;
483 for (uint8_t plane = 0; plane < format.npln; plane++)
484 {
485 plane_info[plane].alloc_width = width;
486 plane_info[plane].alloc_height = height;
487 get_pixel_w_h(&plane_info[plane].alloc_width,
488 &plane_info[plane].alloc_height,
489 format,
490 alloc_type,
491 plane,
492 has_cpu_usage);
493 ALOGV("Aligned w=%d, h=%d (in pixels)",
494 plane_info[plane].alloc_width, plane_info[plane].alloc_height);
495
496 /*
497 * Calculate byte stride (per plane).
498 */
499 if (alloc_type.is_afbc())
500 {
501 assert((plane_info[plane].alloc_width * format.bpp_afbc[plane]) % 8 == 0);
502 plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp_afbc[plane]) / 8;
503 }
504 else
505 {
506 assert((plane_info[plane].alloc_width * format.bpp[plane]) % 8 == 0);
507 plane_info[plane].byte_stride = (plane_info[plane].alloc_width * format.bpp[plane]) / 8;
508
509 /*
510 * Align byte stride (uncompressed allocations only).
511 *
512 * Find the lowest-common-multiple of:
513 * 1. hw_align: Minimum byte stride alignment for HW IP (has_hw_usage == true)
514 * 2. cpu_align: Byte equivalent of 'align_w_cpu' (has_cpu_usage == true)
515 *
516 * NOTE: Pixel stride is defined as multiple of 'align_w_cpu'.
517 */
518 uint16_t hw_align = 0;
519 if (has_hw_usage)
520 {
521 hw_align = format.is_yuv ? 16 : (format.is_rgb ? 64 : 0);
522 }
523
524 uint32_t cpu_align = 0;
525 assert((format.bpp[plane] * format.align_w_cpu) % 8 == 0);
526 if (plane == 0 || !format.planes_contiguous)
527 cpu_align = (format.bpp[plane] * format.align_w_cpu) / 8;
528
529 uint32_t stride_align = lcm(hw_align, cpu_align);
530 if (stride_align)
531 {
532 plane_info[plane].byte_stride = GRALLOC_ALIGN(plane_info[plane].byte_stride, stride_align);
533 plane_info[plane].alloc_width = plane_info[plane].byte_stride * 8 / format.bpp[plane];
534 }
535
536 /*
537 * Update YV12 stride with both CPU & HW usage due to constraint of chroma stride.
538 * Width is anyway aligned to 16px for luma and chroma (has_cpu_usage).
539 */
540 /*
541 * This function can make yv12 align to 32 pixels or higher.
542 * Some apps do not use the provided stride value when a buffer is created
543 * Those apps may assume yv12 buffers are aligned to 32 pixels.
544 * So do not call this function.
545 if (format.id == MALI_GRALLOC_FORMAT_INTERNAL_YV12 && has_hw_usage && has_cpu_usage)
546 {
547 update_yv12_stride(plane,
548 plane_info[0].byte_stride,
549 stride_align,
550 &plane_info[plane].byte_stride);
551 }
552 */
553 GRALLOC_UNUSED(update_yv12_stride);
554 }
555 ALOGV("Byte stride: %d", plane_info[plane].byte_stride);
556
557 /*
558 * Pixel stride (CPU usage only).
559 * Not used in size calculation but exposed to client.
560 */
561 if (plane == 0)
562 {
563 assert((plane_info[plane].byte_stride * 8) % format.bpp[plane] == 0);
564 ALOGV("Pixel stride: %d", (plane_info[plane].byte_stride * 8) / format.bpp[plane]);
565 }
566
567 const uint32_t sb_num = (plane_info[plane].alloc_width * plane_info[plane].alloc_height)
568 / AFBC_PIXELS_PER_BLOCK;
569
570 /*
571 * Calculate body size (per plane).
572 */
573 int body_size = 0;
574 if (alloc_type.is_afbc())
575 {
576 const rect_t sb = get_afbc_sb_size(alloc_type, plane);
577 const int sb_bytes = GRALLOC_ALIGN((format.bpp_afbc[plane] * sb.width * sb.height) / 8, 128);
578 body_size = sb_num * sb_bytes;
579
580 /* When AFBC planes are stored in separate buffers and this is not the last plane,
581 also align the body buffer to make the subsequent header aligned. */
582 if (format.npln > 1 && plane < 2)
583 {
584 afbc_buffer_align(alloc_type.is_tiled, &body_size);
585 }
586
587 if (alloc_type.is_frontbuffer_safe)
588 {
589 int back_buffer_size = body_size;
590 afbc_buffer_align(alloc_type.is_tiled, &back_buffer_size);
591 body_size += back_buffer_size;
592 }
593 }
594 else
595 {
596 body_size = (plane_info[plane].byte_stride) * plane_info[plane].alloc_height;
597 }
598 ALOGV("Body size: %d", body_size);
599
600
601 /*
602 * Calculate header size (per plane).
603 */
604 int header_size = 0;
605 if (alloc_type.is_afbc())
606 {
607 /* As this is AFBC, calculate header size for this plane.
608 * Always align the header, which will make the body buffer aligned.
609 */
610 header_size = sb_num * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY;
611 afbc_buffer_align(alloc_type.is_tiled, &header_size);
612 }
613 ALOGV("AFBC Header size: %d", header_size);
614
615 /*
616 * Set offset for separate chroma planes.
617 */
618 if (plane > 0)
619 {
620 plane_info[plane].offset = *size;
621 }
622
623 /*
624 * Set overall size.
625 * Size must be updated after offset.
626 */
627 *size += body_size + header_size;
628 ALOGV("size=%zu",*size);
629 }
630 }
631
632
633
634 /*
635 * Validate selected format against requested.
636 * Return true if valid, false otherwise.
637 */
validate_format(const format_info_t * const format,const alloc_type_t alloc_type,const buffer_descriptor_t * const bufDescriptor)638 static bool validate_format(const format_info_t * const format,
639 const alloc_type_t alloc_type,
640 const buffer_descriptor_t * const bufDescriptor)
641 {
642 if (alloc_type.is_afbc())
643 {
644 /*
645 * Validate format is supported by AFBC specification and gralloc.
646 */
647 if (format->afbc == false)
648 {
649 ALOGE("ERROR: AFBC selected but not supported for base format: (%s 0x%" PRIx32")",
650 format_name(format->id), format->id);
651 return false;
652 }
653
654 /*
655 * Enforce consistency between number of format planes and
656 * request for single/multi-plane AFBC.
657 */
658 if (((format->npln == 1 && alloc_type.is_multi_plane) ||
659 (format->npln > 1 && !alloc_type.is_multi_plane)))
660 {
661 ALOGE("ERROR: Format ((%s %" PRIx32 "), num planes: %u) is incompatible with %s-plane AFBC request",
662 format_name(format->id), format->id, format->npln, (alloc_type.is_multi_plane) ? "multi" : "single");
663 return false;
664 }
665 }
666 else
667 {
668 if (format->linear == false)
669 {
670 ALOGE("ERROR: Uncompressed format requested but not supported for base format: (%s %" PRIx32 ")",
671 format_name(format->id), format->id);
672 return false;
673 }
674 }
675
676 if (format->id == MALI_GRALLOC_FORMAT_INTERNAL_BLOB &&
677 bufDescriptor->height != 1)
678 {
679 ALOGE("ERROR: Height for format BLOB must be 1.");
680 return false;
681 }
682
683 return true;
684 }
685
color_space_for_dimensions(int width,int height)686 static int color_space_for_dimensions(int width, int height) {
687 auto [sm, lg] = std::minmax(width, height);
688 int64_t area = static_cast<int64_t>(sm) * static_cast<int64_t>(lg);
689
690 if ((lg >= 3840) || (sm >= 3840) || (area >= (3840ll * 1634ll)))
691 {
692 return HAL_DATASPACE_STANDARD_BT2020;
693 }
694
695 if (lg <= 720)
696 {
697 if (sm <= 480)
698 {
699 return HAL_DATASPACE_STANDARD_BT601_525;
700 }
701
702 if (sm <= 576)
703 {
704 return HAL_DATASPACE_STANDARD_BT601_625;
705 }
706 }
707
708 return HAL_DATASPACE_STANDARD_BT709;
709 }
710
set_dataspace(private_handle_t * const hnd,uint64_t usage,int32_t format_idx)711 static int set_dataspace(private_handle_t * const hnd, uint64_t usage, int32_t format_idx)
712 {
713 int color_space = HAL_DATASPACE_STANDARD_UNSPECIFIED;
714 int range = HAL_DATASPACE_RANGE_UNSPECIFIED;
715 int data_space = 0;
716 hnd->yuv_info = MALI_YUV_NO_INFO;
717 int rval = -1;
718 int width = hnd->width;
719 int height = hnd->height;
720
721 static int csc_supported = -1;
722
723 if (csc_supported == -1)
724 {
725 csc_supported = property_get_int32("ro.vendor.gpu.dataspace", 0);
726 #ifdef GRALLOC_NO_CSC_SUPPORTED
727 csc_supported = 0;
728 #endif
729 }
730
731 if (gralloc_buffer_attr_map(hnd, true) < 0)
732 {
733 ALOGE("Failed to map attribute region.");
734 goto out;
735 }
736
737 if (!csc_supported)
738 {
739 if (formats[format_idx].is_yuv)
740 {
741 color_space = HAL_DATASPACE_STANDARD_BT601_625;
742 range = HAL_DATASPACE_RANGE_LIMITED;
743 hnd->yuv_info = MALI_YUV_BT601_NARROW;
744
745 /* Special cases for Camera producers */
746 switch (hnd->format)
747 {
748 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
749 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
750 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
751 {
752 range = HAL_DATASPACE_RANGE_FULL;
753 hnd->yuv_info = MALI_YUV_BT601_WIDE;
754 }
755 }
756
757 data_space = color_space | range;
758 }
759 else
760 {
761 data_space = HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL;
762 }
763
764 gralloc_buffer_attr_write(hnd, GRALLOC_ARM_BUFFER_ATTR_FORCE_DATASPACE, &data_space);
765 }
766 else if (formats[format_idx].is_yuv)
767 {
768 /* Default YUV dataspace. */
769 color_space = HAL_DATASPACE_STANDARD_BT709;
770 range = HAL_DATASPACE_RANGE_LIMITED;
771
772 /* SDR 10-bit YUV is assumed to be narrow BT709.
773 * Dataspace for HDR content will be set (by producer) according to the HDR metadata.
774 */
775 if (formats[format_idx].bps >= 10)
776 {
777 color_space = HAL_DATASPACE_STANDARD_BT2020;
778 }
779 else
780 {
781 color_space = color_space_for_dimensions(width, height);
782 }
783
784 #if GRALLOC_VERSION_MAJOR >= 1
785 /* Override YUV dataspace based on private usage. */
786 switch (usage & MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_MASK)
787 {
788 case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT601:
789 color_space = HAL_DATASPACE_STANDARD_BT601_625;
790 break;
791 case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT709:
792 color_space = HAL_DATASPACE_STANDARD_BT709;
793 break;
794 case MALI_GRALLOC_USAGE_YUV_COLOR_SPACE_BT2020:
795 color_space = HAL_DATASPACE_STANDARD_BT2020;
796 break;
797 }
798
799 switch (usage & MALI_GRALLOC_USAGE_RANGE_MASK)
800 {
801 case MALI_GRALLOC_USAGE_RANGE_NARROW:
802 range = HAL_DATASPACE_RANGE_LIMITED;
803 break;
804 case MALI_GRALLOC_USAGE_RANGE_WIDE:
805 range = HAL_DATASPACE_RANGE_FULL;
806 break;
807 }
808
809 /* Special cases for Camera producers */
810 switch (hnd->format)
811 {
812 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
813 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
814 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
815 {
816 color_space = HAL_DATASPACE_STANDARD_BT601_625;
817 range = HAL_DATASPACE_RANGE_FULL;
818 }
819 }
820
821 data_space = color_space | range;
822
823 /* Set deprecated yuv_info field. */
824 switch (color_space)
825 {
826 case HAL_DATASPACE_STANDARD_BT601_625:
827 if (range == HAL_DATASPACE_RANGE_LIMITED)
828 {
829 hnd->yuv_info = MALI_YUV_BT601_NARROW;
830 }
831 else
832 {
833 hnd->yuv_info = MALI_YUV_BT601_WIDE;
834 }
835 break;
836 case HAL_DATASPACE_STANDARD_BT709:
837 if (range == HAL_DATASPACE_RANGE_LIMITED)
838 {
839 hnd->yuv_info = MALI_YUV_BT709_NARROW;
840 }
841 else
842 {
843 hnd->yuv_info = MALI_YUV_BT709_WIDE;
844 }
845 break;
846 }
847 #endif
848 }
849 else if (formats[format_idx].is_rgb)
850 {
851 /* Default RGB dataspace. */
852 data_space = HAL_DATASPACE_STANDARD_BT709 | HAL_DATASPACE_RANGE_FULL;
853 }
854
855 gralloc_buffer_attr_write(hnd, GRALLOC_ARM_BUFFER_ATTR_DATASPACE, &data_space);
856
857 gralloc_buffer_attr_unmap(hnd);
858
859 rval = 0;
860 out:
861 return rval;
862 }
863
864 /*
865 * Compute SBWC buffer geometry for a buffer containing packed SBWC YUV data
866 * with bits per pixel bpp, width w, and height h.
867 * Returns a pair of { luma size, chroma size }.
868 */
869 template <int bpp>
sbwc_sizes(int w,int h)870 static std::pair<size_t, size_t> sbwc_sizes(int w, int h) {
871 static_assert(bpp == 8 || bpp == 10, "Unexpected bit width");
872
873 const size_t luma_body_size = (bpp == 8) ?
874 SBWC_8B_Y_SIZE(w, h) : SBWC_10B_Y_SIZE(w, h);
875 const size_t luma_header_size = (bpp == 8) ?
876 SBWC_8B_Y_HEADER_SIZE(w, h) : SBWC_10B_Y_HEADER_SIZE(w, h);
877
878 const size_t chroma_body_size = (bpp == 8) ?
879 SBWC_8B_CBCR_SIZE(w, h) : SBWC_10B_CBCR_SIZE(w, h);
880 const size_t chroma_header_size = (bpp == 8) ?
881 SBWC_8B_CBCR_HEADER_SIZE(w, h) : SBWC_10B_CBCR_HEADER_SIZE(w, h);
882
883 ALOGV("SBWC luma body size 0x%zx, header size 0x%zx", luma_body_size, luma_header_size);
884 ALOGV("SBWC chroma body size 0x%zx, header size 0x%zx", chroma_body_size, chroma_header_size);
885
886 return { luma_body_size + luma_header_size,
887 chroma_body_size + chroma_header_size };
888 }
889
prepare_descriptor_exynos_formats(buffer_descriptor_t * bufDescriptor)890 static int prepare_descriptor_exynos_formats(buffer_descriptor_t *bufDescriptor)
891 {
892 size_t luma_size=0, chroma_size=0, ext_size=256;
893 int fd_count = 1;
894 int stride = 0, byte_stride = 0;
895 size_t luma_vstride = 0;
896 // Keep around original requested format for later validation
897 int w = bufDescriptor->width;
898 int h = bufDescriptor->height;
899 uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
900 int is_multiplane = 1;
901
902 // Set default stride
903 stride = GRALLOC_ALIGN(w, 16);
904 luma_vstride = GRALLOC_ALIGN(h, 16);
905 byte_stride = stride;
906
907 if (usage & (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER))
908 {
909 usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA;
910 bufDescriptor->producer_usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA;
911 bufDescriptor->consumer_usage |= GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA;
912 }
913
914 /* SWBC Formats have special size requirements */
915 switch ((uint32_t)bufDescriptor->internal_format)
916 {
917 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
918 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
919 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
920 {
921 std::tie(luma_size, chroma_size) = sbwc_sizes<8>(w, h);
922 byte_stride = SBWC_8B_STRIDE(w);
923 stride = GRALLOC_ALIGN(w, 32);
924 luma_vstride = __ALIGN_UP(h, 8);
925
926 break;
927 }
928 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
929 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
930 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
931 {
932 std::tie(luma_size, chroma_size) = sbwc_sizes<10>(w, h);
933 byte_stride = SBWC_10B_STRIDE(w);
934 stride = GRALLOC_ALIGN(w, 32);
935 luma_vstride = __ALIGN_UP(h, 8);
936
937 break;
938 }
939 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
940 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
941 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
942 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
943 {
944 uint32_t r = 100;
945
946 switch ((uint32_t)bufDescriptor->internal_format)
947 {
948 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
949 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
950 r = 50;
951 break;
952 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
953 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
954 r = 75;
955 break;
956 }
957
958 luma_size = SBWCL_8B_Y_SIZE(w, h, r);
959 chroma_size = SBWCL_8B_CBCR_SIZE(w, h, r);
960
961 /* How to set this information for lossy formats? */
962 byte_stride = SBWCL_8B_STRIDE(w, r);
963
964 stride = GRALLOC_ALIGN(w, 32);
965 luma_vstride = __ALIGN_UP(h, 8);
966 break;
967 }
968 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
969 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
970 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
971 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
972 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
973 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
974 {
975 uint32_t r = 100;
976
977 switch ((uint32_t)bufDescriptor->internal_format)
978 {
979 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
980 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
981 r = 40;
982 break;
983 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
984 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
985 r = 60;
986 break;
987 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
988 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
989 r = 80;
990 break;
991 }
992
993 luma_size = SBWCL_10B_Y_SIZE(w, h, r);
994 chroma_size = SBWCL_10B_CBCR_SIZE(w, h, r);
995
996 byte_stride = SBWCL_10B_STRIDE(w, r);
997
998 stride = GRALLOC_ALIGN(w, 32);
999 luma_vstride = __ALIGN_UP(h, 8);
1000
1001 break;
1002 }
1003 }
1004
1005 // Decide plane count and sizes
1006 switch ((uint32_t)bufDescriptor->internal_format)
1007 {
1008 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
1009 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
1010 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
1011 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
1012 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
1013 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
1014 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
1015 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
1016 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
1017 {
1018 fd_count = 2;
1019 break;
1020 }
1021 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
1022 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
1023 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
1024 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
1025 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
1026 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
1027 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
1028 {
1029 luma_size += chroma_size;
1030 chroma_size = 0;
1031
1032 fd_count = 1;
1033 break;
1034 }
1035 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1036 {
1037 stride = w;
1038 byte_stride = stride;
1039 luma_size = PLANE_SIZE(stride , h * 3 / 2, ext_size);
1040 luma_vstride = h;
1041 fd_count = 1;
1042 break;
1043 }
1044 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1045 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1046 {
1047 stride = GRALLOC_ALIGN(w, 32);
1048 byte_stride = stride;
1049 luma_size = PLANE_SIZE(stride, luma_vstride, ext_size);
1050 #ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
1051 chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size);
1052 #else
1053 chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), (luma_vstride / 2), ext_size);
1054 #endif
1055 fd_count = 3;
1056 break;
1057 }
1058 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1059 {
1060 size_t chroma_vstride = GRALLOC_ALIGN(h / 2, 32);
1061 luma_vstride = GRALLOC_ALIGN(h, 32);
1062 luma_size = PLANE_SIZE(stride, luma_vstride, ext_size);
1063 chroma_size = PLANE_SIZE(stride, chroma_vstride, ext_size);
1064 byte_stride = stride * 16;
1065 fd_count = 2;
1066 break;
1067 }
1068 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
1069 {
1070 /* Same as HAL_PIXEL_FORMAT_YV12 */
1071 chroma_size = PLANE_SIZE(GRALLOC_ALIGN(stride / 2, 16), h, ext_size);
1072 luma_size = PLANE_SIZE(stride, h, 0) + chroma_size;
1073 is_multiplane = 0;
1074 fd_count = 1;
1075 break;
1076 }
1077 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1078 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1079 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1080 {
1081 if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA)
1082 {
1083 luma_vstride = GRALLOC_ALIGN(h, 32);
1084 }
1085
1086 luma_size = PLANE_SIZE(stride, luma_vstride, ext_size);
1087 #ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
1088 chroma_size = PLANE_SIZE(stride, GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size);
1089 #else
1090 chroma_size = PLANE_SIZE(stride, luma_vstride / 2, ext_size);
1091 #endif
1092 fd_count = 2;
1093
1094 break;
1095 }
1096 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
1097 {
1098 #ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
1099 chroma_size = NV12N_S8B_CHROMA_SIZE(stride, GRALLOC_ALIGN(luma_vstride / 2, CHROMA_VALIGN), ext_size);
1100 #else
1101 chroma_size = NV12N_S8B_CHROMA_SIZE(stride, luma_vstride / 2, ext_size);
1102 #endif
1103 luma_size = NV12N_S8B_LUMA_SIZE(stride, luma_vstride, ext_size) + chroma_size;
1104
1105 fd_count = 1;
1106 break;
1107 }
1108 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
1109 {
1110 stride = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
1111 byte_stride = stride;
1112 luma_size = NV12M_S8B_SIZE(stride, luma_vstride, ext_size) + NV12M_S2B_LUMA_SIZE(w, h, ext_size);
1113 chroma_size = NV12M_S8B_SIZE(stride, luma_vstride / 2, ext_size) + NV12M_S2B_CHROMA_SIZE(w, h, ext_size);
1114 fd_count = 2;
1115 break;
1116 }
1117 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
1118 {
1119 stride = GRALLOC_ALIGN(w, BOARD_EXYNOS_S10B_FORMAT_ALIGN);
1120 byte_stride = stride;
1121 chroma_size = NV12N_S8B_CHROMA_SIZE(stride, luma_vstride / 2, ext_size) + NV12N_S2B_SIZE(w, luma_vstride / 2);
1122 luma_size = NV12N_S8B_LUMA_SIZE(stride, luma_vstride, ext_size) + NV12N_S2B_SIZE(w, luma_vstride) + chroma_size;
1123 fd_count = 1;
1124 break;
1125 }
1126 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
1127 {
1128 chroma_size = P010_PLANE_SIZE(stride, luma_vstride / 2, ext_size);
1129 luma_size = P010_PLANE_SIZE(stride, luma_vstride, ext_size);
1130 byte_stride = stride * 2;
1131 fd_count = 2;
1132 break;
1133 }
1134 default:
1135 AERR("invalid yuv format %x\n", (uint32_t)bufDescriptor->internal_format);
1136 return -1;
1137 }
1138
1139 switch ((uint32_t)bufDescriptor->internal_format)
1140 {
1141 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
1142 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
1143 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
1144 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
1145 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
1146 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
1147 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1148 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1149 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1150 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
1151 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
1152 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
1153 if (usage & GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA)
1154 bufDescriptor->alloc_video_private_data = 1;
1155
1156 break;
1157 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
1158 bufDescriptor->alloc_video_private_data = 1;
1159 }
1160
1161 // Add MSCL_EXT_SIZE
1162 if (w % MSCL_ALIGN)
1163 {
1164 luma_size += MSCL_EXT_SIZE;
1165 chroma_size += MSCL_EXT_SIZE/2;
1166 }
1167
1168 for (int i = 0; i < fd_count; i++)
1169 {
1170 size_t alloc_height = i == 0 ? luma_vstride : (luma_vstride / 2);
1171 size_t size = i == 0 ? luma_size : chroma_size;
1172
1173 #ifdef GRALLOC_MSCL_ALLOC_RESTRICTION
1174 size = size < SIZE_4K ? SIZE_4K : size;
1175 #endif
1176 bufDescriptor->sizes[i] = size;
1177
1178 bufDescriptor->plane_info[i].alloc_width = stride;
1179 bufDescriptor->plane_info[i].alloc_height = alloc_height;
1180 bufDescriptor->plane_info[i].byte_stride = byte_stride;
1181 bufDescriptor->plane_info[i].offset = 0;
1182 }
1183
1184 bufDescriptor->fd_count = fd_count;
1185
1186 return 0;
1187 }
1188
1189
mali_gralloc_derive_format_and_size(mali_gralloc_module * m,buffer_descriptor_t * const bufDescriptor)1190 int mali_gralloc_derive_format_and_size(mali_gralloc_module *m,
1191 buffer_descriptor_t * const bufDescriptor)
1192 {
1193 GRALLOC_UNUSED(m);
1194 alloc_type_t alloc_type;
1195 static bool warn_about_mutual_exclusive = true;
1196
1197 int alloc_width = bufDescriptor->width;
1198 int alloc_height = bufDescriptor->height;
1199 uint64_t usage = bufDescriptor->producer_usage | bufDescriptor->consumer_usage;
1200
1201 /*
1202 * Select optimal internal pixel format based upon
1203 * usage and requested format.
1204 */
1205 bufDescriptor->alloc_format = mali_gralloc_select_format(bufDescriptor->hal_format,
1206 bufDescriptor->format_type,
1207 usage,
1208 bufDescriptor->width * bufDescriptor->height,
1209 &bufDescriptor->internal_format);
1210 if (bufDescriptor->alloc_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED)
1211 {
1212 ALOGE("ERROR: Unrecognized and/or unsupported format 0x%" PRIx64 " and usage 0x%" PRIx64,
1213 bufDescriptor->hal_format, usage);
1214 return -EINVAL;
1215 }
1216 else if (warn_about_mutual_exclusive &&
1217 (bufDescriptor->alloc_format & 0x0000000100000000ULL) &&
1218 (bufDescriptor->alloc_format & 0x0000000e00000000ULL))
1219 {
1220 /*
1221 * Modifier bits are no longer mutually exclusive. Warn when
1222 * any bits are set in addition to AFBC basic since these might
1223 * have been handled differently by clients under the old scheme.
1224 * AFBC basic is guaranteed to be signalled when any other AFBC
1225 * flags are set.
1226 * This flag is to avoid the mutually exclusive modifier bits warning
1227 * being continuously emitted. (see comment below for explanation of warning).
1228 */
1229 warn_about_mutual_exclusive = false;
1230 ALOGW("WARNING: internal format modifier bits not mutually exclusive. "
1231 "AFBC basic bit is always set, so extended AFBC support bits must always be checked.");
1232 }
1233
1234 int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
1235 if (format_idx == -1)
1236 {
1237 return -EINVAL;
1238 }
1239 ALOGV("alloc_format: (%s 0x%" PRIx64 ") format_idx: %d",
1240 format_name(bufDescriptor->alloc_format), bufDescriptor->alloc_format, format_idx);
1241
1242 /*
1243 * Obtain allocation type (uncompressed, AFBC basic, etc...)
1244 */
1245 if (!get_alloc_type(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_EXT_MASK,
1246 format_idx, usage, &alloc_type))
1247 {
1248 return -EINVAL;
1249 }
1250
1251 if (!validate_format(&formats[format_idx], alloc_type, bufDescriptor))
1252 {
1253 return -EINVAL;
1254 }
1255
1256 if (is_exynos_format((uint32_t)bufDescriptor->alloc_format))
1257 {
1258 prepare_descriptor_exynos_formats(bufDescriptor);
1259 }
1260 else
1261 {
1262 /*
1263 * Resolution of frame (allocation width and height) might require adjustment.
1264 * This adjustment is only based upon specific usage and pixel format.
1265 * If using AFBC, further adjustments to the allocation width and height will be made later
1266 * based on AFBC alignment requirements and, for YUV, the plane properties.
1267 */
1268 mali_gralloc_adjust_dimensions(bufDescriptor->alloc_format,
1269 usage,
1270 &alloc_width,
1271 &alloc_height);
1272
1273 /* Obtain buffer size and plane information. */
1274 calc_allocation_size(alloc_width,
1275 alloc_height,
1276 alloc_type,
1277 formats[format_idx],
1278 usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
1279 usage & ~(GRALLOC_USAGE_PRIVATE_MASK | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK),
1280 &bufDescriptor->size,
1281 bufDescriptor->plane_info);
1282
1283 }
1284
1285 bufDescriptor->plane_count = formats[format_idx].npln;
1286
1287 switch ((uint32_t)bufDescriptor->alloc_format)
1288 {
1289 case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
1290 case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
1291 // RAW10 image width needs to be multiple of 16 so that the data can be CPU accessed
1292 // in 32bit unit
1293 if (bufDescriptor->width % 16 != 0) {
1294 ALOGE("ERROR: Width for HAL_PIXEL_FORMAT_RAW10 buffers has to be multiple of 16.");
1295 return -EINVAL;
1296 }
1297 // TODO: revert this back when b/152045385 is fixed.
1298 bufDescriptor->pixel_stride = bufDescriptor->width * 5 / 4;
1299 break;
1300 default:
1301 bufDescriptor->pixel_stride = bufDescriptor->plane_info[0].alloc_width;
1302 }
1303
1304 /*
1305 * Each layer of a multi-layer buffer must be aligned so that
1306 * it is accessible by both producer and consumer. In most cases,
1307 * the stride alignment is also sufficient for each layer, however
1308 * for AFBC the header buffer alignment is more constrained (see
1309 * AFBC specification v3.4, section 2.15: "Alignment requirements").
1310 * Also update the buffer size to accommodate all layers.
1311 */
1312 if (bufDescriptor->layer_count > 1)
1313 {
1314 if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK)
1315 {
1316 if (bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS)
1317 {
1318 bufDescriptor->size = GRALLOC_ALIGN(bufDescriptor->size, 4096);
1319 }
1320 else
1321 {
1322 bufDescriptor->size = GRALLOC_ALIGN(bufDescriptor->size, 128);
1323 }
1324 }
1325
1326 bufDescriptor->size *= bufDescriptor->layer_count;
1327 }
1328
1329 /* MFC requires EXT_SIZE padding */
1330 bufDescriptor->size += EXT_SIZE;
1331
1332 #ifdef GRALLOC_MSCL_ALIGN_RESTRICTION
1333 if (bufDescriptor->width % MSCL_ALIGN)
1334 {
1335 bufDescriptor->size += MSCL_EXT_SIZE;
1336 }
1337 #endif
1338
1339 ALOGV("size after padding = %zu %zu %zu", bufDescriptor->sizes[0], bufDescriptor->sizes[1], bufDescriptor->sizes[2]);
1340
1341 return 0;
1342 }
1343
1344
mali_gralloc_buffer_allocate(mali_gralloc_module * m,const gralloc_buffer_descriptor_t * descriptors,uint32_t numDescriptors,buffer_handle_t * pHandle,bool * shared_backend)1345 int mali_gralloc_buffer_allocate(mali_gralloc_module *m, const gralloc_buffer_descriptor_t *descriptors,
1346 uint32_t numDescriptors, buffer_handle_t *pHandle, bool *shared_backend)
1347 {
1348 bool shared = false;
1349 uint64_t backing_store_id = 0x0;
1350 int err;
1351
1352 for (uint32_t i = 0; i < numDescriptors; i++)
1353 {
1354 buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)(descriptors[i]);
1355
1356 err = mali_gralloc_derive_format_and_size(m, bufDescriptor);
1357 if (err != 0)
1358 {
1359 return err;
1360 }
1361 }
1362
1363 /* Allocate ION backing store memory */
1364 err = mali_gralloc_ion_allocate(descriptors, numDescriptors, pHandle, &shared);
1365 if (err < 0)
1366 {
1367 return err;
1368 }
1369
1370 if (shared)
1371 {
1372 backing_store_id = getUniqueId();
1373 }
1374
1375 for (uint32_t i = 0; i < numDescriptors; i++)
1376 {
1377 buffer_descriptor_t * const bufDescriptor = (buffer_descriptor_t *)descriptors[i];
1378 private_handle_t *hnd = (private_handle_t *)pHandle[i];
1379 uint64_t usage = bufDescriptor->consumer_usage | bufDescriptor->producer_usage;
1380
1381 err = gralloc_buffer_attr_allocate(hnd);
1382
1383 if (err < 0)
1384 {
1385 /* free all allocated ion buffer& attr buffer here.*/
1386 for (int idx = 0; idx < numDescriptors; idx++)
1387 {
1388 mali_gralloc_buffer_free(pHandle[idx]);
1389 }
1390 return err;
1391 }
1392
1393 mali_gralloc_dump_buffer_add(hnd);
1394
1395 const int32_t format_idx = get_format_index(bufDescriptor->alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
1396 if (format_idx == -1)
1397 {
1398 return -EINVAL;
1399 }
1400 const int ret = set_dataspace(hnd, usage, format_idx);
1401 if (ret < 0)
1402 {
1403 return ret;
1404 }
1405
1406 #if GRALLOC_ARM_NO_EXTERNAL_AFBC == 0
1407 int afbc_prop = property_get_int32("ro.vendor.ddk.set.afbc", 0);
1408
1409 if (afbc_prop == 1 && hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
1410 {
1411 hnd->is_compressible = 1;
1412
1413 int *mapAddr = (int*)mmap(0, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fds[1], 0);
1414 if(mapAddr == NULL || mapAddr == MAP_FAILED)
1415 {
1416 int errnum = errno;
1417 ALOGE("Unable to mmap fd %d errno: %s", hnd->fds[1], strerror(errnum));
1418 hnd->is_compressible = 0;
1419 hnd->alloc_format = ((uint64_t)hnd->alloc_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK);
1420 hnd->internal_format = ((uint64_t)hnd->internal_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK);
1421 }
1422 else
1423 {
1424 #define AFBC_INFO_SIZE (sizeof(int))
1425 #define AFBC_ENABLE (0xafbc)
1426 int afbc_flag = AFBC_ENABLE;
1427 memcpy(mapAddr, &afbc_flag, AFBC_INFO_SIZE);
1428 munmap(mapAddr, sizeof(int));
1429 }
1430 }
1431 else
1432 {
1433 hnd->is_compressible = 0;
1434 hnd->alloc_format = ((uint64_t)hnd->alloc_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK);
1435 hnd->internal_format = ((uint64_t)hnd->internal_format & ~MALI_GRALLOC_INTFMT_AFBCENABLE_MASK);
1436 }
1437 #endif
1438
1439 if (shared)
1440 {
1441 /*each buffer will share the same backing store id.*/
1442 hnd->backing_store_id = backing_store_id;
1443 }
1444 else
1445 {
1446 /* each buffer will have an unique backing store id.*/
1447 hnd->backing_store_id = getUniqueId();
1448 }
1449 }
1450
1451 if (NULL != shared_backend)
1452 {
1453 *shared_backend = shared;
1454 }
1455
1456 return 0;
1457 }
1458
mali_gralloc_buffer_free(buffer_handle_t pHandle)1459 int mali_gralloc_buffer_free(buffer_handle_t pHandle)
1460 {
1461 int rval = -1;
1462 private_handle_t * const hnd = (private_handle_t * const)(pHandle);
1463
1464 if (hnd != NULL)
1465 {
1466 rval = gralloc_buffer_attr_free(hnd);
1467 mali_gralloc_ion_free(hnd);
1468 }
1469
1470 return rval;
1471 }
1472