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 #include <string.h>
20 #include <dlfcn.h>
21 #include <inttypes.h>
22 #include <log/log.h>
23 #include <assert.h>
24 #include <vector>
25 #include <cutils/properties.h>
26
27 #include "gralloc_priv.h"
28 #include "mali_gralloc_bufferallocation.h"
29 #include "mali_gralloc_usages.h"
30 #include "format_info.h"
31 #include "capabilities/gralloc_capabilities.h"
32 #include "exynos_format.h"
33
34 /* Producer/consumer definitions.
35 * CPU: Software access
36 * GPU: Graphics processor
37 * DPU: Display processor
38 * VPU: Video processor
39 * CAM: Camera ISP
40 * TPU: ML accelerator
41 */
42 #define MALI_GRALLOC_PRODUCER_CPU ((uint16_t)1 << 0)
43 #define MALI_GRALLOC_PRODUCER_GPU ((uint16_t)1 << 1)
44 #define MALI_GRALLOC_PRODUCER_DPU ((uint16_t)1 << 2)
45 #define MALI_GRALLOC_PRODUCER_VPU ((uint16_t)1 << 4)
46 #define MALI_GRALLOC_PRODUCER_CAM ((uint16_t)1 << 5)
47 #define GOOGLE_GRALLOC_PRODUCER_BO ((uint16_t)1 << 6)
48 #define GOOGLE_GRALLOC_PRODUCER_MFC ((uint16_t)1 << 7)
49 #define GOOGLE_GRALLOC_PRODUCER_VPUS_MASK (MALI_GRALLOC_PRODUCER_VPU | GOOGLE_GRALLOC_PRODUCER_BO | GOOGLE_GRALLOC_PRODUCER_MFC)
50 #define GOOGLE_GRALLOC_PRODUCER_TPU ((uint16_t)1 << 8)
51
52 #define MALI_GRALLOC_CONSUMER_CPU ((uint16_t)1 << 0)
53 #define MALI_GRALLOC_CONSUMER_GPU ((uint16_t)1 << 1)
54 #define MALI_GRALLOC_CONSUMER_DPU ((uint16_t)1 << 2)
55 #define MALI_GRALLOC_CONSUMER_VPU ((uint16_t)1 << 3)
56 #define GOOGLE_GRALLOC_CONSUMER_BO ((uint16_t)1 << 4)
57 #define GOOGLE_GRALLOC_CONSUMER_MFC ((uint16_t)1 << 5)
58 #define GOOGLE_GRALLOC_CONSUMER_VPUS_MASK (MALI_GRALLOC_CONSUMER_VPU | GOOGLE_GRALLOC_CONSUMER_BO | GOOGLE_GRALLOC_CONSUMER_MFC)
59 #define GOOGLE_GRALLOC_CONSUMER_TPU ((uint16_t)1 << 6)
60
61 typedef struct
62 {
63 uint32_t base_format;
64 uint64_t format_ext;
65 format_support_flags f_flags;
66 } fmt_props;
67
68 /*
69 * Video encoder consumer can be signalled by a combination of usage flags
70 * Besides VIDEO_ENCODER, clients can specify the specific IP block they belong
71 * to, for fine-grained control over capabilities.
72 *
73 * @param usage [in] Buffer usage.
74 *
75 * @return The corresponding consumer flag, or 0 if the consumer is not a VPU.
76 */
get_vpu_consumer(uint64_t usage)77 static uint16_t get_vpu_consumer(uint64_t usage)
78 {
79 if (!(usage & hidl_common::BufferUsage::VIDEO_ENCODER))
80 return 0;
81
82 /* When both the BO and MFC flags are present, the assumption is BO is the
83 producer and MFC is the consumer. There is no use case as of now in which
84 MFC is the producer and BO is the consumer. */
85 if (usage & GRALLOC_USAGE_GOOGLE_IP_MFC)
86 return GOOGLE_GRALLOC_CONSUMER_MFC;
87
88 if (usage & GRALLOC_USAGE_GOOGLE_IP_BO)
89 return GOOGLE_GRALLOC_CONSUMER_BO;
90
91 // TODO(b/185896428): Support 64-bits usage version for GraphicBufferSource
92 return GOOGLE_GRALLOC_CONSUMER_MFC;
93 }
94
95 /*
96 * Determines all IP consumers included by the requested buffer usage.
97 * Private usage flags are excluded from this process.
98 *
99 * @param usage [in] Buffer usage.
100 *
101 * @return flags word of all enabled consumers;
102 * 0, if no consumers are enabled
103 */
get_consumers(uint64_t usage)104 static uint16_t get_consumers(uint64_t usage)
105 {
106 uint16_t consumers = 0;
107
108 if (usage & GS101_GRALLOC_USAGE_TPU_INPUT)
109 {
110 consumers |= GOOGLE_GRALLOC_CONSUMER_TPU;
111 }
112
113 /* Exclude usages also not applicable to consumer derivation */
114 usage &= ~GRALLOC_USAGE_PROTECTED;
115
116 get_ip_capabilities();
117
118 if ((usage & GRALLOC_USAGE_PUBLIC_MASK) == GRALLOC_USAGE_HW_COMPOSER)
119 {
120 consumers = MALI_GRALLOC_CONSUMER_DPU;
121 }
122 else
123 {
124 if (usage & GRALLOC_USAGE_SW_READ_MASK)
125 {
126 consumers |= MALI_GRALLOC_CONSUMER_CPU;
127 }
128
129 /* GRALLOC_USAGE_HW_FB describes a framebuffer which contains a
130 * pre-composited scene that is scanned-out to a display. This buffer
131 * can be consumed by even the most basic display processor which does
132 * not support multi-layer composition.
133 */
134 if (usage & GRALLOC_USAGE_HW_FB)
135 {
136 consumers |= MALI_GRALLOC_CONSUMER_DPU;
137 }
138
139 consumers |= get_vpu_consumer(usage);
140
141 /* GRALLOC_USAGE_HW_COMPOSER does not explicitly define whether the
142 * display processor is producer or consumer. When used in combination
143 * with GRALLOC_USAGE_HW_TEXTURE, it is assumed to be consumer since the
144 * GPU and DPU both act as compositors.
145 */
146 if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) ==
147 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER))
148 {
149 consumers |= MALI_GRALLOC_CONSUMER_DPU;
150 }
151
152 if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_GPU_DATA_BUFFER))
153 {
154 consumers |= MALI_GRALLOC_CONSUMER_GPU;
155 }
156 }
157
158 return consumers;
159 }
160
161 /*
162 * Video decoder producer can be signalled by a combination of usage flags
163 * Besides VIDEO_DECODER, clients can specify the specific IP block they belong
164 * to, for fine-grained control over capabilities.
165 *
166 * @param usage [in] Buffer usage.
167 *
168 * @return The corresponding producer flag, or 0 if the producer is not a VPU.
169 */
get_vpu_producer(uint64_t usage)170 static uint16_t get_vpu_producer(uint64_t usage)
171 {
172 if (!(usage & hidl_common::BufferUsage::VIDEO_DECODER))
173 return 0;
174
175 /* When both the BO and MFC flags are present, the assumption is BO is the
176 producer and MFC is the consumer. There is no use case as of now in which
177 MFC is the producer and BO is the consumer. */
178 if (usage & GRALLOC_USAGE_GOOGLE_IP_BO)
179 return GOOGLE_GRALLOC_PRODUCER_BO;
180
181 if (usage & GRALLOC_USAGE_GOOGLE_IP_MFC)
182 return GOOGLE_GRALLOC_PRODUCER_MFC;
183
184 MALI_GRALLOC_LOGV("Video producer IP not specified, falling back to default VPU producer");
185 return MALI_GRALLOC_PRODUCER_VPU;
186 }
187
188 /*
189 * Determines all IP producers included by the requested buffer usage.
190 * Private usage flags are excluded from this process.
191 *
192 * @param usage [in] Buffer usage.
193 *
194 * @return flags word of all enabled producers;
195 * 0, if no producers are enabled
196 */
get_producers(uint64_t usage)197 static uint16_t get_producers(uint64_t usage)
198 {
199 uint16_t producers = 0;
200
201 if (usage & GS101_GRALLOC_USAGE_TPU_OUTPUT)
202 {
203 producers |= GOOGLE_GRALLOC_PRODUCER_TPU;
204 }
205
206 /* Exclude usages also not applicable to producer derivation */
207 usage &= ~GRALLOC_USAGE_PROTECTED;
208
209 get_ip_capabilities();
210
211 if (usage & GRALLOC_USAGE_SW_WRITE_MASK)
212 {
213 producers |= MALI_GRALLOC_PRODUCER_CPU;
214 }
215
216 /* DPU is normally consumer however, when there is an alternative
217 * consumer (VPU) and no other producer (e.g. VPU), it acts as a producer.
218 */
219 if ((usage & GRALLOC_USAGE_DECODER) != GRALLOC_USAGE_DECODER &&
220 (usage & (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) ==
221 (GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER))
222 {
223 producers |= MALI_GRALLOC_PRODUCER_DPU;
224 }
225
226 if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_GPU_DATA_BUFFER))
227 {
228 producers |= MALI_GRALLOC_PRODUCER_GPU;
229 }
230
231 if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
232 {
233 producers |= MALI_GRALLOC_PRODUCER_CAM;
234 }
235
236 producers |= get_vpu_producer(usage);
237
238 return producers;
239 }
240
consumers_use_cpu_caps(uint16_t consumers)241 static inline bool consumers_use_cpu_caps(uint16_t consumers)
242 {
243 return consumers & (MALI_GRALLOC_CONSUMER_CPU | GOOGLE_GRALLOC_CONSUMER_TPU);
244 }
245
producers_use_cpu_caps(uint16_t producers)246 static inline bool producers_use_cpu_caps(uint16_t producers)
247 {
248 return producers & (MALI_GRALLOC_PRODUCER_CPU | GOOGLE_GRALLOC_PRODUCER_TPU);
249 }
250
251 /*
252 * Determines the intersection of all IP consumers capability sets. Since all
253 * capabiltiies are positive, the intersection can be expressed via a logical
254 * AND operation. Capabilities must be defined (OPTIONS_PRESENT) to indicate
255 * that an IP is part of the media system (otherwise it will be ignored).
256 * See definition of MALI_GRALLOC_FORMAT_CAPABILITY_* for more information.
257 *
258 * @param consumers [in] Buffer consumers.
259 *
260 * @return flags word of common capabilities shared by *all* consumers;
261 * 0, if no capabilities are shared
262 */
get_consumer_caps(const uint16_t consumers)263 static uint64_t get_consumer_caps(const uint16_t consumers)
264 {
265 uint64_t consumer_caps = ~0;
266
267 get_ip_capabilities();
268
269 /* Consumers can't write */
270 consumer_caps &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE;
271
272 if (consumers_use_cpu_caps(consumers))
273 {
274 consumer_caps &= cpu_runtime_caps.caps_mask;
275 }
276
277 if (consumers & MALI_GRALLOC_CONSUMER_GPU &&
278 gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
279 {
280 consumer_caps &= gpu_runtime_caps.caps_mask;
281 }
282
283 if (consumers & MALI_GRALLOC_CONSUMER_DPU &&
284 dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
285 {
286 consumer_caps &= dpu_runtime_caps.caps_mask;
287 }
288
289 if (consumers & MALI_GRALLOC_CONSUMER_VPU &&
290 vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
291 {
292 consumer_caps &= vpu_runtime_caps.caps_mask;
293 }
294
295 if (consumers & GOOGLE_GRALLOC_CONSUMER_BO &&
296 bo_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
297 {
298 consumer_caps &= bo_runtime_caps.caps_mask;
299 }
300
301 if (consumers & GOOGLE_GRALLOC_CONSUMER_MFC &&
302 mfc_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
303 {
304 consumer_caps &= mfc_runtime_caps.caps_mask;
305 }
306
307 /* TODO: if consumers is 0, set consumer_caps to 0 as well */
308
309 return consumer_caps;
310 }
311
312
313 /*
314 * Determines the intersection of all IP producers capability sets. Since all
315 * capabiltiies are positive, the intersection can be expressed via a logical
316 * AND operation. Capabilities must be defined (OPTIONS_PRESENT) to indicate
317 * that an IP is part of the media system (otherwise it will be ignored).
318 * See definition of MALI_GRALLOC_FORMAT_CAPABILITY_* for more information.
319 *
320 * @param producers [in] Buffer producers.
321 *
322 * @return flags word of common capabilities shared by *all* producers;
323 * 0, if no capabilities are shared
324 */
get_producer_caps(const uint16_t producers)325 static uint64_t get_producer_caps(const uint16_t producers)
326 {
327 uint64_t producer_caps = ~0;
328
329 if (producers == 0)
330 {
331 /* When no producer is specified assume no capabilities. */
332 return 0;
333 }
334
335 get_ip_capabilities();
336
337 /* Producers can't read */
338 producer_caps &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ;
339
340 if (producers_use_cpu_caps(producers))
341 {
342 producer_caps &= cpu_runtime_caps.caps_mask;
343 }
344
345 if (producers & MALI_GRALLOC_PRODUCER_GPU &&
346 gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
347 {
348 producer_caps &= gpu_runtime_caps.caps_mask;
349 }
350
351 if (producers & MALI_GRALLOC_PRODUCER_DPU &&
352 dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
353 {
354 producer_caps &= dpu_runtime_caps.caps_mask;
355 }
356
357 if (producers & MALI_GRALLOC_PRODUCER_CAM &&
358 cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
359 {
360 producer_caps &= cam_runtime_caps.caps_mask;
361 }
362
363 if (producers & MALI_GRALLOC_PRODUCER_VPU &&
364 vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
365 {
366 producer_caps &= vpu_runtime_caps.caps_mask;
367 }
368
369 if (producers & GOOGLE_GRALLOC_PRODUCER_BO &&
370 bo_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
371 {
372 producer_caps &= bo_runtime_caps.caps_mask;
373 }
374
375 if (producers & GOOGLE_GRALLOC_PRODUCER_MFC &&
376 mfc_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
377 {
378 producer_caps &= mfc_runtime_caps.caps_mask;
379 }
380
381 return producer_caps;
382 }
383
384
385 /*
386 * Update buffer dimensions for producer/consumer constraints. This process is
387 * not valid with CPU producer/consumer since the new resolution cannot be
388 * communicated to generic clients through the public APIs. Adjustments are
389 * likely to be related to AFBC.
390 *
391 * @param alloc_format [in] Format (inc. modifiers) to be allocated.
392 * @param usage [in] Buffer usage.
393 * @param width [inout] Buffer width (in pixels).
394 * @param height [inout] Buffer height (in pixels).
395 *
396 * @return none.
397 */
mali_gralloc_adjust_dimensions(const uint64_t alloc_format,const uint64_t usage,int * const width,int * const height)398 void mali_gralloc_adjust_dimensions(const uint64_t alloc_format,
399 const uint64_t usage,
400 int* const width,
401 int* const height)
402 {
403 /* Determine producers. */
404 const uint16_t producers = get_producers(usage);
405
406 /*
407 * Video producer requires additional height padding of AFBC buffers (whole
408 * rows of 16x16 superblocks). Cropping will be applied to internal
409 * dimensions to fit the public size.
410 */
411 if ((producers & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK) &&
412 (alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC))
413 {
414 const int32_t idx = get_format_index(alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK);
415 if (idx != -1)
416 {
417 /* 8-bit/10-bit YUV420 formats. */
418 if (formats[idx].is_yuv && formats[idx].hsub == 2 && formats[idx].vsub == 2)
419 {
420 *height += (alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) ? 16 : 32;
421 }
422 }
423 }
424
425 if (producers & MALI_GRALLOC_PRODUCER_GPU)
426 {
427 /* Pad all AFBC allocations to multiple of GPU tile size. */
428 if (alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC)
429 {
430 *width = GRALLOC_ALIGN(*width, 16);
431 *height = GRALLOC_ALIGN(*height, 16);
432 }
433 }
434
435 MALI_GRALLOC_LOGV("%s: alloc_format=(%s 0x%" PRIx64 ") usage=(%s 0x%" PRIx64
436 ") alloc_width=%u, alloc_height=%u",
437 __FUNCTION__, format_name(alloc_format), alloc_format, describe_usage(usage).c_str(),
438 usage, *width, *height);
439 }
440
441
442 /*
443 * Obtain level of support for base format across all producers and consumers as
444 * defined by IP support table. This support is defined for the most capable IP -
445 * specific IP might have reduced support based on specific capabilities.
446 *
447 * @param producers [in] Producers (flags).
448 * @param consumers [in] Consumers (flags).
449 * @param format [in] Format entry in IP support table.
450 *
451 * @return format support flags.
452 */
ip_supports_base_format(const uint16_t producers,const uint16_t consumers,const format_ip_support_t * const format)453 static format_support_flags ip_supports_base_format(const uint16_t producers,
454 const uint16_t consumers,
455 const format_ip_support_t * const format)
456 {
457 format_support_flags support = ~0;
458
459 /* Determine producer support for base format. */
460 if (producers_use_cpu_caps(producers))
461 {
462 support &= format->cpu_wr;
463 }
464 if (producers & MALI_GRALLOC_PRODUCER_GPU)
465 {
466 support &= format->gpu_wr;
467 }
468 if (producers & MALI_GRALLOC_PRODUCER_DPU)
469 {
470 support &= format->dpu_wr;
471 }
472 if (producers & MALI_GRALLOC_PRODUCER_CAM)
473 {
474 support &= format->cam_wr;
475 }
476 if (producers & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK)
477 {
478 support &= format->vpu_wr;
479 }
480
481 /* Determine consumer support for base format. */
482 if (consumers_use_cpu_caps(consumers))
483 {
484 support &= format->cpu_rd;
485 }
486 if (consumers & MALI_GRALLOC_CONSUMER_GPU)
487 {
488 support &= format->gpu_rd;
489 }
490 if (consumers & MALI_GRALLOC_CONSUMER_DPU)
491 {
492 support &= format->dpu_rd;
493 }
494 if (consumers & GOOGLE_GRALLOC_CONSUMER_VPUS_MASK)
495 {
496 support &= format->vpu_rd;
497 }
498
499 return support;
500 }
501
502
503 /*
504 * Determines whether a base format is subsampled YUV, where each
505 * chroma channel has fewer samples than the luma channel. The
506 * sub-sampling is always a power of 2.
507 *
508 * @param base_format [in] Base format (internal).
509 *
510 * @return 1, where format is subsampled YUV;
511 * 0, otherwise
512 */
is_subsampled_yuv(const uint32_t base_format)513 bool is_subsampled_yuv(const uint32_t base_format)
514 {
515 unsigned long i;
516
517 for (i = 0; i < num_formats; i++)
518 {
519 if (formats[i].id == (base_format & MALI_GRALLOC_INTFMT_FMT_MASK))
520 {
521 if (formats[i].is_yuv == true &&
522 (formats[i].hsub > 1 || formats[i].vsub > 1))
523 {
524 return true;
525 }
526 }
527 }
528 return false;
529 }
530
531
532 /*
533 * Determines whether multi-plane AFBC (requires specific IP capabiltiies) is
534 * supported across all producers and consumers.
535 *
536 * @param producers [in] Producers (flags).
537 * @param consumers [in] Consumers (flags).
538 * @param producer_caps [in] Producer capabilities (flags).
539 * @param consumer_caps [in] Consumer capabilities (flags).
540 *
541 * @return 1, multiplane AFBC is supported
542 * 0, otherwise
543 */
is_afbc_multiplane_supported(const uint16_t producers,const uint16_t consumers,const uint64_t producer_caps,const uint64_t consumer_caps)544 static inline bool is_afbc_multiplane_supported(const uint16_t producers,
545 const uint16_t consumers,
546 const uint64_t producer_caps,
547 const uint64_t consumer_caps)
548 {
549 GRALLOC_UNUSED(consumers);
550
551 return (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
552 producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
553 producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_EXTRAWIDEBLK &&
554 /*no_producer*/ consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_MULTIPLANE_READ &&
555 producers == 0) ? true : false;
556 }
557
558
559 /*
560 * Determines whether a given base format is supported by all producers and
561 * consumers. After checking broad support across producer/consumer IP, this
562 * function uses capabilities to disable features (base formats and AFBC
563 * modifiers) that are not supported by specific versions of each IP.
564 *
565 * @param fmt_idx [in] Index into format properties table (base format).
566 * @param ip_fmt_idx [in] Index into format IP support table (base format).
567 * @param usage [in] Buffer usage.
568 * @param producers [in] Producers (flags).
569 * @param consumers [in] Consumers (flags).
570 * @param producer_caps [in] Producer capabilities (flags).
571 * @param consumer_caps [in] Consumer capabilities (flags).
572 *
573 * @return format support flags.
574 */
is_format_supported(const int32_t fmt_idx,const int32_t ip_fmt_idx,const uint64_t usage,const uint16_t producers,const uint16_t consumers,const uint64_t producer_caps,const uint64_t consumer_caps)575 static format_support_flags is_format_supported(const int32_t fmt_idx,
576 const int32_t ip_fmt_idx,
577 const uint64_t usage,
578 const uint16_t producers,
579 const uint16_t consumers,
580 const uint64_t producer_caps,
581 const uint64_t consumer_caps)
582 {
583 /* Determine format support from table. */
584 format_support_flags f_flags = ip_supports_base_format(producers, consumers,
585 &formats_ip_support[ip_fmt_idx]);
586
587 /* Determine whether producers/consumers support required AFBC features. */
588 if (f_flags & F_AFBC)
589 {
590 if (!formats[fmt_idx].afbc ||
591 (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) == 0)
592 {
593 f_flags &= ~F_AFBC;
594 }
595
596 /* Check that multi-plane format supported by producers/consumers. */
597 if (formats[fmt_idx].npln > 1 &&
598 !is_afbc_multiplane_supported(producers, consumers, producer_caps, consumer_caps))
599 {
600 f_flags &= ~F_AFBC;
601 }
602
603 /* Apply some additional restrictions from producer_caps and consumer_caps */
604 /* Some modifiers affect base format support */
605 if (formats[fmt_idx].is_yuv)
606 {
607 if ((producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE) == 0)
608 {
609 f_flags &= ~F_AFBC;
610 }
611
612 if ((consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ) == 0)
613 {
614 f_flags &= ~F_AFBC;
615 }
616 }
617
618 if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER)
619 {
620 if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY) == 0)
621 {
622 f_flags &= ~F_AFBC;
623 }
624 }
625 }
626 if (f_flags != F_NONE)
627 {
628 if (formats[fmt_idx].id == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_1010102 &&
629 (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA1010102) == 0)
630 {
631 /* TODO: forcing F_LIN is a W/A. Make a proper solution */
632 f_flags = F_NONE;
633 f_flags = F_LIN;
634 }
635 else if (formats[fmt_idx].id == MALI_GRALLOC_FORMAT_INTERNAL_RGBA_16161616)
636 {
637 if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_PIXFMT_RGBA16161616) == 0)
638 {
639 /* TODO: forcing F_LIN is a W/A. Make a proper solution */
640 //f_flags = F_NONE;
641 f_flags = F_LIN;
642 }
643 else if ((producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_RGBA16161616) == 0)
644 {
645 f_flags = F_LIN;
646 }
647 }
648 }
649
650 return f_flags;
651 }
652
653
654 /*
655 * Ensures that the allocation format conforms to the AFBC specification and is
656 * supported by producers and consumers. Format modifiers are (in most cases)
657 * disabled as required to make valid. It is important to first resolve invalid
658 * combinations which are not dependent upon others to reduce the possibility of
659 * circular dependency.
660 *
661 * @param alloc_format [in] Allocation format (base + modifiers).
662 * @param producer_active_caps [in] Producer capabilities (flags).
663 * @param consumer_active_caps [in] Consumer capabilities (flags).
664 *
665 * @return valid alloc_format with AFBC possibly disabled (if required)
666 */
validate_afbc_format(uint64_t alloc_format,const uint64_t producer_active_caps,const uint64_t consumer_active_caps)667 static uint64_t validate_afbc_format(uint64_t alloc_format,
668 const uint64_t producer_active_caps,
669 const uint64_t consumer_active_caps)
670 {
671 const uint32_t base_format = alloc_format & MALI_GRALLOC_INTFMT_FMT_MASK;
672
673 /*
674 * AFBC with tiled-headers must be enabled for AFBC front-buffer-safe allocations.
675 * NOTE: format selection algorithm will always try and enable AFBC with
676 * tiled-headers where supported by producer(s) and consumer(s).
677 */
678 if (alloc_format & MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY)
679 {
680 /*
681 * Disable (extra-) wide-block which is unsupported with front-buffer safe AFBC.
682 */
683 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_WIDEBLK;
684 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK;
685 }
686
687 /*
688 * AFBC specification: Split-block is not supported for
689 * subsampled formats (YUV) when wide-block is enabled.
690 */
691 if (alloc_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK &&
692 alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK &&
693 is_subsampled_yuv(base_format))
694 {
695 /* Disable split-block instead of wide-block because because
696 * wide-block has greater impact on display performance.
697 */
698 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
699 }
700
701 /* AFBC specification: Split-block must be enabled for
702 * non-subsampled formats > 16 bpp, where wide-block is enabled.
703 */
704 if (alloc_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK &&
705 (alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) == 0 &&
706 !is_subsampled_yuv(base_format) &&
707 base_format != MALI_GRALLOC_FORMAT_INTERNAL_RGB_565)
708 {
709 /* Enable split-block if supported by producer(s) & consumer(s),
710 * otherwise disable wide-block.
711 */
712 if (producer_active_caps & consumer_active_caps &
713 MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
714 {
715 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
716 }
717 else
718 {
719 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_WIDEBLK;
720 }
721 }
722
723 /* Some RGB formats don't support split block. */
724 if (base_format == MALI_GRALLOC_FORMAT_INTERNAL_RGB_565)
725 {
726 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
727 }
728
729 /* Ensure that AFBC features are supported by producers/consumers. */
730 if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) &&
731 (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) == 0)
732 {
733 MALI_GRALLOC_LOGE("AFBC basic selected but not supported by producer/consumer. Disabling "
734 "MALI_GRALLOC_INTFMT_AFBC_BASIC");
735 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_BASIC;
736 }
737
738 if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPLITBLK) &&
739 (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK) == 0)
740 {
741 MALI_GRALLOC_LOGE("AFBC split-block selected but not supported by producer/consumer. Disabling "
742 "MALI_GRALLOC_INTFMT_AFBC_SPLITBLK");
743 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
744 }
745
746 if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_WIDEBLK) &&
747 (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK) == 0)
748 {
749 MALI_GRALLOC_LOGE("AFBC wide-block selected but not supported by producer/consumer. Disabling "
750 "MALI_GRALLOC_INTFMT_AFBC_WIDEBLK");
751 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_WIDEBLK;
752 }
753
754 if ((alloc_format & MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS) &&
755 (producer_active_caps & consumer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) == 0)
756 {
757 MALI_GRALLOC_LOGE("AFBC tiled-headers selected but not supported by producer/consumer. Disabling "
758 "MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS");
759 alloc_format &= ~MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
760 }
761
762 if (!((alloc_format & MALI_GRALLOC_INTFMT_AFBC_SPARSE) ||
763 (producer_active_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WRITE_NON_SPARSE)))
764 {
765 MALI_GRALLOC_LOGE("AFBC sparse not selected while producer cannot write non-sparse. Enabling "
766 "MALI_GRALLOC_INTFMT_AFBC_SPARSE");
767 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPARSE;
768 }
769
770 return alloc_format;
771 }
772
773
774 /*
775 * Derives a valid AFBC format (via modifiers) for all producers and consumers.
776 * Formats are validated after enabling the largest feature set supported (and
777 * desirable) for the IP usage. Some format modifier combinations are not
778 * compatible. See MALI_GRALLOC_INTFMT_* modifiers for more information.
779 *
780 * @param base_format [in] Base format (internal).
781 * @param usage [in] Buffer usage.
782 * @param producer [in] Buffer producers (write).
783 * @param consumer [in] Buffer consumers (read).
784 * @param producer_caps [in] Buffer producer capabilities (intersection).
785 * @param consumer_caps [in] Buffer consumer capabilities (intersection).
786 *
787 * @return valid AFBC format, where modifiers are enabled (supported/preferred);
788 * base format without modifers, otherwise
789 */
get_afbc_format(const uint32_t base_format,const uint64_t usage,const uint16_t producer,const uint16_t consumer,const uint64_t producer_caps,const uint64_t consumer_caps)790 static uint64_t get_afbc_format(const uint32_t base_format,
791 const uint64_t usage,
792 const uint16_t producer,
793 const uint16_t consumer,
794 const uint64_t producer_caps,
795 const uint64_t consumer_caps)
796 {
797 uint64_t alloc_format = base_format;
798
799 /*
800 * Determine AFBC modifiers where capabilities are defined for all producers
801 * and consumers. NOTE: AFBC is not supported for video transcode (VPU --> VPU).
802 */
803 if (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT &&
804 ((producer & GOOGLE_GRALLOC_PRODUCER_VPUS_MASK) == 0 || (consumer & GOOGLE_GRALLOC_CONSUMER_VPUS_MASK) == 0))
805 {
806 if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
807 consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
808 {
809 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
810
811 #if 0
812 const int format_idx = get_format_index(base_format);
813
814 /* TODO: AFBC YUV TRANSFORM corrupts screen when enabled. find out why */
815 if (format_idx != -1)
816 {
817 if (formats[format_idx].yuv_transform == true)
818 {
819 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM;
820 }
821 }
822 #endif
823
824 if (!(producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WRITE_NON_SPARSE))
825 {
826 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPARSE;
827 }
828
829 if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
830 consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
831 {
832 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
833
834 if (usage & MALI_GRALLOC_USAGE_FRONTBUFFER &&
835 producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_DOUBLE_BODY)
836 {
837 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY;
838 }
839 }
840
841 /*
842 * Specific producer/consumer combinations benefit from additional
843 * AFBC features (e.g. * --> GPU).
844 */
845 if (consumer & MALI_GRALLOC_CONSUMER_GPU)
846 {
847 if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK &&
848 consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
849 {
850 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
851 }
852
853 /*
854 * NOTE: assume that all AFBC layers are pre-rotated. 16x16 SB
855 * must be used with DPU consumer when rotation is required.
856 */
857 if (producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK &&
858 consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK)
859 {
860 alloc_format |= MALI_GRALLOC_INTFMT_AFBC_WIDEBLK;
861 }
862 }
863 }
864 }
865
866 alloc_format = validate_afbc_format(alloc_format, producer_caps, consumer_caps);
867
868 return alloc_format;
869 }
870
871 /*
872 * Obtains the 'active' capabilities (for producers/consumers) by applying
873 * additional constraints to the capabilities declared for each IP. Some rules
874 * are based on format, others specific to producer/consumer. This function must
875 * be careful not to make any assumptions about the base format properties since
876 * fallback might still occur. It is safe to use any properties which are common
877 * across all compatible formats as defined by is_format_compatible().
878 *
879 * @param format [in] Base format requested.
880 * @param producers [in] Producers (flags).
881 * @param consumers [in] Consumers (flags).
882 * @param producer_active_caps [out] Active producer capabilities (flags).
883 * @param consumer_active_caps [out] Active consumer capabilities (flags).
884 * @param buffer_size [in] Buffer resolution (w x h, in pixels).
885 *
886 * @return none.
887 */
get_active_caps(const format_info_t format,const uint16_t producers,const uint16_t consumers,uint64_t * const producer_active_caps,uint64_t * const consumer_active_caps,const int buffer_size)888 static void get_active_caps(const format_info_t format,
889 const uint16_t producers,
890 const uint16_t consumers,
891 uint64_t * const producer_active_caps,
892 uint64_t * const consumer_active_caps,
893 const int buffer_size)
894 {
895 const uint64_t producer_caps = (producer_active_caps) ? *producer_active_caps : 0;
896 const uint64_t consumer_caps = (consumer_active_caps) ? *consumer_active_caps : 0;
897 uint64_t producer_mask = ~0;
898 uint64_t consumer_mask = ~0;
899
900 if (format.is_yuv)
901 {
902 if ((producer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_WRITE) == 0)
903 {
904 producer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
905 }
906 else if (producers & MALI_GRALLOC_PRODUCER_GPU)
907 {
908 /* All GPUs that can write YUV AFBC can only do it in 16x16,
909 * optionally with tiled headers.
910 */
911 producer_mask &=
912 ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK |
913 MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
914 }
915
916 if ((consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_READ) == 0)
917 {
918 consumer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
919 }
920 }
921
922 // TODO: b/183385318 Prefer 16x16 AFBC over 32x8 for GPU --> GPU
923 if ((producers & MALI_GRALLOC_PRODUCER_GPU) &&
924 (consumers & MALI_GRALLOC_CONSUMER_GPU) &&
925 (producer_caps & consumer_caps & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC))
926 {
927 producer_mask &=
928 ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK |
929 MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
930
931 consumer_mask &=
932 ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK |
933 MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
934 }
935
936 if (consumers & MALI_GRALLOC_CONSUMER_DPU)
937 {
938 /* DPU does not support split-block other than RGB(A) 24/32-bit */
939 if (!format.is_rgb || format.bpp[0] < 24)
940 {
941 if (consumers & MALI_GRALLOC_CONSUMER_DPU)
942 {
943 consumer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
944 }
945 }
946 }
947
948 bool afbc_allowed = false;
949 afbc_allowed = buffer_size > (192 * 192);
950
951 if (consumers & MALI_GRALLOC_CONSUMER_DPU)
952 {
953 /* TODO: make this into an option in BoardConfig */
954 #if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0
955 #define GRALLOC_AFBC_MIN_SIZE 40
956 /* Disable AFBC based on buffer dimensions */
957 afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE;
958 #endif
959 }
960
961 if (!afbc_allowed)
962 {
963 consumer_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
964 }
965
966 if (producer_active_caps)
967 {
968 *producer_active_caps &= producer_mask;
969 }
970 if (consumer_active_caps)
971 {
972 *consumer_active_caps &= consumer_mask;
973 }
974 }
975
976
977 /*
978 * Obtains support flags and modifiers for base format.
979 *
980 * @param base_format [in] Base format for which to deduce support.
981 * @param usage [in] Buffer usage.
982 * @param producers [in] Producers (flags).
983 * @param consumers [in] Consumers (flags).
984 * @param producer_active_caps [in] Producer capabilities (flags).
985 * @param consumer_active_caps [in] Consumer capabilities (flags).
986 * @param fmt_supported [out] Format (base + modifiers) and support (flags).
987 *
988 * @return 1, base format supported
989 * 0, otherwise
990 */
get_supported_format(const uint32_t base_format,const uint64_t usage,const uint16_t producers,const uint16_t consumers,const uint64_t producer_active_caps,const uint64_t consumer_active_caps,fmt_props * const fmt_supported)991 bool get_supported_format(const uint32_t base_format,
992 const uint64_t usage,
993 const uint16_t producers,
994 const uint16_t consumers,
995 const uint64_t producer_active_caps,
996 const uint64_t consumer_active_caps,
997 fmt_props * const fmt_supported)
998 {
999 const int32_t fmt_idx = get_format_index(base_format);
1000 const int32_t ip_fmt_idx = get_ip_format_index(base_format);
1001 assert(fmt_idx >= 0);
1002 if (ip_fmt_idx == -1)
1003 {
1004 /* Return undefined base format. */
1005 MALI_GRALLOC_LOGE("Failed to find IP support info for format id: 0x%" PRIx32,
1006 base_format);
1007 return false;
1008 }
1009
1010 fmt_supported->f_flags = is_format_supported(fmt_idx,
1011 ip_fmt_idx,
1012 usage,
1013 producers,
1014 consumers,
1015 producer_active_caps,
1016 consumer_active_caps);
1017 MALI_GRALLOC_LOGV("IP support: 0x%" PRIx16, fmt_supported->f_flags);
1018 if (fmt_supported->f_flags == F_NONE &&
1019 consumers & MALI_GRALLOC_CONSUMER_GPU &&
1020 consumers & MALI_GRALLOC_CONSUMER_DPU)
1021 {
1022 /* Determine alternative caps for formats when GPU/DPU consumer.
1023 * Although we normally combine capabilities for multiple consumers with "AND",
1024 * in some situations (e.g. formats) we make best effort and say that fallback
1025 * to GPU is acceptable and perferred over rejecting allocation. GPU composition
1026 * must always be supported in case of fallback from DPU.
1027 */
1028 const uint16_t consumers_nodpu = consumers & ~MALI_GRALLOC_CONSUMER_DPU;
1029 uint64_t consumer_nodpu_caps = consumer_active_caps;
1030
1031 /* Set consumer caps to GPU-only (assume superset of DPU). */
1032 consumer_nodpu_caps = get_consumer_caps(consumers_nodpu);
1033 get_active_caps(formats[fmt_idx],
1034 producers, consumers_nodpu,
1035 NULL, &consumer_nodpu_caps,
1036 0 /* N/A without DPU consumer */);
1037
1038 fmt_supported->f_flags = is_format_supported(fmt_idx,
1039 ip_fmt_idx,
1040 usage,
1041 producers,
1042 consumers_nodpu,
1043 producer_active_caps,
1044 consumer_nodpu_caps);
1045 }
1046
1047 fmt_supported->base_format = base_format;
1048 if (fmt_supported->f_flags & F_AFBC)
1049 {
1050 const uint64_t afbc_format = get_afbc_format(base_format,
1051 usage,
1052 producers,
1053 consumers,
1054 producer_active_caps,
1055 consumer_active_caps);
1056
1057 MALI_GRALLOC_LOGV("AFBC format: (%s 0x%" PRIx64 ")",
1058 format_name(afbc_format), afbc_format);
1059
1060 /* Disable AFBC when forced by usage or no format modifiers selected. */
1061 if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC ||
1062 afbc_format == fmt_supported->base_format)
1063 {
1064 fmt_supported->f_flags &= ~F_AFBC;
1065 }
1066
1067 /* Check that AFBC features are correct for multiplane format. */
1068 alloc_type_t alloc_type{};
1069 get_alloc_type(afbc_format & MALI_GRALLOC_INTFMT_EXT_MASK,
1070 fmt_idx,
1071 usage,
1072 &alloc_type);
1073 if (formats[fmt_idx].npln > 1 && alloc_type.is_multi_plane == false)
1074 {
1075 fmt_supported->f_flags &= ~F_AFBC;
1076 }
1077
1078 /* Store any format modifiers */
1079 fmt_supported->format_ext = afbc_format & MALI_GRALLOC_INTFMT_EXT_MASK;
1080 }
1081 if ((fmt_supported->f_flags & F_AFBC) == 0)
1082 {
1083 fmt_supported->format_ext = 0;
1084 }
1085
1086 MALI_GRALLOC_LOGV("Ext format: (%s 0x%" PRIx64 ")", format_name(fmt_supported->format_ext),
1087 fmt_supported->format_ext);
1088
1089 return (fmt_supported->f_flags == F_NONE) ? false : true;
1090 }
1091
1092
1093 /*
1094 * Determines whether two base formats have comparable 'color' components. Alpha
1095 * is considered unimportant for YUV formats.
1096 *
1097 * @param f_old [in] Format properties (old format).
1098 * @param f_new [in] Format properties (new format).
1099 *
1100 * @return 1, format components are equivalent
1101 * 0, otherwise
1102 */
comparable_components(const format_info_t * const f_old,const format_info_t * const f_new)1103 static bool comparable_components(const format_info_t * const f_old,
1104 const format_info_t * const f_new)
1105 {
1106 if (f_old->is_yuv && f_new->bps == f_old->bps)
1107 {
1108 /* Formats have the same number of components. */
1109 if (f_new->total_components() == f_old->total_components())
1110 {
1111 return true;
1112 }
1113
1114 /* Alpha component can be dropped for yuv formats.
1115 * This assumption is required for mapping Y0L2 to
1116 * single plane 10-bit YUV420 AFBC.
1117 */
1118 if (f_old->has_alpha)
1119 {
1120 if (f_new->total_components() == 3 &&
1121 f_new->is_yuv &&
1122 !f_new->has_alpha)
1123 {
1124 return true;
1125 }
1126 }
1127 }
1128 else if (f_old->is_rgb)
1129 {
1130 if (f_new->total_components() == f_old->total_components())
1131 {
1132 if (f_new->bpp[0] == f_old->bpp[0] && f_new->bps == f_old->bps)
1133 {
1134 return true;
1135 }
1136 }
1137 }
1138 else
1139 {
1140 if (f_new->id == f_old->id)
1141 {
1142 return true;
1143 }
1144 }
1145
1146 return false;
1147 }
1148
1149
1150 /*
1151 * Determines whether two base formats are compatible such that data from one
1152 * format could be accurately represented/interpreted in the other format.
1153 *
1154 * @param f_old [in] Format properties (old format).
1155 * @param f_new [in] Format properties (new format).
1156 *
1157 * @return 1, formats are equivalent
1158 * 0, otherwise
1159 */
is_format_compatible(const format_info_t * const f_old,const format_info_t * const f_new)1160 static bool is_format_compatible(const format_info_t * const f_old,
1161 const format_info_t * const f_new)
1162 {
1163 if (f_new->hsub == f_old->hsub &&
1164 f_new->vsub == f_old->vsub &&
1165 f_new->is_rgb == f_old->is_rgb &&
1166 f_new->is_yuv == f_old->is_yuv &&
1167 comparable_components(f_old, f_new))
1168 {
1169 return true;
1170 }
1171 else
1172 {
1173 return false;
1174 }
1175 }
1176
1177 /**
1178 * Provide a grade for the compatible format with respect to the requested format. Used to find the best compatible
1179 * format.
1180 *
1181 * @param fmt[in] Compatible format properties.
1182 * @param req_format Requested base format.
1183 *
1184 * @return The grade of the compatible format. Higher is better. Returns 0 if format extensions are incompatible with
1185 * requested format.
1186 */
grade_format(const fmt_props & fmt,uint32_t req_format)1187 uint64_t grade_format(const fmt_props &fmt, uint32_t req_format)
1188 {
1189 uint64_t grade = 1;
1190
1191 GRALLOC_UNUSED(req_format);
1192
1193 static const struct {
1194 uint64_t fmt_ext;
1195 uint64_t value;
1196 } fmt_ext_values[] {
1197 { MALI_GRALLOC_INTFMT_AFBC_BASIC, 1 },
1198 { MALI_GRALLOC_INTFMT_AFBC_SPLITBLK, 1 },
1199 { MALI_GRALLOC_INTFMT_AFBC_WIDEBLK, 1 },
1200 { MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS, 1 },
1201 { MALI_GRALLOC_INTFMT_AFBC_EXTRAWIDEBLK, 1 },
1202 { MALI_GRALLOC_INTFMT_AFBC_DOUBLE_BODY, 1 },
1203 { MALI_GRALLOC_INTFMT_AFBC_BCH, 1 },
1204 { MALI_GRALLOC_INTFMT_AFBC_YUV_TRANSFORM, 1 },
1205 { MALI_GRALLOC_INTFMT_AFBC_SPARSE, 1 },
1206 };
1207 for (auto& ext : fmt_ext_values)
1208 {
1209 if (fmt.format_ext & ext.fmt_ext)
1210 {
1211 grade += ext.value;
1212 }
1213 }
1214
1215 return grade;
1216 }
1217
1218 /*
1219 * Obtains the 'best' allocation format for requested format and usage:
1220 * 1. Find compatible base formats (based on format properties alone)
1221 * 2. Find base formats supported by producers/consumers
1222 * 3. Find best modifiers from supported base formats
1223 * 4. Select allocation format from "best" base format with "best" modifiers
1224 *
1225 * NOTE: Base format re-mapping should not take place when CPU usage is
1226 * requested.
1227 *
1228 * @param req_base_format [in] Base format requested by client.
1229 * @param usage [in] Buffer usage.
1230 * @param producers [in] Producers (flags).
1231 * @param consumers [in] Consumers (flags).
1232 * @param producer_active_caps [in] Producer capabilities (flags).
1233 * @param consumer_active_caps [in] Consumer capabilities (flags).
1234 *
1235 * @return alloc_format, supported for usage;
1236 * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, otherwise
1237 */
get_best_format(const uint32_t req_base_format,const uint64_t usage,const uint16_t producers,const uint16_t consumers,const uint64_t producer_active_caps,const uint64_t consumer_active_caps)1238 static uint64_t get_best_format(const uint32_t req_base_format,
1239 const uint64_t usage,
1240 const uint16_t producers,
1241 const uint16_t consumers,
1242 const uint64_t producer_active_caps,
1243 const uint64_t consumer_active_caps)
1244 {
1245 uint64_t alloc_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED;
1246
1247 assert(req_base_format != MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED);
1248 const int32_t req_fmt_idx = get_format_index(req_base_format);
1249 MALI_GRALLOC_LOGV("req_base_format: (%s 0x%" PRIx32 ")",
1250 format_name(req_base_format), req_base_format);
1251 MALI_GRALLOC_LOGV("req_fmt_idx: %d", req_fmt_idx);
1252 assert(req_fmt_idx >= 0);
1253
1254 /* 1. Find compatible base formats. */
1255 std::vector<fmt_props> f_compat;
1256 for (uint16_t i = 0; i < num_formats; i++)
1257 {
1258 if (is_format_compatible(&formats[req_fmt_idx], &formats[i]))
1259 {
1260 fmt_props fmt = {0, 0, 0};
1261 fmt.base_format = formats[i].id;
1262 MALI_GRALLOC_LOGV("Compatible: Base-format: (%s 0x%" PRIx32 ")",
1263 format_name(fmt.base_format), fmt.base_format);
1264 f_compat.push_back(fmt);
1265 }
1266 }
1267 assert(f_compat.size() > 0);
1268
1269 /* 2. Find base formats supported by IP and among them, find the highest
1270 * number of modifier enabled format and check if requested format is present
1271 */
1272
1273 int32_t num_supported_formats = 0;
1274 uint64_t req_format_grade = 0;
1275 uint64_t best_fmt_grade = 0;
1276 uint64_t first_of_best_formats = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED;
1277 uint64_t req_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED;
1278
1279 for (uint16_t i = 0; i < f_compat.size(); i++)
1280 {
1281 MALI_GRALLOC_LOGV("Compatible: Base-format: 0x%" PRIx32, f_compat[i].base_format);
1282 fmt_props fmt = {0, 0, 0};
1283 bool supported = get_supported_format(f_compat[i].base_format,
1284 usage,
1285 producers,
1286 consumers,
1287 producer_active_caps,
1288 consumer_active_caps,
1289 &fmt);
1290 if (supported)
1291 {
1292 const uint64_t sup_fmt_grade = grade_format(fmt, req_base_format);
1293 if (sup_fmt_grade)
1294 {
1295 num_supported_formats++;
1296 MALI_GRALLOC_LOGV("Supported: Base-format: (%s 0x%" PRIx32 "), Modifiers: 0x%" PRIx64 ", Flags: 0x%" PRIx16,
1297 format_name(fmt.base_format), fmt.base_format, fmt.format_ext, fmt.f_flags);
1298
1299 /* 3. Find best modifiers from supported base formats */
1300 if (sup_fmt_grade > best_fmt_grade)
1301 {
1302 best_fmt_grade = sup_fmt_grade;
1303 first_of_best_formats = fmt.base_format | fmt.format_ext;
1304 }
1305
1306 /* Check if current supported format is same as requested format */
1307 if (fmt.base_format == req_base_format)
1308 {
1309 req_format_grade = sup_fmt_grade;
1310 req_format = fmt.base_format | fmt.format_ext;
1311 }
1312 }
1313 }
1314 }
1315
1316 /* 4. Select allocation format from "best" base format with "best" modifiers */
1317 if (num_supported_formats > 0)
1318 {
1319 /* Select first/one of best format when requested format is either not
1320 * supported or requested format is not the best format.
1321 */
1322 if ((req_format_grade != best_fmt_grade) &&
1323 (((producers & MALI_GRALLOC_PRODUCER_CPU) == 0) &&
1324 ((consumers & MALI_GRALLOC_CONSUMER_CPU) == 0)))
1325 {
1326 alloc_format = first_of_best_formats;
1327 }
1328 else if (req_format_grade != 0)
1329 {
1330 alloc_format = req_format;
1331 }
1332 }
1333
1334 MALI_GRALLOC_LOGV("Selected format: (%s 0x%" PRIx64 ")",
1335 format_name(alloc_format), alloc_format);
1336 return alloc_format;
1337 }
1338
1339
1340 /*
1341 * Obtain format modifiers from requested format.
1342 *
1343 * @param req_format [in] Requested format (base + optional modifiers).
1344 * @param usage [in] Buffer usage.
1345 *
1346 * @return format modifiers, where extracted from requested format;
1347 * 0, otherwise
1348 */
get_format_ext(const uint64_t req_format,const uint64_t usage)1349 uint64_t get_format_ext(const uint64_t req_format, const uint64_t usage)
1350 {
1351 /* TODO: clean up this function. Or remove it */
1352 GRALLOC_UNUSED(usage);
1353 return req_format & MALI_GRALLOC_INTFMT_EXT_MASK;
1354 }
1355
1356
1357 /*
1358 * Obtain base format from requested format. There are two primary ways in which
1359 * the client can specify requested format:
1360 * - Public API:
1361 * - Normal usage, with HAL_PIXEL_FORMAT_* / MALI_GRALLOC_FORMAT_INTERNAL_*
1362 * - Private usage, (as normal usage) with additional format modifiers (MALI_GRALLOC_INTFMT_*)
1363 * - Private API: allows private usage to be provided explicitly
1364 * (type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
1365 *
1366 * @param req_format [in] Requested format (base + optional modifiers).
1367 * @param usage [in] Buffer usage.
1368 * @param type [in] Format type (public usage or internal).
1369 * @param map_to_internal [in] Base format (if public HAL_PIXEL_FORMAT_*)
1370 * should be mapped to internal representation.
1371 *
1372 * @return base format, where identified/translated from requested format;
1373 * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, otherwise
1374 */
get_base_format(const uint64_t req_format,const uint64_t usage,const mali_gralloc_format_type type,const bool map_to_internal)1375 uint32_t get_base_format(const uint64_t req_format,
1376 const uint64_t usage,
1377 const mali_gralloc_format_type type,
1378 const bool map_to_internal)
1379 {
1380 GRALLOC_UNUSED(type);
1381
1382 uint32_t base_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED;
1383
1384 /* Mask out extension bits which could be present with type 'internal'. */
1385 base_format = req_format & MALI_GRALLOC_INTFMT_FMT_MASK;
1386
1387 /* Map Android flexible formats to internal base formats */
1388 if (req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
1389 {
1390 auto consumers = get_consumers(usage);
1391 auto producers = get_producers(usage);
1392
1393 if ((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_COMPOSER))
1394 {
1395 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
1396 }
1397 else if ((producers & MALI_GRALLOC_PRODUCER_CAM) &&
1398 !(producers & MALI_GRALLOC_PRODUCER_GPU) &&
1399 (consumers == GOOGLE_GRALLOC_CONSUMER_MFC))
1400 {
1401 // Allocated camera buffer is SBWC compressed when
1402 // 1. Camera is one of the producers
1403 // 2. GPU is not one of the producers
1404 // 3. MFC is the sole consumer
1405 if (property_get_bool("debug.vendor.gpu.record_sbwc", true)) {
1406 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC;
1407 } else {
1408 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
1409 }
1410 }
1411 else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
1412 {
1413 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
1414 }
1415 else if (usage & GRALLOC_USAGE_VIDEO_PRIVATE_DATA)
1416 {
1417 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
1418 }
1419 else if ((usage & GRALLOC_USAGE_HW_CAMERA_READ) && (usage & GRALLOC_USAGE_HW_CAMERA_WRITE))
1420 {
1421 // Camera IMPLEMENTATION_DEFINED format output maps to NV21M.
1422 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
1423 }
1424 else
1425 {
1426 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
1427 }
1428 }
1429 else if (req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
1430 {
1431 if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_HW_VIDEO_DECODER))
1432 {
1433 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
1434 }
1435 else if ((usage & GRALLOC_USAGE_HW_TEXTURE) && (usage & GRALLOC_USAGE_HW_CAMERA_WRITE))
1436 {
1437 // Camera flexible YUV format output maps to NV21M.
1438 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;
1439 }
1440 else if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
1441 {
1442 base_format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
1443 }
1444 else
1445 {
1446 // Flexible framework-accessible YUV format; map to NV21 for now
1447 base_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1448 }
1449 }
1450
1451 /* Obtain a valid base format, optionally mapped to internal. Flex formats
1452 * are always mapped to internal base format.
1453 * NOTE: Overlap between HAL_PIXEL_FORMAT_* and MALI_GRALLOC_FORMAT_INTERNAL_*
1454 * is intentional. See enumerations for more information.
1455 */
1456 return get_internal_format(base_format, map_to_internal);
1457 }
1458
1459
1460 /*
1461 * Select pixel format (base + modifier) for allocation.
1462 *
1463 * @param req_format [in] Format (base + optional modifiers) requested by client.
1464 * @param type [in] Format type (public usage or internal).
1465 * @param usage [in] Buffer usage.
1466 * @param buffer_size [in] Buffer resolution (w x h, in pixels).
1467 *
1468 * @return alloc_format, format to be used in allocation;
1469 * MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED, where no suitable
1470 * format could be found.
1471 */
mali_gralloc_select_format(const uint64_t req_format,const mali_gralloc_format_type type,const uint64_t usage,const int buffer_size)1472 uint64_t mali_gralloc_select_format(const uint64_t req_format,
1473 const mali_gralloc_format_type type,
1474 const uint64_t usage,
1475 const int buffer_size)
1476 {
1477 uint64_t alloc_format = MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED;
1478
1479 /*
1480 * Obtain base_format (no extension bits) and indexes into format tables.
1481 */
1482 const uint32_t req_base_format = get_base_format(req_format, usage, type, true);
1483 const int32_t req_fmt_idx = get_format_index(req_base_format);
1484 if (req_base_format == MALI_GRALLOC_FORMAT_INTERNAL_UNDEFINED ||
1485 req_fmt_idx == -1)
1486 {
1487 MALI_GRALLOC_LOGE("Invalid base format! req_base_format = (%s 0x%" PRIx32
1488 "), req_format = (%s 0x%" PRIx64 "), type = 0x%" PRIx32,
1489 format_name(req_base_format), req_base_format, format_name(req_format), req_format, type);
1490 goto out;
1491 }
1492
1493 /* Reject if usage specified is outside white list of valid usages. */
1494 if (type != MALI_GRALLOC_FORMAT_TYPE_INTERNAL && (usage & (~VALID_USAGE)) != 0)
1495 {
1496 MALI_GRALLOC_LOGE("Invalid usage specified: %s 0x%" PRIx64, describe_usage(usage).c_str(), usage);
1497 }
1498
1499 /* TODO: Make a function for finding formats that should be allocated as the request format */
1500 if (is_exynos_format(req_base_format) || req_base_format == HAL_PIXEL_FORMAT_BLOB)
1501 {
1502 alloc_format = req_base_format;
1503 }
1504 else if (usage == 0)
1505 {
1506 /* Allocate format as-is when no usage is specified */
1507 alloc_format = req_base_format;
1508 }
1509 else
1510 {
1511 /* Determine producers and consumers. */
1512 const uint16_t producers = get_producers(usage);
1513 const uint16_t consumers = get_consumers(usage);
1514
1515 MALI_GRALLOC_LOGV("Producers: 0x%" PRIx16 ", Consumers: 0x%" PRIx16,
1516 producers, consumers);
1517
1518 /* Obtain producer and consumer capabilities. */
1519 const uint64_t producer_caps = get_producer_caps(producers);
1520
1521 uint64_t consumer_caps = 0;
1522 #ifdef GRALLOC_HWC_FB_DISABLE_AFBC
1523 if (GRALLOC_HWC_FB_DISABLE_AFBC && DISABLE_FRAMEBUFFER_HAL && (usage & GRALLOC_USAGE_HW_FB))
1524 {
1525 /* Override capabilities to disable AFBC for DRM HWC framebuffer surfaces. */
1526 consumer_caps = MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
1527 }
1528 else
1529 #endif
1530 {
1531 consumer_caps = get_consumer_caps(consumers);
1532 }
1533
1534 MALI_GRALLOC_LOGV("Producer caps: 0x%" PRIx64 ", Consumer caps: 0x%" PRIx64,
1535 producer_caps, consumer_caps);
1536
1537 if (producers == 0 && consumers == 0)
1538 {
1539 MALI_GRALLOC_LOGE("Producer and consumer not identified.");
1540 goto out;
1541 }
1542 else if (producers == 0 || consumers == 0)
1543 {
1544 MALI_GRALLOC_LOGV("Producer or consumer not identified.");
1545 }
1546
1547 if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC &&
1548 formats[req_fmt_idx].is_yuv)
1549 {
1550 MALI_GRALLOC_LOGE("ERROR: Invalid usage 'MALI_GRALLOC_USAGE_NO_AFBC' when allocating YUV formats");
1551 goto out;
1552 }
1553
1554 uint64_t producer_active_caps = producer_caps;
1555 uint64_t consumer_active_caps = consumer_caps;
1556
1557 get_active_caps(formats[req_fmt_idx],
1558 producers, consumers,
1559 &producer_active_caps, &consumer_active_caps,
1560 buffer_size);
1561
1562 MALI_GRALLOC_LOGV("Producer caps (active): 0x%" PRIx64 ", Consumer caps (active): 0x%" PRIx64,
1563 producer_active_caps, consumer_active_caps);
1564
1565 /* TODO: reimplment get_best_format */
1566 alloc_format = get_best_format(formats[req_fmt_idx].id,
1567 usage,
1568 producers,
1569 consumers,
1570 producer_active_caps,
1571 consumer_active_caps);
1572 }
1573
1574 out:
1575 MALI_GRALLOC_LOGV("%s: req_format=(%s 0x%08" PRIx64 "), usage=(%s 0x%" PRIx64
1576 "), req_base_format=(%s 0x%" PRIx32 "), alloc_format=(%s, 0x%" PRIx64 ")", __func__,
1577 format_name(req_format), req_format, describe_usage(usage).c_str(), usage,
1578 format_name(req_base_format), req_base_format, format_name(alloc_format), alloc_format);
1579
1580 return alloc_format;
1581 }
1582
is_exynos_format(uint32_t base_format)1583 bool is_exynos_format(uint32_t base_format)
1584 {
1585 switch (base_format)
1586 {
1587 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1588 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
1589 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
1590 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
1591 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
1592 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
1593 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
1594 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
1595 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
1596 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
1597 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
1598 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
1599 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
1600 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
1601 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
1602 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
1603 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
1604 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
1605 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
1606 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
1607 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
1608 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
1609 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
1610 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
1611 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
1612 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
1613 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
1614 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
1615 return true;
1616 }
1617
1618 return false;
1619 }
1620
1621