• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016, 2019 Collabora, Ltd.
3  * Copyright (c) 2018 DisplayLink (UK) Ltd.
4  *
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  */
37 struct pixel_format_info {
38 	/** DRM/wl_shm format code */
39 	uint32_t format;
40 
41 	/** The DRM format name without the DRM_FORMAT_ prefix. */
42 	const char *drm_format_name;
43 
44 	/** 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;
103 
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;
117 };
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  */
129 const struct pixel_format_info *
130 pixel_format_get_info(uint32_t format);
131 
132 /**
133  * 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  */
142 const struct pixel_format_info *
143 pixel_format_get_info_shm(uint32_t format);
144 
145 /**
146  * 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  */
160 const struct pixel_format_info *
161 pixel_format_get_info_by_drm_name(const char *drm_format_name);
162 
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  */
174 unsigned int
175 pixel_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  */
189 bool
190 pixel_format_is_opaque(const struct pixel_format_info *format);
191 
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  */
205 const struct pixel_format_info *
206 pixel_format_get_opaque_substitute(const struct pixel_format_info *format);
207 
208 /**
209  * 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  */
222 const struct pixel_format_info *
223 pixel_format_get_info_by_opaque_substitute(uint32_t format);
224 
225 /**
226  * 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  */
240 unsigned int
241 pixel_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  */
259 unsigned int
260 pixel_format_height_for_plane(const struct pixel_format_info *format,
261 			      unsigned int plane,
262 			      unsigned int height);
263