blob: 0b1a5f58b0196fb996984c885ed29b23cf6c715b [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 <inttypes.h>
28#include <stdbool.h>
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -040029#include <pixman.h>
Daniel Stone903721a2017-04-04 17:54:20 +010030
31/**
32 * Contains information about pixel formats, mapping format codes from
33 * wl_shm and drm_fourcc.h (which are deliberately identical, but for the
34 * special cases of WL_SHM_ARGB8888 and WL_SHM_XRGB8888) into various
35 * sets of information. Helper functions are provided for dealing with these
36 * raw structures.
37 */
38struct pixel_format_info {
39 /** DRM/wl_shm format code */
40 uint32_t format;
41
Pekka Paalanene7c91b62018-09-26 14:00:34 +030042 /** The DRM format name without the DRM_FORMAT_ prefix. */
43 const char *drm_format_name;
44
Daniel Stone903721a2017-04-04 17:54:20 +010045 /** If non-zero, number of planes in base (non-modified) format. */
46 int num_planes;
47
48 /** If format contains alpha channel, opaque equivalent of format,
49 * i.e. alpha channel replaced with X. */
50 uint32_t opaque_substitute;
51
52 /** How the format should be sampled, expressed in terms of tokens
53 * from the EGL_WL_bind_wayland_display extension. If not set,
54 * assumed to be either RGB or RGBA, depending on whether or not
55 * the format contains an alpha channel. The samplers may still
56 * return alpha even for opaque formats; users must manually set
57 * the alpha channel to 1.0 (or ignore it) if the format is
58 * opaque. */
59 uint32_t sampler_type;
60
61 /** GL format, if data can be natively/directly uploaded. Note that
62 * whilst DRM formats are little-endian unless explicitly specified,
63 * (i.e. DRM_FORMAT_ARGB8888 is stored BGRA as sequential bytes in
64 * memory), GL uses the sequential byte order, so that format maps to
65 * GL_BGRA_EXT plus GL_UNSIGNED_BYTE. To add to the confusion, the
66 * explicitly-sized types (e.g. GL_UNSIGNED_SHORT_5_5_5_1) read in
67 * machine-endian order, so for these types, the correspondence
68 * depends on endianness. */
69 int gl_format;
70
71 /** GL data type, if data can be natively/directly uploaded. */
72 int gl_type;
73
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -040074 /** Pixman data type, if it agrees exactly with the wl_shm format */
75 pixman_format_code_t pixman_format;
76
Daniel Stone903721a2017-04-04 17:54:20 +010077 /** If set, this format can be used with the legacy drmModeAddFB()
78 * function (not AddFB2), using this and the bpp member. */
79 int depth;
80
81 /** See 'depth' member above. */
82 int bpp;
83
84 /** Horizontal subsampling; if non-zero, divide the width by this
85 * member to obtain the number of columns in the source buffer for
86 * secondary planes only. Stride is not affected by horizontal
87 * subsampling. */
88 int hsub;
89
90 /** Vertical subsampling; if non-zero, divide the height by this
91 * member to obtain the number of rows in the source buffer for
92 * secondary planes only. */
93 int vsub;
94
95 /* Ordering of chroma components. */
96 enum {
97 ORDER_UV = 0,
98 ORDER_VU,
99 } chroma_order;
100
101 /* If packed YUV (num_planes == 1), ordering of luma/chroma
102 * components. */
103 enum {
104 ORDER_LUMA_CHROMA = 0,
105 ORDER_CHROMA_LUMA,
106 } luma_chroma_order;
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300107
108 /** How many significant bits each channel has, or zero if N/A. */
109 struct {
110 int r;
111 int g;
112 int b;
113 int a;
114 } bits;
115
116 /** How channel bits are interpreted, fixed (uint) or floating-point */
117 enum {
118 PIXEL_COMPONENT_TYPE_FIXED = 0,
119 PIXEL_COMPONENT_TYPE_FLOAT,
120 } component_type;
Daniel Stone903721a2017-04-04 17:54:20 +0100121};
122
123/**
124 * Get pixel format information for a DRM format code
125 *
126 * Given a DRM format code, return a pixel format info structure describing
127 * the properties of that format.
128 *
129 * @param format DRM format code to get info for
130 * @returns A pixel format structure (must not be freed), or NULL if the
131 * format could not be found
132 */
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300133const struct pixel_format_info *
134pixel_format_get_info(uint32_t format);
135
136/**
Marius Vlada9a63042018-11-20 17:04:57 +0200137 * Get pixel format information for a SHM format code
138 *
139 * Given a SHM format code, return a DRM pixel format info structure describing
140 * the properties of that format.
141 *
142 * @param format SHM format code to get info for.
143 * @returns A pixel format structure (must not be freed), or NULL if the
144 * format could not be found.
145 */
146const struct pixel_format_info *
147pixel_format_get_info_shm(uint32_t format);
148
149/**
Manuel Stoeckl8a7f1e22021-07-26 22:29:20 -0400150 * Get pixel format information by table index
151 *
152 * Given a 0-based index in the format table, return the corresponding
153 * DRM pixel format info structure.
154 *
155 * @param index Index of the pixel format in the table
156 * @returns A pixel format structure (must not be freed), or NULL if the
157 * index is out of range.
158 */
159const struct pixel_format_info *
160pixel_format_get_info_by_index(unsigned int index);
161
162/**
163 * Return the size of the pixel format table
164 *
165 * @returns The number of entries in the pixel format table
166 */
167unsigned int
168pixel_format_get_info_count(void);
169
170/**
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300171 * Get pixel format information for a named DRM format
172 *
173 * Given a DRM format name, return a pixel format info structure describing
174 * the properties of that format.
175 *
176 * The DRM format name is the preprocessor token name from drm_fourcc.h
177 * without the DRM_FORMAT_ prefix. The search is also case-insensitive.
178 * Both "xrgb8888" and "XRGB8888" searches will find DRM_FORMAT_XRGB8888
179 * for example.
180 *
181 * @param drm_format_name DRM format name to get info for (not NULL)
182 * @returns A pixel format structure (must not be freed), or NULL if the
183 * name could not be found
184 */
185const struct pixel_format_info *
186pixel_format_get_info_by_drm_name(const char *drm_format_name);
Daniel Stone903721a2017-04-04 17:54:20 +0100187
188/**
189 * Get number of planes used by a pixel format
190 *
191 * Given a pixel format info structure, return the number of planes
192 * required for a buffer. Note that this is not necessarily identical to
193 * the number of samplers required to be bound, as two views into a single
194 * plane are sometimes required.
195 *
196 * @param format Pixel format info structure
197 * @returns Number of planes required for the format
198 */
199unsigned int
200pixel_format_get_plane_count(const struct pixel_format_info *format);
201
202/**
203 * Determine if a pixel format is opaque or contains alpha
204 *
205 * Returns whether or not the pixel format is opaque, or contains a
206 * significant alpha channel. Note that the suggested EGL sampler type may
207 * still sample undefined data into the alpha channel; users must consider
208 * alpha as 1.0 if the format is opaque, and not rely on the sampler to
209 * return this when sampling from the alpha channel.
210 *
211 * @param format Pixel format info structure
212 * @returns True if the format is opaque, or false if it has significant alpha
213 */
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300214bool
215pixel_format_is_opaque(const struct pixel_format_info *format);
Daniel Stone903721a2017-04-04 17:54:20 +0100216
217/**
218 * Get compatible opaque equivalent for a format
219 *
220 * Given a pixel format info structure, return a format which is wholly
221 * compatible with the input format, but opaque, ignoring the alpha channel.
222 * If an alpha format is provided, but the content is known to all be opaque,
223 * then this can be used as a substitute to avoid blending.
224 *
225 * If the input format is opaque, this function will return the input format.
226 *
227 * @param format Pixel format info structure
228 * @returns A pixel format info structure for the compatible opaque substitute
229 */
230const struct pixel_format_info *
231pixel_format_get_opaque_substitute(const struct pixel_format_info *format);
232
233/**
Pekka Paalanen8ba775d2019-09-13 14:44:24 +0300234 * For an opaque format, get the equivalent format with alpha instead of an
235 * ignored channel
236 *
237 * This is the opposite lookup from pixel_format_get_opaque_substitute().
238 * Finds the format whose opaque substitute is the given format.
239 *
240 * If the input format is not opaque or does not have ignored (X) bits, then
241 * the search cannot find a match.
242 *
243 * @param format DRM format code to search for
244 * @returns A pixel format info structure for the pixel format whose opaque
245 * substitute is the argument, or NULL if no match.
246 */
247const struct pixel_format_info *
248pixel_format_get_info_by_opaque_substitute(uint32_t format);
249
250/**
Daniel Stone903721a2017-04-04 17:54:20 +0100251 * Return the effective sampling width for a given plane
252 *
253 * When horizontal subsampling is effective, a sampler bound to a secondary
254 * plane must bind the sampler with a smaller effective width. This function
255 * returns the effective width to use for the sampler, i.e. dividing by hsub.
256 *
257 * If horizontal subsampling is not in effect, this will be equal to the
258 * width.
259 *
260 * @param format Pixel format info structure
261 * @param plane Zero-indexed plane number
262 * @param width Width of the buffer
263 * @returns Effective width for sampling
264 */
265unsigned int
266pixel_format_width_for_plane(const struct pixel_format_info *format,
267 unsigned int plane,
268 unsigned int width);
269
270/**
271 * Return the effective sampling height for a given plane
272 *
273 * When vertical subsampling is in effect, a sampler bound to a secondary
274 * plane must bind the sampler with a smaller effective height. This function
275 * returns the effective height to use for the sampler, i.e. dividing by vsub.
276 *
277 * If vertical subsampling is not in effect, this will be equal to the height.
278 *
279 * @param format Pixel format info structure
280 * @param plane Zero-indexed plane number
281 * @param height Height of the buffer
282 * @returns Effective width for sampling
283 */
284unsigned int
285pixel_format_height_for_plane(const struct pixel_format_info *format,
286 unsigned int plane,
287 unsigned int height);
Marius Vlad6f6fd262021-07-12 12:58:34 +0300288/**
289 * Return a human-readable format modifier. Comprised from the modifier name,
290 * the vendor name, and the original encoded value in hexadecimal, using
291 * 'VENDOR_NAME_MODIFIER_NAME (modifier_encoded_value)' pattern. In case the
292 * modifier name (and the vendor name) isn't found, this returns the original
293 * encoded value, as a string value.
294 *
295 * @param modifier the modifier in question
296 * @returns a malloc'ed string, caller responsible for freeing after use.
297 */
298char *
299pixel_format_get_modifier(uint64_t modifier);