blob: 3e1252604e6a21092b7f1a8a60cf5f25607b95f6 [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>
29
30/**
31 * Contains information about pixel formats, mapping format codes from
32 * wl_shm and drm_fourcc.h (which are deliberately identical, but for the
33 * special cases of WL_SHM_ARGB8888 and WL_SHM_XRGB8888) into various
34 * sets of information. Helper functions are provided for dealing with these
35 * raw structures.
36 */
37struct pixel_format_info {
38 /** DRM/wl_shm format code */
39 uint32_t format;
40
Pekka Paalanene7c91b62018-09-26 14:00:34 +030041 /** The DRM format name without the DRM_FORMAT_ prefix. */
42 const char *drm_format_name;
43
Daniel Stone903721a2017-04-04 17:54:20 +010044 /** If non-zero, number of planes in base (non-modified) format. */
45 int num_planes;
46
47 /** If format contains alpha channel, opaque equivalent of format,
48 * i.e. alpha channel replaced with X. */
49 uint32_t opaque_substitute;
50
51 /** How the format should be sampled, expressed in terms of tokens
52 * from the EGL_WL_bind_wayland_display extension. If not set,
53 * assumed to be either RGB or RGBA, depending on whether or not
54 * the format contains an alpha channel. The samplers may still
55 * return alpha even for opaque formats; users must manually set
56 * the alpha channel to 1.0 (or ignore it) if the format is
57 * opaque. */
58 uint32_t sampler_type;
59
60 /** GL format, if data can be natively/directly uploaded. Note that
61 * whilst DRM formats are little-endian unless explicitly specified,
62 * (i.e. DRM_FORMAT_ARGB8888 is stored BGRA as sequential bytes in
63 * memory), GL uses the sequential byte order, so that format maps to
64 * GL_BGRA_EXT plus GL_UNSIGNED_BYTE. To add to the confusion, the
65 * explicitly-sized types (e.g. GL_UNSIGNED_SHORT_5_5_5_1) read in
66 * machine-endian order, so for these types, the correspondence
67 * depends on endianness. */
68 int gl_format;
69
70 /** GL data type, if data can be natively/directly uploaded. */
71 int gl_type;
72
73 /** If set, this format can be used with the legacy drmModeAddFB()
74 * function (not AddFB2), using this and the bpp member. */
75 int depth;
76
77 /** See 'depth' member above. */
78 int bpp;
79
80 /** Horizontal subsampling; if non-zero, divide the width by this
81 * member to obtain the number of columns in the source buffer for
82 * secondary planes only. Stride is not affected by horizontal
83 * subsampling. */
84 int hsub;
85
86 /** Vertical subsampling; if non-zero, divide the height by this
87 * member to obtain the number of rows in the source buffer for
88 * secondary planes only. */
89 int vsub;
90
91 /* Ordering of chroma components. */
92 enum {
93 ORDER_UV = 0,
94 ORDER_VU,
95 } chroma_order;
96
97 /* If packed YUV (num_planes == 1), ordering of luma/chroma
98 * components. */
99 enum {
100 ORDER_LUMA_CHROMA = 0,
101 ORDER_CHROMA_LUMA,
102 } luma_chroma_order;
Pekka Paalanenabd3f3c2019-09-27 14:33:46 +0300103
104 /** How many significant bits each channel has, or zero if N/A. */
105 struct {
106 int r;
107 int g;
108 int b;
109 int a;
110 } bits;
111
112 /** How channel bits are interpreted, fixed (uint) or floating-point */
113 enum {
114 PIXEL_COMPONENT_TYPE_FIXED = 0,
115 PIXEL_COMPONENT_TYPE_FLOAT,
116 } component_type;
Daniel Stone903721a2017-04-04 17:54:20 +0100117};
118
119/**
120 * Get pixel format information for a DRM format code
121 *
122 * Given a DRM format code, return a pixel format info structure describing
123 * the properties of that format.
124 *
125 * @param format DRM format code to get info for
126 * @returns A pixel format structure (must not be freed), or NULL if the
127 * format could not be found
128 */
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300129const struct pixel_format_info *
130pixel_format_get_info(uint32_t format);
131
132/**
Marius Vlada9a63042018-11-20 17:04:57 +0200133 * Get pixel format information for a SHM format code
134 *
135 * Given a SHM format code, return a DRM pixel format info structure describing
136 * the properties of that format.
137 *
138 * @param format SHM format code to get info for.
139 * @returns A pixel format structure (must not be freed), or NULL if the
140 * format could not be found.
141 */
142const struct pixel_format_info *
143pixel_format_get_info_shm(uint32_t format);
144
145/**
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300146 * Get pixel format information for a named DRM format
147 *
148 * Given a DRM format name, return a pixel format info structure describing
149 * the properties of that format.
150 *
151 * The DRM format name is the preprocessor token name from drm_fourcc.h
152 * without the DRM_FORMAT_ prefix. The search is also case-insensitive.
153 * Both "xrgb8888" and "XRGB8888" searches will find DRM_FORMAT_XRGB8888
154 * for example.
155 *
156 * @param drm_format_name DRM format name to get info for (not NULL)
157 * @returns A pixel format structure (must not be freed), or NULL if the
158 * name could not be found
159 */
160const struct pixel_format_info *
161pixel_format_get_info_by_drm_name(const char *drm_format_name);
Daniel Stone903721a2017-04-04 17:54:20 +0100162
163/**
164 * Get number of planes used by a pixel format
165 *
166 * Given a pixel format info structure, return the number of planes
167 * required for a buffer. Note that this is not necessarily identical to
168 * the number of samplers required to be bound, as two views into a single
169 * plane are sometimes required.
170 *
171 * @param format Pixel format info structure
172 * @returns Number of planes required for the format
173 */
174unsigned int
175pixel_format_get_plane_count(const struct pixel_format_info *format);
176
177/**
178 * Determine if a pixel format is opaque or contains alpha
179 *
180 * Returns whether or not the pixel format is opaque, or contains a
181 * significant alpha channel. Note that the suggested EGL sampler type may
182 * still sample undefined data into the alpha channel; users must consider
183 * alpha as 1.0 if the format is opaque, and not rely on the sampler to
184 * return this when sampling from the alpha channel.
185 *
186 * @param format Pixel format info structure
187 * @returns True if the format is opaque, or false if it has significant alpha
188 */
Pekka Paalanenf5ed7432018-09-26 14:26:53 +0300189bool
190pixel_format_is_opaque(const struct pixel_format_info *format);
Daniel Stone903721a2017-04-04 17:54:20 +0100191
192/**
193 * Get compatible opaque equivalent for a format
194 *
195 * Given a pixel format info structure, return a format which is wholly
196 * compatible with the input format, but opaque, ignoring the alpha channel.
197 * If an alpha format is provided, but the content is known to all be opaque,
198 * then this can be used as a substitute to avoid blending.
199 *
200 * If the input format is opaque, this function will return the input format.
201 *
202 * @param format Pixel format info structure
203 * @returns A pixel format info structure for the compatible opaque substitute
204 */
205const struct pixel_format_info *
206pixel_format_get_opaque_substitute(const struct pixel_format_info *format);
207
208/**
Pekka Paalanen8ba775d2019-09-13 14:44:24 +0300209 * For an opaque format, get the equivalent format with alpha instead of an
210 * ignored channel
211 *
212 * This is the opposite lookup from pixel_format_get_opaque_substitute().
213 * Finds the format whose opaque substitute is the given format.
214 *
215 * If the input format is not opaque or does not have ignored (X) bits, then
216 * the search cannot find a match.
217 *
218 * @param format DRM format code to search for
219 * @returns A pixel format info structure for the pixel format whose opaque
220 * substitute is the argument, or NULL if no match.
221 */
222const struct pixel_format_info *
223pixel_format_get_info_by_opaque_substitute(uint32_t format);
224
225/**
Daniel Stone903721a2017-04-04 17:54:20 +0100226 * Return the effective sampling width for a given plane
227 *
228 * When horizontal subsampling is effective, a sampler bound to a secondary
229 * plane must bind the sampler with a smaller effective width. This function
230 * returns the effective width to use for the sampler, i.e. dividing by hsub.
231 *
232 * If horizontal subsampling is not in effect, this will be equal to the
233 * width.
234 *
235 * @param format Pixel format info structure
236 * @param plane Zero-indexed plane number
237 * @param width Width of the buffer
238 * @returns Effective width for sampling
239 */
240unsigned int
241pixel_format_width_for_plane(const struct pixel_format_info *format,
242 unsigned int plane,
243 unsigned int width);
244
245/**
246 * Return the effective sampling height for a given plane
247 *
248 * When vertical subsampling is in effect, a sampler bound to a secondary
249 * plane must bind the sampler with a smaller effective height. This function
250 * returns the effective height to use for the sampler, i.e. dividing by vsub.
251 *
252 * If vertical subsampling is not in effect, this will be equal to the height.
253 *
254 * @param format Pixel format info structure
255 * @param plane Zero-indexed plane number
256 * @param height Height of the buffer
257 * @returns Effective width for sampling
258 */
259unsigned int
260pixel_format_height_for_plane(const struct pixel_format_info *format,
261 unsigned int plane,
262 unsigned int height);