summaryrefslogtreecommitdiff
path: root/cros_gralloc/cros_gralloc_helpers.cc
blob: 86b4c8c854f519278b1500cbcbb98e373af4cad1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
 * Copyright 2016 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "cros_gralloc_helpers.h"

#include <hardware/gralloc.h>
#include <sync/sync.h>

/* Define to match AIDL BufferUsage::VIDEO_DECODER. */
#define BUFFER_USAGE_VIDEO_DECODER (1 << 22)

/* Define to match AIDL BufferUsage::GPU_DATA_BUFFER. */
#define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24)

uint32_t cros_gralloc_convert_format(int format)
{
	/*
	 * Conversion from HAL to fourcc-based DRV formats based on
	 * platform_android.c in mesa.
	 */

	switch (format) {
	case HAL_PIXEL_FORMAT_RGBA_8888:
		return DRM_FORMAT_ABGR8888;
	case HAL_PIXEL_FORMAT_RGBX_8888:
		return DRM_FORMAT_XBGR8888;
	case HAL_PIXEL_FORMAT_RGB_888:
		return DRM_FORMAT_BGR888;
	case HAL_PIXEL_FORMAT_RGB_565:
		return DRM_FORMAT_RGB565;
	case HAL_PIXEL_FORMAT_BGRA_8888:
		return DRM_FORMAT_ARGB8888;
	case HAL_PIXEL_FORMAT_RAW16:
		return DRM_FORMAT_R16;
	/*
	 * Choose DRM_FORMAT_R8 because <system/graphics.h> requires the buffers
	 * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width
	 * equal to their size in bytes.
	 */
	case HAL_PIXEL_FORMAT_BLOB:
		return DRM_FORMAT_R8;
	case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
		return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED;
	case HAL_PIXEL_FORMAT_YCbCr_420_888:
		return DRM_FORMAT_FLEX_YCbCr_420_888;
	case HAL_PIXEL_FORMAT_Y8:
		return DRM_FORMAT_R8;
	case HAL_PIXEL_FORMAT_Y16:
		return DRM_FORMAT_R16;
	case HAL_PIXEL_FORMAT_YV12:
		return DRM_FORMAT_YVU420_ANDROID;
#if ANDROID_API_LEVEL >= 29
	case HAL_PIXEL_FORMAT_RGBA_FP16:
		return DRM_FORMAT_ABGR16161616F;
	case HAL_PIXEL_FORMAT_RGBA_1010102:
		return DRM_FORMAT_ABGR2101010;
#endif
#if ANDROID_API_LEVEL >= 30
	case HAL_PIXEL_FORMAT_YCBCR_P010:
		return DRM_FORMAT_P010;
#endif
	}

	return DRM_FORMAT_NONE;
}

uint64_t cros_gralloc_convert_usage(uint64_t usage)
{
	uint64_t use_flags = BO_USE_NONE;

	if (usage & GRALLOC_USAGE_CURSOR)
		use_flags |= BO_USE_NONE;
	if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)
		use_flags |= BO_USE_SW_READ_RARELY;
	if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN)
		use_flags |= BO_USE_SW_READ_OFTEN;
	if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
		use_flags |= BO_USE_SW_WRITE_RARELY;
	if ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_OFTEN)
		use_flags |= BO_USE_SW_WRITE_OFTEN;
	if (usage & GRALLOC_USAGE_HW_TEXTURE)
		use_flags |= BO_USE_TEXTURE;
	if (usage & GRALLOC_USAGE_HW_RENDER)
		use_flags |= BO_USE_RENDERING;
	if (usage & GRALLOC_USAGE_HW_2D)
		use_flags |= BO_USE_RENDERING;
	if (usage & GRALLOC_USAGE_HW_COMPOSER)
		/* HWC wants to use display hardware, but can defer to OpenGL. */
		use_flags |= BO_USE_SCANOUT | BO_USE_TEXTURE;
	if (usage & GRALLOC_USAGE_HW_FB)
		use_flags |= BO_USE_NONE;
	if (usage & GRALLOC_USAGE_EXTERNAL_DISP)
		/*
		 * This flag potentially covers external display for the normal drivers (i915,
		 * rockchip) and usb monitors (evdi/udl). It's complicated so ignore it.
		 * */
		use_flags |= BO_USE_NONE;
	/* Map this flag to linear until real HW protection is available on Android. */
	if (usage & GRALLOC_USAGE_PROTECTED)
		use_flags |= BO_USE_LINEAR;
	if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
		use_flags |= BO_USE_HW_VIDEO_ENCODER;
		/*HACK: See b/30054495 */
		use_flags |= BO_USE_SW_READ_OFTEN;
	}
	if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
		use_flags |= BO_USE_CAMERA_WRITE;
	if (usage & GRALLOC_USAGE_HW_CAMERA_READ)
		use_flags |= BO_USE_CAMERA_READ;
	if (usage & GRALLOC_USAGE_RENDERSCRIPT)
		use_flags |= BO_USE_RENDERSCRIPT;
	if (usage & BUFFER_USAGE_VIDEO_DECODER)
		use_flags |= BO_USE_HW_VIDEO_DECODER;
	if (usage & BUFFER_USAGE_FRONT_RENDERING)
		use_flags |= BO_USE_FRONT_RENDERING;
	if (usage & BUFFER_USAGE_GPU_DATA_BUFFER)
		use_flags |= BO_USE_GPU_DATA_BUFFER;

	return use_flags;
}

uint32_t cros_gralloc_convert_map_usage(uint64_t usage)
{
	uint32_t map_flags = BO_MAP_NONE;

	if (usage & GRALLOC_USAGE_SW_READ_MASK)
		map_flags |= BO_MAP_READ;
	if (usage & GRALLOC_USAGE_SW_WRITE_MASK)
		map_flags |= BO_MAP_WRITE;

	return map_flags;
}

cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle)
{
	auto hnd = reinterpret_cast<cros_gralloc_handle_t>(handle);
	if (!hnd || hnd->magic != cros_gralloc_magic)
		return nullptr;

	return hnd;
}

int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence)
{
	if (fence < 0)
		return 0;

	/*
	 * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT
	 * documentation states the caller waits indefinitely on the fence if timeout < 0.
	 */
	int err = sync_wait(fence, 1000);
	if (err < 0) {
		drv_log("Timed out on sync wait, err = %s\n", strerror(errno));
		err = sync_wait(fence, -1);
		if (err < 0) {
			drv_log("sync wait error = %s\n", strerror(errno));
			return -errno;
		}
	}

	if (close_fence) {
		err = close(fence);
		if (err) {
			drv_log("Unable to close fence fd, err = %s\n", strerror(errno));
			return -errno;
		}
	}

	return 0;
}

std::string get_drm_format_string(uint32_t drm_format)
{
	char *sequence = (char *)&drm_format;
	std::string s(sequence, 4);
	return "DRM_FOURCC_" + s;
}