You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					195 lines
				
				7.2 KiB
			
		
		
			
		
	
	
					195 lines
				
				7.2 KiB
			| 
								 
											9 years ago
										 
									 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright © 2016 Collabora, Ltd.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is hereby granted, free of charge, to any person obtaining a
							 | 
						||
| 
								 | 
							
								 * copy of this software and associated documentation files (the "Software"),
							 | 
						||
| 
								 | 
							
								 * to deal in the Software without restriction, including without limitation
							 | 
						||
| 
								 | 
							
								 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
							 | 
						||
| 
								 | 
							
								 * and/or sell copies of the Software, and to permit persons to whom the
							 | 
						||
| 
								 | 
							
								 * Software is furnished to do so, subject to the following conditions:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The above copyright notice and this permission notice (including the next
							 | 
						||
| 
								 | 
							
								 * paragraph) shall be included in all copies or substantial portions of the
							 | 
						||
| 
								 | 
							
								 * Software.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						||
| 
								 | 
							
								 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						||
| 
								 | 
							
								 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
							 | 
						||
| 
								 | 
							
								 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						||
| 
								 | 
							
								 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
							 | 
						||
| 
								 | 
							
								 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
							 | 
						||
| 
								 | 
							
								 * DEALINGS IN THE SOFTWARE.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Author: Daniel Stone <daniels@collabora.com>
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <inttypes.h>
							 | 
						||
| 
								 | 
							
								#include <stdbool.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Contains information about pixel formats, mapping format codes from
							 | 
						||
| 
								 | 
							
								 * wl_shm and drm_fourcc.h (which are deliberately identical, but for the
							 | 
						||
| 
								 | 
							
								 * special cases of WL_SHM_ARGB8888 and WL_SHM_XRGB8888) into various
							 | 
						||
| 
								 | 
							
								 * sets of information. Helper functions are provided for dealing with these
							 | 
						||
| 
								 | 
							
								 * raw structures.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								struct pixel_format_info {
							 | 
						||
| 
								 | 
							
									/** DRM/wl_shm format code */
							 | 
						||
| 
								 | 
							
									uint32_t format;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** If non-zero, number of planes in base (non-modified) format. */
							 | 
						||
| 
								 | 
							
									int num_planes;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** If format contains alpha channel, opaque equivalent of format,
							 | 
						||
| 
								 | 
							
									 *  i.e. alpha channel replaced with X. */
							 | 
						||
| 
								 | 
							
									uint32_t opaque_substitute;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** How the format should be sampled, expressed in terms of tokens
							 | 
						||
| 
								 | 
							
									 *  from the EGL_WL_bind_wayland_display extension. If not set,
							 | 
						||
| 
								 | 
							
									 *  assumed to be either RGB or RGBA, depending on whether or not
							 | 
						||
| 
								 | 
							
									 *  the format contains an alpha channel. The samplers may still
							 | 
						||
| 
								 | 
							
									 *  return alpha even for opaque formats; users must manually set
							 | 
						||
| 
								 | 
							
									 *  the alpha channel to 1.0 (or ignore it) if the format is
							 | 
						||
| 
								 | 
							
									 *  opaque. */
							 | 
						||
| 
								 | 
							
									uint32_t sampler_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** GL format, if data can be natively/directly uploaded. Note that
							 | 
						||
| 
								 | 
							
									 *  whilst DRM formats are little-endian unless explicitly specified,
							 | 
						||
| 
								 | 
							
									 *  (i.e. DRM_FORMAT_ARGB8888 is stored BGRA as sequential bytes in
							 | 
						||
| 
								 | 
							
									 *  memory), GL uses the sequential byte order, so that format maps to
							 | 
						||
| 
								 | 
							
									 *  GL_BGRA_EXT plus GL_UNSIGNED_BYTE. To add to the confusion, the
							 | 
						||
| 
								 | 
							
									 *  explicitly-sized types (e.g. GL_UNSIGNED_SHORT_5_5_5_1) read in
							 | 
						||
| 
								 | 
							
									 *  machine-endian order, so for these types, the correspondence
							 | 
						||
| 
								 | 
							
									 *  depends on endianness. */
							 | 
						||
| 
								 | 
							
									int gl_format;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** GL data type, if data can be natively/directly uploaded. */
							 | 
						||
| 
								 | 
							
									int gl_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** If set, this format can be used with the legacy drmModeAddFB()
							 | 
						||
| 
								 | 
							
									 *  function (not AddFB2), using this and the bpp member. */
							 | 
						||
| 
								 | 
							
									int depth;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** See 'depth' member above. */
							 | 
						||
| 
								 | 
							
									int bpp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** Horizontal subsampling; if non-zero, divide the width by this
							 | 
						||
| 
								 | 
							
									 *  member to obtain the number of columns in the source buffer for
							 | 
						||
| 
								 | 
							
									 *  secondary planes only. Stride is not affected by horizontal
							 | 
						||
| 
								 | 
							
									 *  subsampling. */
							 | 
						||
| 
								 | 
							
									int hsub;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** Vertical subsampling; if non-zero, divide the height by this
							 | 
						||
| 
								 | 
							
									 *  member to obtain the number of rows in the source buffer for
							 | 
						||
| 
								 | 
							
									 *  secondary planes only. */
							 | 
						||
| 
								 | 
							
									int vsub;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* Ordering of chroma components. */
							 | 
						||
| 
								 | 
							
									enum {
							 | 
						||
| 
								 | 
							
										ORDER_UV = 0,
							 | 
						||
| 
								 | 
							
										ORDER_VU,
							 | 
						||
| 
								 | 
							
									} chroma_order;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/* If packed YUV (num_planes == 1), ordering of luma/chroma
							 | 
						||
| 
								 | 
							
									 * components. */
							 | 
						||
| 
								 | 
							
									enum {
							 | 
						||
| 
								 | 
							
										ORDER_LUMA_CHROMA = 0,
							 | 
						||
| 
								 | 
							
										ORDER_CHROMA_LUMA,
							 | 
						||
| 
								 | 
							
									} luma_chroma_order;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Get pixel format information for a DRM format code
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Given a DRM format code, return a pixel format info structure describing
							 | 
						||
| 
								 | 
							
								 * the properties of that format.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format DRM format code to get info for
							 | 
						||
| 
								 | 
							
								 * @returns A pixel format structure (must not be freed), or NULL if the
							 | 
						||
| 
								 | 
							
								 *          format could not be found
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const struct pixel_format_info *pixel_format_get_info(uint32_t format);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Get number of planes used by a pixel format
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Given a pixel format info structure, return the number of planes
							 | 
						||
| 
								 | 
							
								 * required for a buffer. Note that this is not necessarily identical to
							 | 
						||
| 
								 | 
							
								 * the number of samplers required to be bound, as two views into a single
							 | 
						||
| 
								 | 
							
								 * plane are sometimes required.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format Pixel format info structure
							 | 
						||
| 
								 | 
							
								 * @returns Number of planes required for the format
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								unsigned int
							 | 
						||
| 
								 | 
							
								pixel_format_get_plane_count(const struct pixel_format_info *format);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Determine if a pixel format is opaque or contains alpha
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Returns whether or not the pixel format is opaque, or contains a
							 | 
						||
| 
								 | 
							
								 * significant alpha channel. Note that the suggested EGL sampler type may
							 | 
						||
| 
								 | 
							
								 * still sample undefined data into the alpha channel; users must consider
							 | 
						||
| 
								 | 
							
								 * alpha as 1.0 if the format is opaque, and not rely on the sampler to
							 | 
						||
| 
								 | 
							
								 * return this when sampling from the alpha channel.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format Pixel format info structure
							 | 
						||
| 
								 | 
							
								 * @returns True if the format is opaque, or false if it has significant alpha
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								bool pixel_format_is_opaque(const struct pixel_format_info *format);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Get compatible opaque equivalent for a format
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Given a pixel format info structure, return a format which is wholly
							 | 
						||
| 
								 | 
							
								 * compatible with the input format, but opaque, ignoring the alpha channel.
							 | 
						||
| 
								 | 
							
								 * If an alpha format is provided, but the content is known to all be opaque,
							 | 
						||
| 
								 | 
							
								 * then this can be used as a substitute to avoid blending.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * If the input format is opaque, this function will return the input format.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format Pixel format info structure
							 | 
						||
| 
								 | 
							
								 * @returns A pixel format info structure for the compatible opaque substitute
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const struct pixel_format_info *
							 | 
						||
| 
								 | 
							
								pixel_format_get_opaque_substitute(const struct pixel_format_info *format);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Return the effective sampling width for a given plane
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * When horizontal subsampling is effective, a sampler bound to a secondary
							 | 
						||
| 
								 | 
							
								 * plane must bind the sampler with a smaller effective width. This function
							 | 
						||
| 
								 | 
							
								 * returns the effective width to use for the sampler, i.e. dividing by hsub.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * If horizontal subsampling is not in effect, this will be equal to the
							 | 
						||
| 
								 | 
							
								 * width.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format Pixel format info structure
							 | 
						||
| 
								 | 
							
								 * @param plane Zero-indexed plane number
							 | 
						||
| 
								 | 
							
								 * @param width Width of the buffer
							 | 
						||
| 
								 | 
							
								 * @returns Effective width for sampling
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								unsigned int
							 | 
						||
| 
								 | 
							
								pixel_format_width_for_plane(const struct pixel_format_info *format,
							 | 
						||
| 
								 | 
							
											     unsigned int plane,
							 | 
						||
| 
								 | 
							
											     unsigned int width);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Return the effective sampling height for a given plane
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * When vertical subsampling is in effect, a sampler bound to a secondary
							 | 
						||
| 
								 | 
							
								 * plane must bind the sampler with a smaller effective height. This function
							 | 
						||
| 
								 | 
							
								 * returns the effective height to use for the sampler, i.e. dividing by vsub.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * If vertical subsampling is not in effect, this will be equal to the height.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @param format Pixel format info structure
							 | 
						||
| 
								 | 
							
								 * @param plane Zero-indexed plane number
							 | 
						||
| 
								 | 
							
								 * @param height Height of the buffer
							 | 
						||
| 
								 | 
							
								 * @returns Effective width for sampling
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								unsigned int
							 | 
						||
| 
								 | 
							
								pixel_format_height_for_plane(const struct pixel_format_info *format,
							 | 
						||
| 
								 | 
							
											      unsigned int plane,
							 | 
						||
| 
								 | 
							
											      unsigned int height);
							 |