weston/libweston/pixel-formats.h
Daniel Stone 903721a621 libweston: Add pixel-format helpers
Rather than duplicating knowledge of pixel formats across several
components, create a custom central repository.

Signed-off-by: Daniel Stone <daniels@collabora.com>
[Pekka: fix include paths and two copy-pastas]
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
2017-04-07 12:28:36 +03:00

195 lines
7.2 KiB
C

/*
* 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);