cogl: Map CoglPixelFormats to their specific properties

By providing an (internal) table to map `CoglPixelFormat`s to their
respective properties  we will be able to get rid of the unusual enum
values in the future. This is something we will need once we want to
have support for more pixel formats (such as YUV-based formats).

As an extra feature, we provide a `to_string()` method, which is quite
useful for debugging purposes (rather than deciphering enum values).

https://gitlab.gnome.org/GNOME/mutter/merge_requests/524
This commit is contained in:
Niels De Graef 2019-04-04 12:33:43 +02:00
parent 69cebc2a70
commit d3ed857ebc
2 changed files with 244 additions and 12 deletions

View File

@ -36,6 +36,204 @@
#include "cogl-pixel-format.h" #include "cogl-pixel-format.h"
/* An entry to map CoglPixelFormats to their respective properties */
typedef struct _CoglPixelFormatInfo
{
CoglPixelFormat cogl_format;
const char *format_str;
int bpp; /* Bytes per pixel */
int aligned; /* Aligned components? (-1 if n/a) */
} CoglPixelFormatInfo;
static const CoglPixelFormatInfo format_info_table[] = {
{
.cogl_format = COGL_PIXEL_FORMAT_ANY,
.format_str = "ANY",
.bpp = 0,
.aligned = -1
},
{
.cogl_format = COGL_PIXEL_FORMAT_A_8,
.format_str = "A_8",
.bpp = 1,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_565,
.format_str = "RGB_565",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
.format_str = "RGBA_4444",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
.format_str = "RGBA_5551",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_YUV,
.format_str = "YUV",
.bpp = 0,
.aligned = -1
},
{
.cogl_format = COGL_PIXEL_FORMAT_G_8,
.format_str = "G_8",
.bpp = 1,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RG_88,
.format_str = "RG_88",
.bpp = 2,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGB_888,
.format_str = "RGB_888",
.bpp = 3,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGR_888,
.format_str = "BGR_888",
.bpp = 3,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
.format_str = "RGBA_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
.format_str = "BGRA_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
.format_str = "ARGB_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
.format_str = "ABGR_8888",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
.format_str = "RGBA_1010102",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
.format_str = "BGRA_1010102",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
.format_str = "ARGB_2101010",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
.format_str = "ABGR_2101010",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
.format_str = "RGBA_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
.format_str = "BGRA_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
.format_str = "ARGB_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
.format_str = "ABGR_8888_PRE",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
.format_str = "RGBA_4444_PRE",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
.format_str = "RGBA_5551_PRE",
.bpp = 2,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
.format_str = "RGBA_1010102_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
.format_str = "BGRA_1010102_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
.format_str = "ARGB_2101010_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
.format_str = "ABGR_2101010_PRE",
.bpp = 4,
.aligned = 0
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
.format_str = "DEPTH_16",
.bpp = 2,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
.format_str = "DEPTH_32",
.bpp = 4,
.aligned = 1
},
{
.cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8,
.format_str = "DEPTH_24_STENCIL_8",
.bpp = 4,
.aligned = 1
},
};
/* /*
* Returns the number of bytes-per-pixel of a given format. The bpp * Returns the number of bytes-per-pixel of a given format. The bpp
* can be extracted from the least significant nibble of the pixel * can be extracted from the least significant nibble of the pixel
@ -59,12 +257,15 @@
int int
_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
{ {
int bpp_lut[] = { 0, 1, 3, 4, size_t i;
2, 2, 2, 0,
1, 2, 0, 0,
3, 4, 0, 0 };
return bpp_lut [format & 0xf]; for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
return format_info_table[i].bpp;
}
g_assert_not_reached ();
} }
/* Note: this also refers to the mapping defined above for /* Note: this also refers to the mapping defined above for
@ -72,18 +273,38 @@ _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
gboolean gboolean
_cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format)
{ {
int aligned_lut[] = { -1, 1, 1, 1, int aligned = -1;
0, 0, 0, -1, size_t i;
1, 1, -1, -1,
0, 0, -1, -1};
int aligned = aligned_lut[format & 0xf];
g_return_val_if_fail (aligned != -1, FALSE);
/* NB: currently checking whether the format components are aligned /* NB: currently checking whether the format components are aligned
* or not determines whether the format is endian dependent or not. * or not determines whether the format is endian dependent or not.
* In the future though we might consider adding formats with * In the future though we might consider adding formats with
* aligned components that are also endian independant. */ * aligned components that are also endian independant. */
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
{
aligned = format_info_table[i].aligned;
break;
}
}
g_return_val_if_fail (aligned != -1, FALSE);
return aligned; return aligned;
} }
const char *
cogl_pixel_format_to_string (CoglPixelFormat format)
{
size_t i;
for (i = 0; i < G_N_ELEMENTS (format_info_table); i++)
{
if (format_info_table[i].cogl_format == format)
return format_info_table[i].format_str;
}
g_assert_not_reached ();
}

View File

@ -284,6 +284,17 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format);
#define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ #define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \
(((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8)
/**
* cogl_pixel_format_to_string:
* @format: a #CoglPixelFormat
*
* Returns a string representation of @format, useful for debugging purposes.
*
* Returns: (transfer none): A string representation of @format.
*/
const char *
cogl_pixel_format_to_string (CoglPixelFormat format);
G_END_DECLS G_END_DECLS
#endif /* __COGL_PIXEL_FORMAT_H__ */ #endif /* __COGL_PIXEL_FORMAT_H__ */