blob: 9c19a5500bc6a972334efc82c33e76f225dcb270 [file] [log] [blame]
Daniel Stone903721a2017-04-04 17:54:20 +01001/*
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +03002 * Copyright © 2016, 2019 Collabora, Ltd.
Pekka Paalanene7c91b62018-09-26 14:00:34 +03003 * Copyright (c) 2018 DisplayLink (UK) Ltd.
Daniel Stone903721a2017-04-04 17:54:20 +01004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Author: Daniel Stone <daniels@collabora.com>
25 */
26
27#include "config.h"
28
29#include <endian.h>
30#include <inttypes.h>
31#include <stdbool.h>
32#include <unistd.h>
Marius Vlad6f6fd262021-07-12 12:58:34 +030033#include <stdio.h>
Pekka Paalanenf5ed7432018-09-26 14:26:53 +030034#include <string.h>
Marius Vlad6f6fd262021-07-12 12:58:34 +030035#include <stdlib.h>
Marius Vlada9a63042018-11-20 17:04:57 +020036#include <wayland-client-protocol.h>
Daniel Stone903721a2017-04-04 17:54:20 +010037
Marius Vlad6f6fd262021-07-12 12:58:34 +030038#include <xf86drm.h>
39
Pekka Paalanenc232f8d2019-04-05 16:09:45 +030040#include "shared/helpers.h"
Marius Vlad6f6fd262021-07-12 12:58:34 +030041#include "shared/string-helpers.h"
Pekka Paalanen4b301fe2021-02-04 17:39:45 +020042#include "shared/weston-drm-fourcc.h"
Daniel Stone903721a2017-04-04 17:54:20 +010043#include "wayland-util.h"
44#include "pixel-formats.h"
45
Pekka Paalanena4ecf962021-03-03 14:45:55 +020046#ifdef ENABLE_EGL
Daniel Stone903721a2017-04-04 17:54:20 +010047#include <EGL/egl.h>
48#include <EGL/eglext.h>
49#include <GLES2/gl2.h>
50#include <GLES2/gl2ext.h>
51#define GL_FORMAT(fmt) .gl_format = (fmt)
52#define GL_TYPE(type) .gl_type = (type)
53#define SAMPLER_TYPE(type) .sampler_type = (type)
54#else
55#define GL_FORMAT(fmt) .gl_format = 0
56#define GL_TYPE(type) .gl_type = 0
57#define SAMPLER_TYPE(type) .sampler_type = 0
58#endif
59
Pekka Paalanene7c91b62018-09-26 14:00:34 +030060#define DRM_FORMAT(f) .format = DRM_FORMAT_ ## f, .drm_format_name = #f
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030061#define BITS_RGBA_FIXED(r_, g_, b_, a_) \
62 .bits.r = r_, \
63 .bits.g = g_, \
64 .bits.b = b_, \
65 .bits.a = a_, \
66 .component_type = PIXEL_COMPONENT_TYPE_FIXED
Pekka Paalanene7c91b62018-09-26 14:00:34 +030067
Pekka Paalanenc232f8d2019-04-05 16:09:45 +030068#include "shared/weston-egl-ext.h"
Daniel Stone903721a2017-04-04 17:54:20 +010069
70/**
71 * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
72 * supported. Indexed/greyscale formats, and formats not containing complete
73 * colour channels, are not supported.
74 */
75static const struct pixel_format_info pixel_format_table[] = {
76 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030077 DRM_FORMAT(XRGB4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030078 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010079 },
80 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030081 DRM_FORMAT(ARGB4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030082 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +010083 .opaque_substitute = DRM_FORMAT_XRGB4444,
84 },
85 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030086 DRM_FORMAT(XBGR4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030087 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010088 },
89 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030090 DRM_FORMAT(ABGR4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030091 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +010092 .opaque_substitute = DRM_FORMAT_XBGR4444,
93 },
94 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030095 DRM_FORMAT(RGBX4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030096 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010097# if __BYTE_ORDER == __LITTLE_ENDIAN
98 GL_FORMAT(GL_RGBA),
99 GL_TYPE(GL_UNSIGNED_SHORT_4_4_4_4),
100#endif
101 },
102 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300103 DRM_FORMAT(RGBA4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300104 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +0100105 .opaque_substitute = DRM_FORMAT_RGBX4444,
106# if __BYTE_ORDER == __LITTLE_ENDIAN
107 GL_FORMAT(GL_RGBA),
108 GL_TYPE(GL_UNSIGNED_SHORT_4_4_4_4),
109#endif
110 },
111 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300112 DRM_FORMAT(BGRX4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300113 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100114 },
115 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300116 DRM_FORMAT(BGRA4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300117 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +0100118 .opaque_substitute = DRM_FORMAT_BGRX4444,
119 },
120 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300121 DRM_FORMAT(XRGB1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300122 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100123 .depth = 15,
124 .bpp = 16,
125 },
126 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300127 DRM_FORMAT(ARGB1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300128 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100129 .opaque_substitute = DRM_FORMAT_XRGB1555,
130 },
131 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300132 DRM_FORMAT(XBGR1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300133 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100134 },
135 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300136 DRM_FORMAT(ABGR1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300137 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100138 .opaque_substitute = DRM_FORMAT_XBGR1555,
139 },
140 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300141 DRM_FORMAT(RGBX5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300142 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100143# if __BYTE_ORDER == __LITTLE_ENDIAN
144 GL_FORMAT(GL_RGBA),
145 GL_TYPE(GL_UNSIGNED_SHORT_5_5_5_1),
146#endif
147 },
148 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300149 DRM_FORMAT(RGBA5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300150 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100151 .opaque_substitute = DRM_FORMAT_RGBX5551,
152# if __BYTE_ORDER == __LITTLE_ENDIAN
153 GL_FORMAT(GL_RGBA),
154 GL_TYPE(GL_UNSIGNED_SHORT_5_5_5_1),
155#endif
156 },
157 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300158 DRM_FORMAT(BGRX5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300159 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100160 },
161 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300162 DRM_FORMAT(BGRA5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300163 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100164 .opaque_substitute = DRM_FORMAT_BGRX5551,
165 },
166 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300167 DRM_FORMAT(RGB565),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300168 BITS_RGBA_FIXED(5, 6, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100169 .depth = 16,
170 .bpp = 16,
171# if __BYTE_ORDER == __LITTLE_ENDIAN
172 GL_FORMAT(GL_RGB),
173 GL_TYPE(GL_UNSIGNED_SHORT_5_6_5),
174#endif
175 },
176 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300177 DRM_FORMAT(BGR565),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300178 BITS_RGBA_FIXED(5, 6, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100179 },
180 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300181 DRM_FORMAT(RGB888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300182 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100183 },
184 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300185 DRM_FORMAT(BGR888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300186 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100187 GL_FORMAT(GL_RGB),
188 GL_TYPE(GL_UNSIGNED_BYTE),
189 },
190 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300191 DRM_FORMAT(XRGB8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300192 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100193 .depth = 24,
194 .bpp = 32,
195 GL_FORMAT(GL_BGRA_EXT),
196 GL_TYPE(GL_UNSIGNED_BYTE),
197 },
198 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300199 DRM_FORMAT(ARGB8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300200 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100201 .opaque_substitute = DRM_FORMAT_XRGB8888,
202 .depth = 32,
203 .bpp = 32,
204 GL_FORMAT(GL_BGRA_EXT),
205 GL_TYPE(GL_UNSIGNED_BYTE),
206 },
207 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300208 DRM_FORMAT(XBGR8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300209 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100210 GL_FORMAT(GL_RGBA),
211 GL_TYPE(GL_UNSIGNED_BYTE),
212 },
213 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300214 DRM_FORMAT(ABGR8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300215 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100216 .opaque_substitute = DRM_FORMAT_XBGR8888,
217 GL_FORMAT(GL_RGBA),
218 GL_TYPE(GL_UNSIGNED_BYTE),
219 },
220 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300221 DRM_FORMAT(RGBX8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300222 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100223 },
224 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300225 DRM_FORMAT(RGBA8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300226 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100227 .opaque_substitute = DRM_FORMAT_RGBX8888,
228 },
229 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300230 DRM_FORMAT(BGRX8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300231 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100232 },
233 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300234 DRM_FORMAT(BGRA8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300235 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100236 .opaque_substitute = DRM_FORMAT_BGRX8888,
237 },
238 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300239 DRM_FORMAT(XRGB2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300240 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100241 .depth = 30,
242 .bpp = 32,
243 },
244 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300245 DRM_FORMAT(ARGB2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300246 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100247 .opaque_substitute = DRM_FORMAT_XRGB2101010,
248 },
249 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300250 DRM_FORMAT(XBGR2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300251 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100252# if __BYTE_ORDER == __LITTLE_ENDIAN
253 GL_FORMAT(GL_RGBA),
254 GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
255#endif
256 },
257 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300258 DRM_FORMAT(ABGR2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300259 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100260 .opaque_substitute = DRM_FORMAT_XBGR2101010,
261# if __BYTE_ORDER == __LITTLE_ENDIAN
262 GL_FORMAT(GL_RGBA),
263 GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
264#endif
265 },
266 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300267 DRM_FORMAT(RGBX1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300268 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100269 },
270 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300271 DRM_FORMAT(RGBA1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300272 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100273 .opaque_substitute = DRM_FORMAT_RGBX1010102,
274 },
275 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300276 DRM_FORMAT(BGRX1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300277 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100278 },
279 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300280 DRM_FORMAT(BGRA1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300281 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100282 .opaque_substitute = DRM_FORMAT_BGRX1010102,
283 },
284 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300285 DRM_FORMAT(YUYV),
Daniel Stone903721a2017-04-04 17:54:20 +0100286 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
287 .num_planes = 1,
288 .hsub = 2,
289 },
290 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300291 DRM_FORMAT(YVYU),
Daniel Stone903721a2017-04-04 17:54:20 +0100292 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
293 .num_planes = 1,
294 .chroma_order = ORDER_VU,
295 .hsub = 2,
296 },
297 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300298 DRM_FORMAT(UYVY),
Daniel Stone903721a2017-04-04 17:54:20 +0100299 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
300 .num_planes = 1,
301 .luma_chroma_order = ORDER_CHROMA_LUMA,
302 .hsub = 2,
303 },
304 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300305 DRM_FORMAT(VYUY),
Daniel Stone903721a2017-04-04 17:54:20 +0100306 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
307 .num_planes = 1,
308 .luma_chroma_order = ORDER_CHROMA_LUMA,
309 .chroma_order = ORDER_VU,
310 .hsub = 2,
311 },
312 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300313 DRM_FORMAT(NV12),
Daniel Stone903721a2017-04-04 17:54:20 +0100314 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
315 .num_planes = 2,
316 .hsub = 2,
317 .vsub = 2,
318 },
319 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300320 DRM_FORMAT(NV21),
Daniel Stone903721a2017-04-04 17:54:20 +0100321 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
322 .num_planes = 2,
323 .chroma_order = ORDER_VU,
324 .hsub = 2,
325 .vsub = 2,
326 },
327 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300328 DRM_FORMAT(NV16),
Daniel Stone903721a2017-04-04 17:54:20 +0100329 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
330 .num_planes = 2,
331 .hsub = 2,
332 .vsub = 1,
333 },
334 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300335 DRM_FORMAT(NV61),
Daniel Stone903721a2017-04-04 17:54:20 +0100336 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
337 .num_planes = 2,
338 .chroma_order = ORDER_VU,
339 .hsub = 2,
340 .vsub = 1,
341 },
342 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300343 DRM_FORMAT(NV24),
Daniel Stone903721a2017-04-04 17:54:20 +0100344 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
345 .num_planes = 2,
346 },
347 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300348 DRM_FORMAT(NV42),
Daniel Stone903721a2017-04-04 17:54:20 +0100349 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
350 .num_planes = 2,
351 .chroma_order = ORDER_VU,
352 },
353 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300354 DRM_FORMAT(YUV410),
Daniel Stone903721a2017-04-04 17:54:20 +0100355 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
356 .num_planes = 3,
357 .hsub = 4,
358 .vsub = 4,
359 },
360 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300361 DRM_FORMAT(YVU410),
Daniel Stone903721a2017-04-04 17:54:20 +0100362 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
363 .num_planes = 3,
364 .chroma_order = ORDER_VU,
365 .hsub = 4,
366 .vsub = 4,
367 },
368 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300369 DRM_FORMAT(YUV411),
Daniel Stone903721a2017-04-04 17:54:20 +0100370 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
371 .num_planes = 3,
372 .hsub = 4,
373 .vsub = 1,
374 },
375 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300376 DRM_FORMAT(YVU411),
Daniel Stone903721a2017-04-04 17:54:20 +0100377 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
378 .num_planes = 3,
379 .chroma_order = ORDER_VU,
380 .hsub = 4,
381 .vsub = 1,
382 },
383 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300384 DRM_FORMAT(YUV420),
Daniel Stone903721a2017-04-04 17:54:20 +0100385 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
386 .num_planes = 3,
387 .hsub = 2,
388 .vsub = 2,
389 },
390 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300391 DRM_FORMAT(YVU420),
Daniel Stone903721a2017-04-04 17:54:20 +0100392 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
393 .num_planes = 3,
394 .chroma_order = ORDER_VU,
395 .hsub = 2,
396 .vsub = 2,
397 },
398 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300399 DRM_FORMAT(YUV422),
Daniel Stone903721a2017-04-04 17:54:20 +0100400 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
401 .num_planes = 3,
402 .hsub = 2,
403 .vsub = 1,
404 },
405 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300406 DRM_FORMAT(YVU422),
Daniel Stone903721a2017-04-04 17:54:20 +0100407 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
408 .num_planes = 3,
409 .chroma_order = ORDER_VU,
410 .hsub = 2,
411 .vsub = 1,
412 },
413 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300414 DRM_FORMAT(YUV444),
Daniel Stone903721a2017-04-04 17:54:20 +0100415 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
416 .num_planes = 3,
417 },
418 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300419 DRM_FORMAT(YVU444),
Daniel Stone903721a2017-04-04 17:54:20 +0100420 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
421 .num_planes = 3,
422 .chroma_order = ORDER_VU,
423 },
424};
425
426WL_EXPORT const struct pixel_format_info *
Marius Vlada9a63042018-11-20 17:04:57 +0200427pixel_format_get_info_shm(uint32_t format)
428{
429 if (format == WL_SHM_FORMAT_XRGB8888)
430 return pixel_format_get_info(DRM_FORMAT_XRGB8888);
431 else if (format == WL_SHM_FORMAT_ARGB8888)
432 return pixel_format_get_info(DRM_FORMAT_ARGB8888);
433 else
434 return pixel_format_get_info(format);
435}
436
437WL_EXPORT const struct pixel_format_info *
Daniel Stone903721a2017-04-04 17:54:20 +0100438pixel_format_get_info(uint32_t format)
439{
440 unsigned int i;
441
442 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
443 if (pixel_format_table[i].format == format)
444 return &pixel_format_table[i];
445 }
446
447 return NULL;
448}
449
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300450WL_EXPORT const struct pixel_format_info *
451pixel_format_get_info_by_drm_name(const char *drm_format_name)
452{
453 const struct pixel_format_info *info;
454 unsigned int i;
455
456 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
457 info = &pixel_format_table[i];
458 if (strcasecmp(info->drm_format_name, drm_format_name) == 0)
459 return info;
460 }
461
462 return NULL;
463}
464
Daniel Stone903721a2017-04-04 17:54:20 +0100465WL_EXPORT unsigned int
466pixel_format_get_plane_count(const struct pixel_format_info *info)
467{
468 return info->num_planes ? info->num_planes : 1;
469}
470
471WL_EXPORT bool
472pixel_format_is_opaque(const struct pixel_format_info *info)
473{
474 return !info->opaque_substitute;
475}
476
Daniel Stone903721a2017-04-04 17:54:20 +0100477WL_EXPORT const struct pixel_format_info *
478pixel_format_get_opaque_substitute(const struct pixel_format_info *info)
479{
480 if (!info->opaque_substitute)
481 return info;
482 else
483 return pixel_format_get_info(info->opaque_substitute);
484}
485
Pekka Paalanen8ba775d2019-09-13 14:44:24 +0300486WL_EXPORT const struct pixel_format_info *
487pixel_format_get_info_by_opaque_substitute(uint32_t format)
488{
489 unsigned int i;
490
491 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
492 if (pixel_format_table[i].opaque_substitute == format)
493 return &pixel_format_table[i];
494 }
495
496 return NULL;
497}
498
Daniel Stone903721a2017-04-04 17:54:20 +0100499WL_EXPORT unsigned int
500pixel_format_width_for_plane(const struct pixel_format_info *info,
501 unsigned int plane,
502 unsigned int width)
503{
504 /* We don't support any formats where the first plane is subsampled. */
505 if (plane == 0 || !info->hsub)
506 return width;
507
508 return width / info->hsub;
509}
510
511WL_EXPORT unsigned int
512pixel_format_height_for_plane(const struct pixel_format_info *info,
513 unsigned int plane,
514 unsigned int height)
515{
516 /* We don't support any formats where the first plane is subsampled. */
517 if (plane == 0 || !info->vsub)
518 return height;
519
520 return height / info->vsub;
521}
Marius Vlad6f6fd262021-07-12 12:58:34 +0300522
523#ifdef HAVE_HUMAN_FORMAT_MODIFIER
524WL_EXPORT char *
525pixel_format_get_modifier(uint64_t modifier)
526{
527 char *modifier_name;
528 char *vendor_name;
529 char *mod_str;
530
531 modifier_name = drmGetFormatModifierName(modifier);
532 vendor_name = drmGetFormatModifierVendor(modifier);
533
534 if (!modifier_name) {
535 if (vendor_name)
536 str_printf(&mod_str, "%s_%s (0x%llx)",
537 vendor_name, "UNKNOWN_MODIFIER",
538 (unsigned long long) modifier);
539 else
540 str_printf(&mod_str, "0x%llx",
541 (unsigned long long) modifier);
542
543 free(vendor_name);
544 return mod_str;
545 }
546
547 if (modifier == DRM_FORMAT_MOD_LINEAR) {
548 str_printf(&mod_str, "%s (0x%llx)", modifier_name,
549 (unsigned long long) modifier);
550 free(modifier_name);
551 free(vendor_name);
552 return mod_str;
553 }
554
555 str_printf(&mod_str, "%s_%s (0x%llx)", vendor_name, modifier_name,
556 (unsigned long long) modifier);
557
558 free(modifier_name);
559 free(vendor_name);
560
561 return mod_str;
562}
563#else
564WL_EXPORT char *
565pixel_format_get_modifier(uint64_t modifier)
566{
567 char *mod_str;
568 str_printf(&mod_str, "0x%llx", (unsigned long long) modifier);
569 return mod_str;
570}
571#endif