aboutsummaryrefslogtreecommitdiff
path: root/render/pixman/pixel_format.c
blob: 5a460a0a26503de801062ad92ab4d03e4e36d413 (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
#include <drm_fourcc.h>
#include <wlr/util/log.h>

#include "render/pixman.h"

static const struct wlr_pixman_pixel_format formats[] = {
	{
		.drm_format = DRM_FORMAT_ARGB8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_b8g8r8a8,
#else
		.pixman_format = PIXMAN_a8r8g8b8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_XBGR8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_r8g8b8x8,
#else
		.pixman_format = PIXMAN_x8b8g8r8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_XRGB8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_b8g8r8x8,
#else
		.pixman_format = PIXMAN_x8r8g8b8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_ABGR8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_r8g8b8a8,
#else
		.pixman_format = PIXMAN_a8b8g8r8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_RGBA8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_a8b8g8r8,
#else
		.pixman_format = PIXMAN_r8g8b8a8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_RGBX8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_x8b8g8r8,
#else
		.pixman_format = PIXMAN_r8g8b8x8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_BGRA8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_a8r8g8b8,
#else
		.pixman_format = PIXMAN_b8g8r8a8,
#endif
	},
	{
		.drm_format = DRM_FORMAT_BGRX8888,
#if WLR_BIG_ENDIAN
		.pixman_format = PIXMAN_x8r8g8b8,
#else
		.pixman_format = PIXMAN_b8g8r8x8,
#endif
	},
#if WLR_LITTLE_ENDIAN
	// Since DRM formats are always little-endian, they don't have an
	// equivalent on big-endian if their components are spanning across
	// multiple bytes.
	{
		.drm_format = DRM_FORMAT_RGB565,
		.pixman_format = PIXMAN_r5g6b5,
	},
	{
		.drm_format = DRM_FORMAT_BGR565,
		.pixman_format = PIXMAN_b5g6r5,
	},
	{
		.drm_format = DRM_FORMAT_ARGB2101010,
		.pixman_format = PIXMAN_a2r10g10b10,
	},
	{
		.drm_format = DRM_FORMAT_XRGB2101010,
		.pixman_format = PIXMAN_x2r10g10b10,
	},
	{
		.drm_format = DRM_FORMAT_ABGR2101010,
		.pixman_format = PIXMAN_a2b10g10r10,
	},
	{
		.drm_format = DRM_FORMAT_XBGR2101010,
		.pixman_format = PIXMAN_x2b10g10r10,
	},
#endif
};

pixman_format_code_t get_pixman_format_from_drm(uint32_t fmt) {
	for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
		if (formats[i].drm_format == fmt) {
			return formats[i].pixman_format;
		}
	}

	wlr_log(WLR_ERROR, "DRM format 0x%"PRIX32" has no pixman equivalent", fmt);
	return 0;
}

uint32_t get_drm_format_from_pixman(pixman_format_code_t fmt) {
	for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
		if (formats[i].pixman_format == fmt) {
			return formats[i].drm_format;
		}
	}

	wlr_log(WLR_ERROR, "pixman format 0x%"PRIX32" has no drm equivalent", fmt);
	return DRM_FORMAT_INVALID;
}

const uint32_t *get_pixman_drm_formats(size_t *len) {
	static uint32_t drm_formats[sizeof(formats) / sizeof(formats[0])];
	*len = sizeof(formats) / sizeof(formats[0]);
	for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
		drm_formats[i] = formats[i].drm_format;
	}
	return drm_formats;
}