1 /*
2  * Copyright (C) 2016-2017 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 
24 #if GRALLOC_USE_GRALLOC1_API == 1
25 #include <hardware/gralloc1.h>
26 #else
27 #include <hardware/gralloc.h>
28 #endif
29 
30 #include "mali_gralloc_module.h"
31 #include "gralloc_priv.h"
32 
33 static mali_gralloc_format_caps dpu_runtime_caps;
34 static mali_gralloc_format_caps vpu_runtime_caps;
35 static mali_gralloc_format_caps gpu_runtime_caps;
36 static mali_gralloc_format_caps cam_runtime_caps;
37 static pthread_mutex_t caps_init_mutex = PTHREAD_MUTEX_INITIALIZER;
38 static bool runtime_caps_read = false;
39 
40 #define MALI_GRALLOC_GPU_LIB_NAME "libGLES_mali.so"
41 #if defined(__LP64__)
42 #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib64/egl/"
43 #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib64/egl/"
44 #else
45 #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib/egl/"
46 #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib/egl/"
47 #endif
48 
49 #define GRALLOC_AFBC_MIN_SIZE 75
50 
get_block_capabilities(bool hal_module,const char * name,mali_gralloc_format_caps * block_caps)51 static bool get_block_capabilities(bool hal_module, const char *name, mali_gralloc_format_caps *block_caps)
52 {
53 	void *dso_handle = NULL;
54 	bool rval = false;
55 
56 	/* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers
57 	 * to determine hw format capabilities.
58 	 */
59 	if (!hal_module)
60 	{
61 		dso_handle = dlopen(name, RTLD_LAZY);
62 	}
63 	else
64 	{
65 		/* libhardware does some heuristics to find hal modules
66 		 * and then stores the dso handle internally. Use this.
67 		 */
68 		const struct hw_module_t *module = { NULL };
69 
70 		if (hw_get_module(name, &module) >= 0)
71 		{
72 			dso_handle = module->dso;
73 		}
74 	}
75 
76 	if (dso_handle)
77 	{
78 		void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR);
79 
80 		if (sym)
81 		{
82 			memcpy((void *)block_caps, sym, sizeof(mali_gralloc_format_caps));
83 			rval = true;
84 		}
85 
86 		if (!hal_module)
87 		{
88 			dlclose(dso_handle);
89 		}
90 	}
91 
92 	return rval;
93 }
94 
map_flex_formats(uint64_t req_format)95 static int map_flex_formats(uint64_t req_format)
96 {
97     /* Map Android flexible formats to internal base formats */
98     if(req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
99        req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
100     {
101         req_format = MALI_GRALLOC_FORMAT_INTERNAL_NV12;
102 
103     }
104     return req_format;
105 }
106 
is_afbc_supported(int req_format_mapped)107 static bool is_afbc_supported(int req_format_mapped)
108 {
109 	bool rval = true;
110 
111 	/* These base formats we currently don't support with compression */
112 	switch (req_format_mapped)
113 	{
114 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
115 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
116 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
117 	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
118 	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
119 	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
120 	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
121 	case HAL_PIXEL_FORMAT_YCbCr_422_I:
122 		rval = false;
123 		break;
124 	}
125 
126 	return rval;
127 }
128 
is_android_yuv_format(int req_format)129 static bool is_android_yuv_format(int req_format)
130 {
131 	bool rval = false;
132 
133 	switch (req_format)
134 	{
135 	case HAL_PIXEL_FORMAT_YV12:
136 	case HAL_PIXEL_FORMAT_Y8:
137 	case HAL_PIXEL_FORMAT_Y16:
138 	case HAL_PIXEL_FORMAT_YCbCr_420_888:
139 	case HAL_PIXEL_FORMAT_YCbCr_422_888:
140 	case HAL_PIXEL_FORMAT_YCbCr_444_888:
141 	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
142 	case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
143 		rval = true;
144 		break;
145 	}
146 
147 	return rval;
148 }
149 
is_afbc_allowed(int buffer_size)150 static bool is_afbc_allowed(int buffer_size)
151 {
152 	bool afbc_allowed = false;
153 
154 	(void)buffer_size;
155 
156 #if MALI_DISPLAY_VERSION == 550 || MALI_DISPLAY_VERSION == 650
157 #if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0
158 	afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE;
159 
160 #else
161 	/* If display size is not valid then always allow AFBC */
162 	afbc_allowed = true;
163 
164 #endif
165 #else
166 	/* For cetus, always allow AFBC */
167 	afbc_allowed = true;
168 #endif
169 	return afbc_allowed;
170 }
171 
is_afbc_format(uint64_t internal_format)172 static bool is_afbc_format(uint64_t internal_format)
173 {
174 	return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0;
175 }
176 
determine_best_format(int req_format,mali_gralloc_producer_type producer,mali_gralloc_consumer_type consumer,uint64_t producer_runtime_mask,uint64_t consumer_runtime_mask)177 static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer,
178                                       mali_gralloc_consumer_type consumer, uint64_t producer_runtime_mask,
179                                       uint64_t consumer_runtime_mask)
180 {
181 	/* Default is to return the requested format */
182 	uint64_t internal_format = req_format;
183 	uint64_t dpu_mask = dpu_runtime_caps.caps_mask;
184 	uint64_t gpu_mask = gpu_runtime_caps.caps_mask;
185 	uint64_t vpu_mask = vpu_runtime_caps.caps_mask;
186 	uint64_t cam_mask = cam_runtime_caps.caps_mask;
187 
188 	if (producer == MALI_GRALLOC_PRODUCER_GPU &&
189 	    gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
190 	{
191 		gpu_mask &= producer_runtime_mask;
192 
193 		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
194 		{
195 			gpu_mask &= consumer_runtime_mask;
196 			dpu_mask &= consumer_runtime_mask;
197 
198 			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK &&
199 			    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
200 			{
201 				internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
202 			}
203 			else if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
204 			         dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
205 			{
206 				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
207 
208 				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
209 				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
210 				{
211 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
212 				}
213 			}
214 		}
215 		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
216 		{
217 			gpu_mask &= consumer_runtime_mask;
218 
219 			/* When GPU acts as both producer and consumer it prefers 16x16 superblocks */
220 			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
221 			{
222 				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
223 			}
224 
225 			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
226 			{
227 				internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
228 			}
229 		}
230 		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
231 		{
232 			vpu_mask &= consumer_runtime_mask;
233 
234 			if (internal_format == HAL_PIXEL_FORMAT_YV12 || internal_format == MALI_GRALLOC_FORMAT_INTERNAL_NV12)
235 			{
236 				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
237 				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
238 				{
239 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
240 				}
241 
242 				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
243 				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
244 				{
245 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
246 				}
247 			}
248 		}
249 	}
250 	else if (producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER &&
251 	         vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
252 	{
253 		vpu_mask &= producer_runtime_mask;
254 
255 		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
256 		{
257 			gpu_mask &= consumer_runtime_mask;
258 			dpu_mask &= consumer_runtime_mask;
259 
260 			if (internal_format == HAL_PIXEL_FORMAT_YV12)
261 			{
262 				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
263 				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
264 				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
265 				{
266 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
267 				}
268 
269 				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
270 				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
271 				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
272 				{
273 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
274 				}
275 			}
276 		}
277 		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
278 		{
279 			gpu_mask &= consumer_runtime_mask;
280 
281 			if (internal_format == HAL_PIXEL_FORMAT_YV12)
282 			{
283 				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
284 				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
285 				{
286 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
287 				}
288 
289 				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
290 				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
291 				{
292 					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
293 				}
294 			}
295 		}
296 		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
297 		{
298 			/* Fall-through. To be decided.*/
299 		}
300 	}
301 	else if (producer == MALI_GRALLOC_PRODUCER_CAMERA &&
302 	         cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
303 	{
304 		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
305 		{
306 			/* Fall-through. To be decided.*/
307 		}
308 		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
309 		{
310 			/* Fall-through. To be decided.*/
311 		}
312 		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
313 		{
314 			/* Fall-through. To be decided.*/
315 		}
316 	}
317 
318 	return internal_format;
319 }
320 
decode_internal_format(uint64_t req_format,mali_gralloc_format_type type)321 static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_type type)
322 {
323 	uint64_t internal_format, me_mask, base_format, mapped_base_format;
324 
325 	if (type == MALI_GRALLOC_FORMAT_TYPE_USAGE)
326 	{
327 		internal_format = GRALLOC_PRIVATE_FORMAT_UNWRAP((int)req_format);
328 	}
329 	else if (type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
330 	{
331 		internal_format = req_format;
332 	}
333 	else
334 	{
335 		internal_format = 0;
336 		goto out;
337 	}
338 
339 	me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK;
340 
341 	if (me_mask > 0 && ((me_mask - 1) & me_mask) != 0)
342 	{
343 		ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format);
344 		internal_format = 0;
345 		goto out;
346 	}
347 
348 	base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
349 
350 	/* Even though private format allocations are intended to be for specific
351 	 * formats, certain test cases uses the flexible formats that needs to be mapped
352 	 * to internal ones.
353 	 */
354 	mapped_base_format = map_flex_formats((uint32_t)base_format);
355 
356 	/* Validate the internal base format passed in */
357 	switch (mapped_base_format)
358 	{
359 	case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
360 	case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
361 	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
362 	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
363 	case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
364 	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
365 	case MALI_GRALLOC_FORMAT_INTERNAL_Y8:
366 	case MALI_GRALLOC_FORMAT_INTERNAL_Y16:
367 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
368 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
369 	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
370 	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
371 	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
372 	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
373 	case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
374 	case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
375 	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
376 	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
377 	case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
378 	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
379 		if (mapped_base_format != base_format)
380 		{
381 			internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format;
382 		}
383 
384 		break;
385 
386 	default:
387 		ALOGE("Internal base format requested is unrecognized: %" PRIx64, internal_format);
388 		internal_format = 0;
389 		break;
390 	}
391 
392 out:
393 	return internal_format;
394 }
395 
determine_producer(mali_gralloc_producer_type * producer,uint64_t * producer_runtime_mask,int req_format,int usage)396 static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format,
397                                int usage)
398 {
399 	bool rval = true;
400 
401 	/* Default to GPU */
402 	*producer = MALI_GRALLOC_PRODUCER_GPU;
403 
404 	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
405 	{
406 		rval = false;
407 	}
408 	else if (usage & GRALLOC_USAGE_HW_RENDER)
409 	{
410 		if (is_android_yuv_format(req_format))
411 		{
412 			if (gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE)
413 			{
414 				*producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
415 			}
416 			else
417 			{
418 				/* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */
419 				*producer_runtime_mask &=
420 				    ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
421 			}
422 		}
423 
424 		*producer = MALI_GRALLOC_PRODUCER_GPU;
425 	}
426 	else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK)
427 	{
428 		*producer = MALI_GRALLOC_PRODUCER_CAMERA;
429 	}
430 	/* HW_TEXTURE+HW_COMPOSER+EXTERNAL_DISP is a definition set by
431 	 * stagefright for "video decoder". We check for it here.
432 	 */
433 	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) ==
434 	         (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP))
435 	{
436 		*producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER;
437 	}
438 
439 	return rval;
440 }
441 
determine_consumer(mali_gralloc_consumer_type * consumer,uint64_t * consumer_runtime_mask,int req_format,int usage)442 static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format,
443                                int usage)
444 {
445 	bool rval = true;
446 
447 	/* Default to GPU */
448 	*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
449 
450 	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
451 	{
452 		rval = false;
453 	}
454 	/* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB,
455 	 * we pick DPU even if there are no runtime capabilities present.
456 	 */
457 	else if (usage & GRALLOC_USAGE_HW_FB)
458 	{
459 		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
460 	}
461 	else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
462 	{
463 		if (is_android_yuv_format(req_format))
464 		{
465 			if (vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD)
466 				*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
467 		}
468 		else
469 		{
470 			*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
471 		}
472 		*consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER;
473 	}
474 	/* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it
475 	 * to determine consumer. When a buffer is targeted for either we reject the DPU when it lacks
476 	 * runtime capabilities, in favor of the more capable GPU.
477 	 */
478 	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) ==
479 	             (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER) &&
480 	         dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
481 	{
482 		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
483 	}
484 	else if (usage & GRALLOC_USAGE_HW_TEXTURE)
485 	{
486 		*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
487 	}
488 
489 	return rval;
490 }
491 
492 /*
493  * Here we determine format capabilities for the 4 IPs we support.
494  * For now these are controlled by build defines, but in the future
495  * they should be read out from each user-space driver.
496  */
determine_format_capabilities()497 static void determine_format_capabilities()
498 {
499 	/* Loading libraries can take some time and
500 	 * we may see many allocations at boot.
501 	 */
502 	pthread_mutex_lock(&caps_init_mutex);
503 
504 	if (runtime_caps_read)
505 	{
506 		goto already_init;
507 	}
508 
509 	memset((void *)&dpu_runtime_caps, 0, sizeof(dpu_runtime_caps));
510 	memset((void *)&vpu_runtime_caps, 0, sizeof(vpu_runtime_caps));
511 	memset((void *)&gpu_runtime_caps, 0, sizeof(gpu_runtime_caps));
512 	memset((void *)&cam_runtime_caps, 0, sizeof(cam_runtime_caps));
513 
514 	/* Determine DPU format capabilities */
515 	if (!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps))
516 	{
517 #if MALI_DISPLAY_VERSION >= 500
518 		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
519 		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
520 
521 #if MALI_DISPLAY_VERSION >= 550
522 		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
523 #endif
524 #endif
525 	}
526 
527 	/* Determine GPU format capabilities */
528 	if (access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
529 	{
530 		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
531 	}
532 	else if (access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
533 	{
534 		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
535 	}
536 
537 	if ((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0)
538 	{
539 		ALOGW("Failed to find GPU block configuration in %s. Using static build configuration.",
540 		      MALI_GRALLOC_GPU_LIB_NAME);
541 
542 #if MALI_GPU_SUPPORT_AFBC_BASIC == 1
543 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
544 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
545 
546 		/* Need to verify when to remove this */
547 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE;
548 
549 #if MALI_SUPPORT_AFBC_SPLITBLK == 1
550 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
551 #endif
552 
553 #if MALI_SUPPORT_AFBC_WIDEBLK == 1
554 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
555 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
556 #endif
557 
558 #if MALI_USE_YUV_AFBC_WIDEBLK != 1
559 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE;
560 #endif
561 
562 #if MALI_SUPPORT_AFBC_TILED_HEADERS == 1
563 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
564 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
565 		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
566 #endif
567 #endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */
568 	}
569 
570 /* Determine VPU format capabilities */
571 #if MALI_VIDEO_VERSION == 500 || MALI_VIDEO_VERSION == 550
572 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
573 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
574 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD;
575 #endif
576 
577 #if MALI_VIDEO_VERSION == 61
578 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
579 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
580 	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
581 #endif
582 
583 /* Build specific capability changes */
584 #if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1
585 	{
586 		dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
587 		gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
588 		vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
589 		cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
590 	}
591 #endif
592 
593 	runtime_caps_read = true;
594 
595 already_init:
596 	pthread_mutex_unlock(&caps_init_mutex);
597 
598 	ALOGV("GPU format capabilities 0x%" PRIx64, gpu_runtime_caps.caps_mask);
599 	ALOGV("DPU format capabilities 0x%" PRIx64, dpu_runtime_caps.caps_mask);
600 	ALOGV("VPU format capabilities 0x%" PRIx64, vpu_runtime_caps.caps_mask);
601 	ALOGV("CAM format capabilities 0x%" PRIx64, cam_runtime_caps.caps_mask);
602 }
603 
mali_gralloc_select_format(uint64_t req_format,mali_gralloc_format_type type,uint64_t usage,int buffer_size)604 uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage, int buffer_size)
605 {
606 	uint64_t internal_format = 0;
607 	mali_gralloc_consumer_type consumer;
608 	mali_gralloc_producer_type producer;
609 	uint64_t producer_runtime_mask = ~(0ULL);
610 	uint64_t consumer_runtime_mask = ~(0ULL);
611 	uint64_t req_format_mapped = 0;
612 
613 	if (!runtime_caps_read)
614 	{
615 		/*
616 		 * It is better to initialize these when needed because
617 		 * not all processes allocates memory.
618 		 */
619 		determine_format_capabilities();
620 	}
621 
622 	/* A unique usage specifies that an internal format is in req_format */
623 	if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT || type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
624 	{
625 		internal_format = decode_internal_format(req_format, type);
626 		goto out;
627 	}
628 
629 	/* Re-map special Android formats */
630 	req_format_mapped = map_flex_formats(req_format);
631 
632 	/* Determine producer/consumer */
633 	if (!determine_producer(&producer, &producer_runtime_mask, req_format, usage) ||
634 	    !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage))
635 	{
636 		/* Failing to determine producer/consumer usually means
637 		 * client has requested sw rendering.
638 		 */
639 		internal_format = req_format_mapped;
640 		goto out;
641 	}
642 
643 	/*
644 	 * Determine runtime capability limitations
645 	 */
646 
647 	/* Disable AFBC based on unique usage */
648 	if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC)
649 	{
650 		if (is_android_yuv_format(req_format_mapped))
651 		{
652 			ALOGE("It is invalid to specify NO_AFBC usage flags when allocating YUV formats.\
653                    Requested fmt: 0x%" PRIx64 " Re-Mapped fmt: 0x%" PRIx64,
654 			      req_format, req_format_mapped);
655 			internal_format = 0;
656 			goto out;
657 		}
658 
659 		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
660 	}
661 	/* Disable AFBC based on buffer dimensions */
662 	else if (!is_afbc_allowed(buffer_size))
663 	{
664 		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
665 	}
666 	else if (!is_afbc_supported(req_format_mapped))
667 	{
668 		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
669 	}
670 
671 	/* Automatically select format in case producer/consumer identified */
672 	internal_format =
673 	    determine_best_format(req_format_mapped, producer, consumer, producer_runtime_mask, consumer_runtime_mask);
674 
675 out:
676 	ALOGV("mali_gralloc_select_format: req_format=0x%08" PRIx64 " req_fmt_mapped=0x%" PRIx64
677 	      " internal_format=0x%" PRIx64 " usage=0x%" PRIx64,
678 	      req_format, req_format_mapped, internal_format, usage);
679 
680 	return internal_format;
681 }
682 
683 extern "C" {
mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps * gpu_caps)684 void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps)
685 {
686 	if (gpu_caps != NULL)
687 	{
688 		if (!runtime_caps_read)
689 		{
690 			determine_format_capabilities();
691 		}
692 
693 		memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(struct mali_gralloc_format_caps));
694 	}
695 }
696 }
697