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