summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_format_internal.h
blob: 9f857bfa368d10d4a8155c7d0828d38c4f23e6b7 (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
/* SPDX-License-Identifier: GPL-2.0 or MIT */

#ifndef DRM_FORMAT_INTERNAL_H
#define DRM_FORMAT_INTERNAL_H

#include <linux/bits.h>
#include <linux/types.h>

/*
 * Each pixel-format conversion helper takes a raw pixel in a
 * specific input format and returns a raw pixel in a specific
 * output format. All pixels are in little-endian byte order.
 *
 * Function names are
 *
 *   drm_pixel_<input>_to_<output>_<algorithm>()
 *
 * where <input> and <output> refer to pixel formats. The
 * <algorithm> is optional and hints to the method used for the
 * conversion. Helpers with no algorithm given apply pixel-bit
 * shifting.
 *
 * The argument type is u32. We expect this to be wide enough to
 * hold all conversion input from 32-bit RGB to any output format.
 * The Linux kernel should avoid format conversion for anything
 * but XRGB8888 input data. Converting from other format can still
 * be acceptable in some cases.
 *
 * The return type is u32. It is wide enough to hold all conversion
 * output from XRGB8888. For output formats wider than 32 bit, a
 * return type of u64 would be acceptable.
 */

/*
 * Conversions from XRGB8888
 */

static inline u32 drm_pixel_xrgb8888_to_r8_bt601(u32 pix)
{
	u32 r = (pix & 0x00ff0000) >> 16;
	u32 g = (pix & 0x0000ff00) >> 8;
	u32 b =  pix & 0x000000ff;

	/* ITU-R BT.601: Y = 0.299 R + 0.587 G + 0.114 B */
	return (3 * r + 6 * g + b) / 10;
}

static inline u32 drm_pixel_xrgb8888_to_rgb332(u32 pix)
{
	return ((pix & 0x00e00000) >> 16) |
	       ((pix & 0x0000e000) >> 11) |
	       ((pix & 0x000000c0) >> 6);
}

static inline u32 drm_pixel_xrgb8888_to_rgb565(u32 pix)
{
	return ((pix & 0x00f80000) >> 8) |
	       ((pix & 0x0000fc00) >> 5) |
	       ((pix & 0x000000f8) >> 3);
}

static inline u32 drm_pixel_xrgb8888_to_rgbx5551(u32 pix)
{
	return ((pix & 0x00f80000) >> 8) |
	       ((pix & 0x0000f800) >> 5) |
	       ((pix & 0x000000f8) >> 2);
}

static inline u32 drm_pixel_xrgb8888_to_rgba5551(u32 pix)
{
	return drm_pixel_xrgb8888_to_rgbx5551(pix) |
	       BIT(0); /* set alpha bit */
}

static inline u32 drm_pixel_xrgb8888_to_xrgb1555(u32 pix)
{
	return ((pix & 0x00f80000) >> 9) |
	       ((pix & 0x0000f800) >> 6) |
	       ((pix & 0x000000f8) >> 3);
}

static inline u32 drm_pixel_xrgb8888_to_argb1555(u32 pix)
{
	return BIT(15) | /* set alpha bit */
	       drm_pixel_xrgb8888_to_xrgb1555(pix);
}

static inline u32 drm_pixel_xrgb8888_to_rgb888(u32 pix)
{
	return pix & GENMASK(23, 0);
}

static inline u32 drm_pixel_xrgb8888_to_bgr888(u32 pix)
{
	return ((pix & 0x00ff0000) >> 16) |
	       ((pix & 0x0000ff00)) |
	       ((pix & 0x000000ff) << 16);
}

static inline u32 drm_pixel_xrgb8888_to_argb8888(u32 pix)
{
	return GENMASK(31, 24) | /* fill alpha bits */
	       pix;
}

static inline u32 drm_pixel_xrgb8888_to_xbgr8888(u32 pix)
{
	return ((pix & 0xff000000)) | /* also copy filler bits */
	       ((pix & 0x00ff0000) >> 16) |
	       ((pix & 0x0000ff00)) |
	       ((pix & 0x000000ff) << 16);
}

static inline u32 drm_pixel_xrgb8888_to_abgr8888(u32 pix)
{
	return GENMASK(31, 24) | /* fill alpha bits */
	       drm_pixel_xrgb8888_to_xbgr8888(pix);
}

static inline u32 drm_pixel_xrgb8888_to_xrgb2101010(u32 pix)
{
	pix = ((pix & 0x000000ff) << 2) |
	      ((pix & 0x0000ff00) << 4) |
	      ((pix & 0x00ff0000) << 6);
	return pix | ((pix >> 8) & 0x00300c03);
}

static inline u32 drm_pixel_xrgb8888_to_argb2101010(u32 pix)
{
	return GENMASK(31, 30) | /* set alpha bits */
	       drm_pixel_xrgb8888_to_xrgb2101010(pix);
}

static inline u32 drm_pixel_xrgb8888_to_xbgr2101010(u32 pix)
{
	pix = ((pix & 0x00ff0000) >> 14) |
	      ((pix & 0x0000ff00) << 4) |
	      ((pix & 0x000000ff) << 22);
	return pix | ((pix >> 8) & 0x00300c03);
}

static inline u32 drm_pixel_xrgb8888_to_abgr2101010(u32 pix)
{
	return GENMASK(31, 30) | /* set alpha bits */
	       drm_pixel_xrgb8888_to_xbgr2101010(pix);
}

/*
 * Conversion from ARGB8888
 */

static inline u32 drm_pixel_argb8888_to_argb4444(u32 pix)
{
	return ((pix & 0xf0000000) >> 16) |
	       ((pix & 0x00f00000) >> 12) |
	       ((pix & 0x0000f000) >> 8) |
	       ((pix & 0x000000f0) >> 4);
}

#endif