xref: /aosp_15_r20/external/minigbm/cros_gralloc/cros_gralloc_helpers.cc (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker  * Copyright 2016 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker  * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker  */
6*d95af8dfSAndroid Build Coastguard Worker 
7*d95af8dfSAndroid Build Coastguard Worker #include "cros_gralloc_helpers.h"
8*d95af8dfSAndroid Build Coastguard Worker 
9*d95af8dfSAndroid Build Coastguard Worker #include <hardware/gralloc.h>
10*d95af8dfSAndroid Build Coastguard Worker #include <sync/sync.h>
11*d95af8dfSAndroid Build Coastguard Worker 
12*d95af8dfSAndroid Build Coastguard Worker /* Define to match AIDL BufferUsage::VIDEO_DECODER. */
13*d95af8dfSAndroid Build Coastguard Worker #define BUFFER_USAGE_VIDEO_DECODER (1 << 22)
14*d95af8dfSAndroid Build Coastguard Worker 
15*d95af8dfSAndroid Build Coastguard Worker /* Define to match AIDL BufferUsage::SENSOR_DIRECT_DATA. */
16*d95af8dfSAndroid Build Coastguard Worker #define BUFFER_USAGE_SENSOR_DIRECT_DATA (1 << 23)
17*d95af8dfSAndroid Build Coastguard Worker 
18*d95af8dfSAndroid Build Coastguard Worker /* Define to match AIDL BufferUsage::GPU_DATA_BUFFER. */
19*d95af8dfSAndroid Build Coastguard Worker #define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24)
20*d95af8dfSAndroid Build Coastguard Worker 
21*d95af8dfSAndroid Build Coastguard Worker /* Define to match AIDL PixelFormat::R_8. */
22*d95af8dfSAndroid Build Coastguard Worker #define HAL_PIXEL_FORMAT_R8 0x38
23*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_convert_format(int format)24*d95af8dfSAndroid Build Coastguard Worker uint32_t cros_gralloc_convert_format(int format)
25*d95af8dfSAndroid Build Coastguard Worker {
26*d95af8dfSAndroid Build Coastguard Worker 	/*
27*d95af8dfSAndroid Build Coastguard Worker 	 * Conversion from HAL to fourcc-based DRV formats based on
28*d95af8dfSAndroid Build Coastguard Worker 	 * platform_android.c in mesa.
29*d95af8dfSAndroid Build Coastguard Worker 	 */
30*d95af8dfSAndroid Build Coastguard Worker 
31*d95af8dfSAndroid Build Coastguard Worker 	switch (format) {
32*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGBA_8888:
33*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_ABGR8888;
34*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGBX_8888:
35*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_XBGR8888;
36*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGB_888:
37*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_BGR888;
38*d95af8dfSAndroid Build Coastguard Worker 	/*
39*d95af8dfSAndroid Build Coastguard Worker 	 * Confusingly, HAL_PIXEL_FORMAT_RGB_565 is defined as:
40*d95af8dfSAndroid Build Coastguard Worker 	 *
41*d95af8dfSAndroid Build Coastguard Worker 	 * "16-bit packed format that has 5-bit R, 6-bit G, and 5-bit B components, in that
42*d95af8dfSAndroid Build Coastguard Worker 	 *  order, from the  most-sigfinicant bits to the least-significant bits."
43*d95af8dfSAndroid Build Coastguard Worker 	 *
44*d95af8dfSAndroid Build Coastguard Worker 	 * so the order of the components is intentionally not flipped between the pixel
45*d95af8dfSAndroid Build Coastguard Worker 	 * format and the DRM format.
46*d95af8dfSAndroid Build Coastguard Worker 	 */
47*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGB_565:
48*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_RGB565;
49*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_BGRA_8888:
50*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_ARGB8888;
51*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RAW16:
52*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_R16;
53*d95af8dfSAndroid Build Coastguard Worker 	/*
54*d95af8dfSAndroid Build Coastguard Worker 	 * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers
55*d95af8dfSAndroid Build Coastguard Worker 	 * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width
56*d95af8dfSAndroid Build Coastguard Worker 	 * equal to their size in bytes.
57*d95af8dfSAndroid Build Coastguard Worker 	 */
58*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_BLOB:
59*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_R8:
60*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_R8;
61*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
62*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED;
63*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_YCbCr_420_888:
64*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_FLEX_YCbCr_420_888;
65*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_Y8:
66*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_R8;
67*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_Y16:
68*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_R16;
69*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_YV12:
70*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_YVU420_ANDROID;
71*d95af8dfSAndroid Build Coastguard Worker #if ANDROID_API_LEVEL >= 29
72*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGBA_FP16:
73*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_ABGR16161616F;
74*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_RGBA_1010102:
75*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_ABGR2101010;
76*d95af8dfSAndroid Build Coastguard Worker #endif
77*d95af8dfSAndroid Build Coastguard Worker #if ANDROID_API_LEVEL >= 30
78*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_YCBCR_P010:
79*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_P010;
80*d95af8dfSAndroid Build Coastguard Worker #endif
81*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_DEPTH_16:
82*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_DEPTH16;
83*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_DEPTH_24:
84*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_DEPTH24;
85*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
86*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_DEPTH24_STENCIL8;
87*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_DEPTH_32F:
88*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_DEPTH32;
89*d95af8dfSAndroid Build Coastguard Worker 	case HAL_PIXEL_FORMAT_DEPTH_32F_STENCIL_8:
90*d95af8dfSAndroid Build Coastguard Worker 		return DRM_FORMAT_DEPTH32_STENCIL8;
91*d95af8dfSAndroid Build Coastguard Worker 	}
92*d95af8dfSAndroid Build Coastguard Worker 
93*d95af8dfSAndroid Build Coastguard Worker 	return DRM_FORMAT_NONE;
94*d95af8dfSAndroid Build Coastguard Worker }
95*d95af8dfSAndroid Build Coastguard Worker 
handle_usage(uint64_t * gralloc_usage,uint64_t gralloc_mask,uint64_t * bo_use_flags,uint64_t bo_mask)96*d95af8dfSAndroid Build Coastguard Worker static inline void handle_usage(uint64_t *gralloc_usage, uint64_t gralloc_mask,
97*d95af8dfSAndroid Build Coastguard Worker 				uint64_t *bo_use_flags, uint64_t bo_mask)
98*d95af8dfSAndroid Build Coastguard Worker {
99*d95af8dfSAndroid Build Coastguard Worker 	if (((*gralloc_usage) & gralloc_mask) == gralloc_mask) {
100*d95af8dfSAndroid Build Coastguard Worker 		(*gralloc_usage) &= ~gralloc_mask;
101*d95af8dfSAndroid Build Coastguard Worker 		(*bo_use_flags) |= bo_mask;
102*d95af8dfSAndroid Build Coastguard Worker 	}
103*d95af8dfSAndroid Build Coastguard Worker }
104*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_convert_usage(uint64_t usage)105*d95af8dfSAndroid Build Coastguard Worker uint64_t cros_gralloc_convert_usage(uint64_t usage)
106*d95af8dfSAndroid Build Coastguard Worker {
107*d95af8dfSAndroid Build Coastguard Worker 	uint64_t use_flags = BO_USE_NONE;
108*d95af8dfSAndroid Build Coastguard Worker 
109*d95af8dfSAndroid Build Coastguard Worker 	/*
110*d95af8dfSAndroid Build Coastguard Worker 	 * GRALLOC_USAGE_SW_READ_OFTEN contains GRALLOC_USAGE_SW_READ_RARELY, thus OFTEN must be
111*d95af8dfSAndroid Build Coastguard Worker 	 * handled first. The same applies to GRALLOC_USAGE_SW_WRITE_OFTEN.
112*d95af8dfSAndroid Build Coastguard Worker 	 */
113*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_SW_READ_OFTEN, &use_flags, BO_USE_SW_READ_OFTEN);
114*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_SW_READ_RARELY, &use_flags, BO_USE_SW_READ_RARELY);
115*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_OFTEN, &use_flags, BO_USE_SW_WRITE_OFTEN);
116*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_RARELY, &use_flags, BO_USE_SW_WRITE_RARELY);
117*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_TEXTURE, &use_flags, BO_USE_TEXTURE);
118*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_RENDER, &use_flags, BO_USE_RENDERING);
119*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_2D, &use_flags, BO_USE_RENDERING);
120*d95af8dfSAndroid Build Coastguard Worker 	/* HWC wants to use display hardware, but can defer to OpenGL. */
121*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_COMPOSER, &use_flags,
122*d95af8dfSAndroid Build Coastguard Worker 		     BO_USE_SCANOUT | BO_USE_TEXTURE);
123*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_FB, &use_flags, BO_USE_NONE);
124*d95af8dfSAndroid Build Coastguard Worker 	/*
125*d95af8dfSAndroid Build Coastguard Worker 	 * This flag potentially covers external display for the normal drivers (i915/rockchip) and
126*d95af8dfSAndroid Build Coastguard Worker 	 * usb monitors (evdi/udl). It's complicated so ignore it.
127*d95af8dfSAndroid Build Coastguard Worker 	 */
128*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_EXTERNAL_DISP, &use_flags, BO_USE_NONE);
129*d95af8dfSAndroid Build Coastguard Worker 	/* Map PROTECTED to linear until real HW protection is available on Android. */
130*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_PROTECTED, &use_flags, BO_USE_LINEAR);
131*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_CURSOR, &use_flags, BO_USE_NONE);
132*d95af8dfSAndroid Build Coastguard Worker 	/* HACK: See b/30054495 for BO_USE_SW_READ_OFTEN. */
133*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_VIDEO_ENCODER, &use_flags,
134*d95af8dfSAndroid Build Coastguard Worker 		     BO_USE_HW_VIDEO_ENCODER | BO_USE_SW_READ_OFTEN);
135*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_WRITE, &use_flags, BO_USE_CAMERA_WRITE);
136*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_READ, &use_flags, BO_USE_CAMERA_READ);
137*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, GRALLOC_USAGE_RENDERSCRIPT, &use_flags, BO_USE_RENDERSCRIPT);
138*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, BUFFER_USAGE_VIDEO_DECODER, &use_flags, BO_USE_HW_VIDEO_DECODER);
139*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, BUFFER_USAGE_SENSOR_DIRECT_DATA, &use_flags,
140*d95af8dfSAndroid Build Coastguard Worker 		     BO_USE_SENSOR_DIRECT_DATA);
141*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, BUFFER_USAGE_GPU_DATA_BUFFER, &use_flags, BO_USE_GPU_DATA_BUFFER);
142*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING, &use_flags, BO_USE_FRONT_RENDERING);
143*d95af8dfSAndroid Build Coastguard Worker 	handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING_PRIVATE, &use_flags,
144*d95af8dfSAndroid Build Coastguard Worker 		     BO_USE_FRONT_RENDERING);
145*d95af8dfSAndroid Build Coastguard Worker 
146*d95af8dfSAndroid Build Coastguard Worker 	if (usage) {
147*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Unhandled gralloc usage: %llx", (unsigned long long)usage);
148*d95af8dfSAndroid Build Coastguard Worker 		return BO_USE_NONE;
149*d95af8dfSAndroid Build Coastguard Worker 	}
150*d95af8dfSAndroid Build Coastguard Worker 
151*d95af8dfSAndroid Build Coastguard Worker 	return use_flags;
152*d95af8dfSAndroid Build Coastguard Worker }
153*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_convert_map_usage(uint64_t usage)154*d95af8dfSAndroid Build Coastguard Worker uint32_t cros_gralloc_convert_map_usage(uint64_t usage)
155*d95af8dfSAndroid Build Coastguard Worker {
156*d95af8dfSAndroid Build Coastguard Worker 	uint32_t map_flags = BO_MAP_NONE;
157*d95af8dfSAndroid Build Coastguard Worker 
158*d95af8dfSAndroid Build Coastguard Worker 	if (usage & GRALLOC_USAGE_SW_READ_MASK)
159*d95af8dfSAndroid Build Coastguard Worker 		map_flags |= BO_MAP_READ;
160*d95af8dfSAndroid Build Coastguard Worker 	if (usage & GRALLOC_USAGE_SW_WRITE_MASK)
161*d95af8dfSAndroid Build Coastguard Worker 		map_flags |= BO_MAP_WRITE;
162*d95af8dfSAndroid Build Coastguard Worker 
163*d95af8dfSAndroid Build Coastguard Worker 	return map_flags;
164*d95af8dfSAndroid Build Coastguard Worker }
165*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_convert_handle(buffer_handle_t handle)166*d95af8dfSAndroid Build Coastguard Worker cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle)
167*d95af8dfSAndroid Build Coastguard Worker {
168*d95af8dfSAndroid Build Coastguard Worker 	if (sizeof(native_handle_t) + (sizeof(int) * (handle->numFds + handle->numInts)) !=
169*d95af8dfSAndroid Build Coastguard Worker 	    sizeof(struct cros_gralloc_handle))
170*d95af8dfSAndroid Build Coastguard Worker 		return nullptr;
171*d95af8dfSAndroid Build Coastguard Worker 
172*d95af8dfSAndroid Build Coastguard Worker 	auto hnd = reinterpret_cast<cros_gralloc_handle_t>(handle);
173*d95af8dfSAndroid Build Coastguard Worker 	if (!hnd || hnd->magic != cros_gralloc_magic)
174*d95af8dfSAndroid Build Coastguard Worker 		return nullptr;
175*d95af8dfSAndroid Build Coastguard Worker 
176*d95af8dfSAndroid Build Coastguard Worker 	// if hnd->reserved_region_size == 0, handle->numFds is hnd->num_planes
177*d95af8dfSAndroid Build Coastguard Worker 	// if hnd->reserved_region_size > 0, handle->numFds is hnd->num_planes + 1
178*d95af8dfSAndroid Build Coastguard Worker 	if ((uint32_t)handle->numFds != hnd->num_planes + (hnd->reserved_region_size > 0))
179*d95af8dfSAndroid Build Coastguard Worker 		return nullptr;
180*d95af8dfSAndroid Build Coastguard Worker 
181*d95af8dfSAndroid Build Coastguard Worker 	return hnd;
182*d95af8dfSAndroid Build Coastguard Worker }
183*d95af8dfSAndroid Build Coastguard Worker 
cros_gralloc_sync_wait(int32_t fence,bool close_fence)184*d95af8dfSAndroid Build Coastguard Worker int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence)
185*d95af8dfSAndroid Build Coastguard Worker {
186*d95af8dfSAndroid Build Coastguard Worker 	if (fence < 0)
187*d95af8dfSAndroid Build Coastguard Worker 		return 0;
188*d95af8dfSAndroid Build Coastguard Worker 
189*d95af8dfSAndroid Build Coastguard Worker 	/*
190*d95af8dfSAndroid Build Coastguard Worker 	 * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT
191*d95af8dfSAndroid Build Coastguard Worker 	 * documentation states the caller waits indefinitely on the fence if timeout < 0.
192*d95af8dfSAndroid Build Coastguard Worker 	 */
193*d95af8dfSAndroid Build Coastguard Worker 	int err = sync_wait(fence, 1000);
194*d95af8dfSAndroid Build Coastguard Worker 	if (err < 0) {
195*d95af8dfSAndroid Build Coastguard Worker 		ALOGE("Timed out on sync wait, err = %s", strerror(errno));
196*d95af8dfSAndroid Build Coastguard Worker 		err = sync_wait(fence, -1);
197*d95af8dfSAndroid Build Coastguard Worker 		if (err < 0) {
198*d95af8dfSAndroid Build Coastguard Worker 			ALOGE("sync wait error = %s", strerror(errno));
199*d95af8dfSAndroid Build Coastguard Worker 			return -errno;
200*d95af8dfSAndroid Build Coastguard Worker 		}
201*d95af8dfSAndroid Build Coastguard Worker 	}
202*d95af8dfSAndroid Build Coastguard Worker 
203*d95af8dfSAndroid Build Coastguard Worker 	if (close_fence) {
204*d95af8dfSAndroid Build Coastguard Worker 		err = close(fence);
205*d95af8dfSAndroid Build Coastguard Worker 		if (err) {
206*d95af8dfSAndroid Build Coastguard Worker 			ALOGE("Unable to close fence fd, err = %s", strerror(errno));
207*d95af8dfSAndroid Build Coastguard Worker 			return -errno;
208*d95af8dfSAndroid Build Coastguard Worker 		}
209*d95af8dfSAndroid Build Coastguard Worker 	}
210*d95af8dfSAndroid Build Coastguard Worker 
211*d95af8dfSAndroid Build Coastguard Worker 	return 0;
212*d95af8dfSAndroid Build Coastguard Worker }
213*d95af8dfSAndroid Build Coastguard Worker 
get_drm_format_string(uint32_t drm_format)214*d95af8dfSAndroid Build Coastguard Worker std::string get_drm_format_string(uint32_t drm_format)
215*d95af8dfSAndroid Build Coastguard Worker {
216*d95af8dfSAndroid Build Coastguard Worker 	char *sequence = (char *)&drm_format;
217*d95af8dfSAndroid Build Coastguard Worker 	std::string s(sequence, 4);
218*d95af8dfSAndroid Build Coastguard Worker 	return "DRM_FOURCC_" + s;
219*d95af8dfSAndroid Build Coastguard Worker }
220