blob: 9064cb66619290223b3b089e78276f1264448eaf [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
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -040068#define PIXMAN_FMT(fmt) .pixman_format = (PIXMAN_ ## fmt)
69
Pekka Paalanenc232f8d2019-04-05 16:09:45 +030070#include "shared/weston-egl-ext.h"
Daniel Stone903721a2017-04-04 17:54:20 +010071
72/**
73 * Table of DRM formats supported by Weston; RGB, ARGB and YUV formats are
74 * supported. Indexed/greyscale formats, and formats not containing complete
75 * colour channels, are not supported.
76 */
77static const struct pixel_format_info pixel_format_table[] = {
78 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030079 DRM_FORMAT(XRGB4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030080 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010081 },
82 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030083 DRM_FORMAT(ARGB4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030084 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +010085 .opaque_substitute = DRM_FORMAT_XRGB4444,
86 },
87 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030088 DRM_FORMAT(XBGR4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030089 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010090 },
91 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030092 DRM_FORMAT(ABGR4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030093 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +010094 .opaque_substitute = DRM_FORMAT_XBGR4444,
95 },
96 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +030097 DRM_FORMAT(RGBX4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +030098 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +010099# if __BYTE_ORDER == __LITTLE_ENDIAN
100 GL_FORMAT(GL_RGBA),
101 GL_TYPE(GL_UNSIGNED_SHORT_4_4_4_4),
102#endif
103 },
104 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300105 DRM_FORMAT(RGBA4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300106 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +0100107 .opaque_substitute = DRM_FORMAT_RGBX4444,
108# if __BYTE_ORDER == __LITTLE_ENDIAN
109 GL_FORMAT(GL_RGBA),
110 GL_TYPE(GL_UNSIGNED_SHORT_4_4_4_4),
111#endif
112 },
113 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300114 DRM_FORMAT(BGRX4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300115 BITS_RGBA_FIXED(4, 4, 4, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100116 },
117 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300118 DRM_FORMAT(BGRA4444),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300119 BITS_RGBA_FIXED(4, 4, 4, 4),
Daniel Stone903721a2017-04-04 17:54:20 +0100120 .opaque_substitute = DRM_FORMAT_BGRX4444,
121 },
122 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300123 DRM_FORMAT(XRGB1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300124 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100125 .depth = 15,
126 .bpp = 16,
127 },
128 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300129 DRM_FORMAT(ARGB1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300130 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100131 .opaque_substitute = DRM_FORMAT_XRGB1555,
132 },
133 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300134 DRM_FORMAT(XBGR1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300135 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100136 },
137 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300138 DRM_FORMAT(ABGR1555),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300139 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100140 .opaque_substitute = DRM_FORMAT_XBGR1555,
141 },
142 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300143 DRM_FORMAT(RGBX5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300144 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100145# if __BYTE_ORDER == __LITTLE_ENDIAN
146 GL_FORMAT(GL_RGBA),
147 GL_TYPE(GL_UNSIGNED_SHORT_5_5_5_1),
148#endif
149 },
150 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300151 DRM_FORMAT(RGBA5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300152 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100153 .opaque_substitute = DRM_FORMAT_RGBX5551,
154# if __BYTE_ORDER == __LITTLE_ENDIAN
155 GL_FORMAT(GL_RGBA),
156 GL_TYPE(GL_UNSIGNED_SHORT_5_5_5_1),
157#endif
158 },
159 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300160 DRM_FORMAT(BGRX5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300161 BITS_RGBA_FIXED(5, 5, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100162 },
163 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300164 DRM_FORMAT(BGRA5551),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300165 BITS_RGBA_FIXED(5, 5, 5, 1),
Daniel Stone903721a2017-04-04 17:54:20 +0100166 .opaque_substitute = DRM_FORMAT_BGRX5551,
167 },
168 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300169 DRM_FORMAT(RGB565),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300170 BITS_RGBA_FIXED(5, 6, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100171 .depth = 16,
172 .bpp = 16,
173# if __BYTE_ORDER == __LITTLE_ENDIAN
174 GL_FORMAT(GL_RGB),
175 GL_TYPE(GL_UNSIGNED_SHORT_5_6_5),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400176 PIXMAN_FMT(r5g6b5),
Daniel Stone903721a2017-04-04 17:54:20 +0100177#endif
178 },
179 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300180 DRM_FORMAT(BGR565),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300181 BITS_RGBA_FIXED(5, 6, 5, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100182 },
183 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300184 DRM_FORMAT(RGB888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300185 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100186 },
187 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300188 DRM_FORMAT(BGR888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300189 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100190 GL_FORMAT(GL_RGB),
191 GL_TYPE(GL_UNSIGNED_BYTE),
192 },
193 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300194 DRM_FORMAT(XRGB8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300195 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100196 .depth = 24,
197 .bpp = 32,
198 GL_FORMAT(GL_BGRA_EXT),
199 GL_TYPE(GL_UNSIGNED_BYTE),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400200#if __BYTE_ORDER == __LITTLE_ENDIAN
201 PIXMAN_FMT(x8r8g8b8),
202#else
203 PIXMAN_FMT(b8g8r8x8),
204#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100205 },
206 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300207 DRM_FORMAT(ARGB8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300208 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100209 .opaque_substitute = DRM_FORMAT_XRGB8888,
210 .depth = 32,
211 .bpp = 32,
212 GL_FORMAT(GL_BGRA_EXT),
213 GL_TYPE(GL_UNSIGNED_BYTE),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400214#if __BYTE_ORDER == __LITTLE_ENDIAN
215 PIXMAN_FMT(a8r8g8b8),
216#else
217 PIXMAN_FMT(b8g8r8a8),
218#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100219 },
220 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300221 DRM_FORMAT(XBGR8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300222 BITS_RGBA_FIXED(8, 8, 8, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100223 GL_FORMAT(GL_RGBA),
224 GL_TYPE(GL_UNSIGNED_BYTE),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400225#if __BYTE_ORDER == __LITTLE_ENDIAN
226 PIXMAN_FMT(x8b8g8r8),
227#else
228 PIXMAN_FMT(r8g8b8x8),
229#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100230 },
231 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300232 DRM_FORMAT(ABGR8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300233 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100234 .opaque_substitute = DRM_FORMAT_XBGR8888,
235 GL_FORMAT(GL_RGBA),
236 GL_TYPE(GL_UNSIGNED_BYTE),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400237#if __BYTE_ORDER == __LITTLE_ENDIAN
238 PIXMAN_FMT(a8b8g8r8),
239#else
240 PIXMAN_FMT(r8g8b8a8),
241#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100242 },
243 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300244 DRM_FORMAT(RGBX8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300245 BITS_RGBA_FIXED(8, 8, 8, 0),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400246#if __BYTE_ORDER == __LITTLE_ENDIAN
247 PIXMAN_FMT(r8g8b8x8),
248#else
249 PIXMAN_FMT(x8b8g8r8),
250#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100251 },
252 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300253 DRM_FORMAT(RGBA8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300254 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100255 .opaque_substitute = DRM_FORMAT_RGBX8888,
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400256#if __BYTE_ORDER == __LITTLE_ENDIAN
257 PIXMAN_FMT(r8g8b8a8),
258#else
259 PIXMAN_FMT(a8b8g8r8),
260#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100261 },
262 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300263 DRM_FORMAT(BGRX8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300264 BITS_RGBA_FIXED(8, 8, 8, 0),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400265#if __BYTE_ORDER == __LITTLE_ENDIAN
266 PIXMAN_FMT(b8g8r8x8),
267#else
268 PIXMAN_FMT(x8r8g8b8),
269#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100270 },
271 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300272 DRM_FORMAT(BGRA8888),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300273 BITS_RGBA_FIXED(8, 8, 8, 8),
Daniel Stone903721a2017-04-04 17:54:20 +0100274 .opaque_substitute = DRM_FORMAT_BGRX8888,
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400275#if __BYTE_ORDER == __LITTLE_ENDIAN
276 PIXMAN_FMT(b8g8r8a8),
277#else
278 PIXMAN_FMT(a8r8g8b8),
279#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100280 },
281 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300282 DRM_FORMAT(XRGB2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300283 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100284 .depth = 30,
285 .bpp = 32,
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400286#if __BYTE_ORDER == __LITTLE_ENDIAN
287 PIXMAN_FMT(x2r10g10b10),
288#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100289 },
290 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300291 DRM_FORMAT(ARGB2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300292 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100293 .opaque_substitute = DRM_FORMAT_XRGB2101010,
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400294#if __BYTE_ORDER == __LITTLE_ENDIAN
295 PIXMAN_FMT(a2r10g10b10),
296#endif
Daniel Stone903721a2017-04-04 17:54:20 +0100297 },
298 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300299 DRM_FORMAT(XBGR2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300300 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100301# if __BYTE_ORDER == __LITTLE_ENDIAN
302 GL_FORMAT(GL_RGBA),
303 GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400304 PIXMAN_FMT(x2b10g10r10),
Daniel Stone903721a2017-04-04 17:54:20 +0100305#endif
306 },
307 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300308 DRM_FORMAT(ABGR2101010),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300309 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100310 .opaque_substitute = DRM_FORMAT_XBGR2101010,
311# if __BYTE_ORDER == __LITTLE_ENDIAN
312 GL_FORMAT(GL_RGBA),
313 GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400314 PIXMAN_FMT(a2b10g10r10),
Daniel Stone903721a2017-04-04 17:54:20 +0100315#endif
316 },
317 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300318 DRM_FORMAT(RGBX1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300319 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100320 },
321 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300322 DRM_FORMAT(RGBA1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300323 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100324 .opaque_substitute = DRM_FORMAT_RGBX1010102,
325 },
326 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300327 DRM_FORMAT(BGRX1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300328 BITS_RGBA_FIXED(10, 10, 10, 0),
Daniel Stone903721a2017-04-04 17:54:20 +0100329 },
330 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300331 DRM_FORMAT(BGRA1010102),
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300332 BITS_RGBA_FIXED(10, 10, 10, 2),
Daniel Stone903721a2017-04-04 17:54:20 +0100333 .opaque_substitute = DRM_FORMAT_BGRX1010102,
334 },
335 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300336 DRM_FORMAT(YUYV),
Daniel Stone903721a2017-04-04 17:54:20 +0100337 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
338 .num_planes = 1,
339 .hsub = 2,
340 },
341 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300342 DRM_FORMAT(YVYU),
Daniel Stone903721a2017-04-04 17:54:20 +0100343 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
344 .num_planes = 1,
345 .chroma_order = ORDER_VU,
346 .hsub = 2,
347 },
348 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300349 DRM_FORMAT(UYVY),
Daniel Stone903721a2017-04-04 17:54:20 +0100350 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
351 .num_planes = 1,
352 .luma_chroma_order = ORDER_CHROMA_LUMA,
353 .hsub = 2,
354 },
355 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300356 DRM_FORMAT(VYUY),
Daniel Stone903721a2017-04-04 17:54:20 +0100357 SAMPLER_TYPE(EGL_TEXTURE_Y_XUXV_WL),
358 .num_planes = 1,
359 .luma_chroma_order = ORDER_CHROMA_LUMA,
360 .chroma_order = ORDER_VU,
361 .hsub = 2,
362 },
363 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300364 DRM_FORMAT(NV12),
Daniel Stone903721a2017-04-04 17:54:20 +0100365 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
366 .num_planes = 2,
367 .hsub = 2,
368 .vsub = 2,
369 },
370 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300371 DRM_FORMAT(NV21),
Daniel Stone903721a2017-04-04 17:54:20 +0100372 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
373 .num_planes = 2,
374 .chroma_order = ORDER_VU,
375 .hsub = 2,
376 .vsub = 2,
377 },
378 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300379 DRM_FORMAT(NV16),
Daniel Stone903721a2017-04-04 17:54:20 +0100380 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
381 .num_planes = 2,
382 .hsub = 2,
383 .vsub = 1,
384 },
385 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300386 DRM_FORMAT(NV61),
Daniel Stone903721a2017-04-04 17:54:20 +0100387 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
388 .num_planes = 2,
389 .chroma_order = ORDER_VU,
390 .hsub = 2,
391 .vsub = 1,
392 },
393 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300394 DRM_FORMAT(NV24),
Daniel Stone903721a2017-04-04 17:54:20 +0100395 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
396 .num_planes = 2,
397 },
398 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300399 DRM_FORMAT(NV42),
Daniel Stone903721a2017-04-04 17:54:20 +0100400 SAMPLER_TYPE(EGL_TEXTURE_Y_UV_WL),
401 .num_planes = 2,
402 .chroma_order = ORDER_VU,
403 },
404 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300405 DRM_FORMAT(YUV410),
Daniel Stone903721a2017-04-04 17:54:20 +0100406 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
407 .num_planes = 3,
408 .hsub = 4,
409 .vsub = 4,
410 },
411 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300412 DRM_FORMAT(YVU410),
Daniel Stone903721a2017-04-04 17:54:20 +0100413 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
414 .num_planes = 3,
415 .chroma_order = ORDER_VU,
416 .hsub = 4,
417 .vsub = 4,
418 },
419 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300420 DRM_FORMAT(YUV411),
Daniel Stone903721a2017-04-04 17:54:20 +0100421 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
422 .num_planes = 3,
423 .hsub = 4,
424 .vsub = 1,
425 },
426 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300427 DRM_FORMAT(YVU411),
Daniel Stone903721a2017-04-04 17:54:20 +0100428 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
429 .num_planes = 3,
430 .chroma_order = ORDER_VU,
431 .hsub = 4,
432 .vsub = 1,
433 },
434 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300435 DRM_FORMAT(YUV420),
Daniel Stone903721a2017-04-04 17:54:20 +0100436 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
437 .num_planes = 3,
438 .hsub = 2,
439 .vsub = 2,
440 },
441 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300442 DRM_FORMAT(YVU420),
Daniel Stone903721a2017-04-04 17:54:20 +0100443 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
444 .num_planes = 3,
445 .chroma_order = ORDER_VU,
446 .hsub = 2,
447 .vsub = 2,
448 },
449 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300450 DRM_FORMAT(YUV422),
Daniel Stone903721a2017-04-04 17:54:20 +0100451 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
452 .num_planes = 3,
453 .hsub = 2,
454 .vsub = 1,
455 },
456 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300457 DRM_FORMAT(YVU422),
Daniel Stone903721a2017-04-04 17:54:20 +0100458 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
459 .num_planes = 3,
460 .chroma_order = ORDER_VU,
461 .hsub = 2,
462 .vsub = 1,
463 },
464 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300465 DRM_FORMAT(YUV444),
Daniel Stone903721a2017-04-04 17:54:20 +0100466 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
467 .num_planes = 3,
468 },
469 {
Pekka Paalanene7c91b62018-09-26 14:00:34 +0300470 DRM_FORMAT(YVU444),
Daniel Stone903721a2017-04-04 17:54:20 +0100471 SAMPLER_TYPE(EGL_TEXTURE_Y_U_V_WL),
472 .num_planes = 3,
473 .chroma_order = ORDER_VU,
474 },
475};
476
477WL_EXPORT const struct pixel_format_info *
Marius Vlada9a63042018-11-20 17:04:57 +0200478pixel_format_get_info_shm(uint32_t format)
479{
480 if (format == WL_SHM_FORMAT_XRGB8888)
481 return pixel_format_get_info(DRM_FORMAT_XRGB8888);
482 else if (format == WL_SHM_FORMAT_ARGB8888)
483 return pixel_format_get_info(DRM_FORMAT_ARGB8888);
484 else
485 return pixel_format_get_info(format);
486}
487
488WL_EXPORT const struct pixel_format_info *
Daniel Stone903721a2017-04-04 17:54:20 +0100489pixel_format_get_info(uint32_t format)
490{
491 unsigned int i;
492
493 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
494 if (pixel_format_table[i].format == format)
495 return &pixel_format_table[i];
496 }
497
498 return NULL;
499}
500
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300501WL_EXPORT const struct pixel_format_info *
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400502pixel_format_get_info_by_index(unsigned int index)
503{
504 if (index >= ARRAY_LENGTH(pixel_format_table))
505 return NULL;
506
507 return &pixel_format_table[index];
508}
509
510WL_EXPORT unsigned int
511pixel_format_get_info_count(void)
512{
513 return ARRAY_LENGTH(pixel_format_table);
514}
515
516
517WL_EXPORT const struct pixel_format_info *
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300518pixel_format_get_info_by_drm_name(const char *drm_format_name)
519{
520 const struct pixel_format_info *info;
521 unsigned int i;
522
523 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
524 info = &pixel_format_table[i];
525 if (strcasecmp(info->drm_format_name, drm_format_name) == 0)
526 return info;
527 }
528
529 return NULL;
530}
531
Daniel Stone903721a2017-04-04 17:54:20 +0100532WL_EXPORT unsigned int
533pixel_format_get_plane_count(const struct pixel_format_info *info)
534{
535 return info->num_planes ? info->num_planes : 1;
536}
537
538WL_EXPORT bool
539pixel_format_is_opaque(const struct pixel_format_info *info)
540{
541 return !info->opaque_substitute;
542}
543
Daniel Stone903721a2017-04-04 17:54:20 +0100544WL_EXPORT const struct pixel_format_info *
545pixel_format_get_opaque_substitute(const struct pixel_format_info *info)
546{
547 if (!info->opaque_substitute)
548 return info;
549 else
550 return pixel_format_get_info(info->opaque_substitute);
551}
552
Pekka Paalanen8ba775d2019-09-13 14:44:24 +0300553WL_EXPORT const struct pixel_format_info *
554pixel_format_get_info_by_opaque_substitute(uint32_t format)
555{
556 unsigned int i;
557
558 for (i = 0; i < ARRAY_LENGTH(pixel_format_table); i++) {
559 if (pixel_format_table[i].opaque_substitute == format)
560 return &pixel_format_table[i];
561 }
562
563 return NULL;
564}
565
Daniel Stone903721a2017-04-04 17:54:20 +0100566WL_EXPORT unsigned int
567pixel_format_width_for_plane(const struct pixel_format_info *info,
568 unsigned int plane,
569 unsigned int width)
570{
571 /* We don't support any formats where the first plane is subsampled. */
572 if (plane == 0 || !info->hsub)
573 return width;
574
575 return width / info->hsub;
576}
577
578WL_EXPORT unsigned int
579pixel_format_height_for_plane(const struct pixel_format_info *info,
580 unsigned int plane,
581 unsigned int height)
582{
583 /* We don't support any formats where the first plane is subsampled. */
584 if (plane == 0 || !info->vsub)
585 return height;
586
587 return height / info->vsub;
588}
Marius Vlad6f6fd262021-07-12 12:58:34 +0300589
590#ifdef HAVE_HUMAN_FORMAT_MODIFIER
591WL_EXPORT char *
592pixel_format_get_modifier(uint64_t modifier)
593{
594 char *modifier_name;
595 char *vendor_name;
596 char *mod_str;
597
598 modifier_name = drmGetFormatModifierName(modifier);
599 vendor_name = drmGetFormatModifierVendor(modifier);
600
601 if (!modifier_name) {
602 if (vendor_name)
603 str_printf(&mod_str, "%s_%s (0x%llx)",
604 vendor_name, "UNKNOWN_MODIFIER",
605 (unsigned long long) modifier);
606 else
607 str_printf(&mod_str, "0x%llx",
608 (unsigned long long) modifier);
609
610 free(vendor_name);
611 return mod_str;
612 }
613
614 if (modifier == DRM_FORMAT_MOD_LINEAR) {
615 str_printf(&mod_str, "%s (0x%llx)", modifier_name,
616 (unsigned long long) modifier);
617 free(modifier_name);
618 free(vendor_name);
619 return mod_str;
620 }
621
622 str_printf(&mod_str, "%s_%s (0x%llx)", vendor_name, modifier_name,
623 (unsigned long long) modifier);
624
625 free(modifier_name);
626 free(vendor_name);
627
628 return mod_str;
629}
630#else
631WL_EXPORT char *
632pixel_format_get_modifier(uint64_t modifier)
633{
634 char *mod_str;
635 str_printf(&mod_str, "0x%llx", (unsigned long long) modifier);
636 return mod_str;
637}
638#endif