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