From 0d7a929b831e34fe730b6eedc4357c6c47c37385 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Thu, 4 Apr 2019 12:33:43 +0200 Subject: [PATCH] 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 --- cogl/cogl/cogl-pixel-format.c | 245 ++++++++++++++++++++++++++++++++-- cogl/cogl/cogl-pixel-format.h | 11 ++ 2 files changed, 244 insertions(+), 12 deletions(-) diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c index 45e3cb774..a8c0857a6 100644 --- a/cogl/cogl/cogl-pixel-format.c +++ b/cogl/cogl/cogl-pixel-format.c @@ -36,6 +36,204 @@ #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 * can be extracted from the least significant nibble of the pixel @@ -59,12 +257,15 @@ int _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) { - int bpp_lut[] = { 0, 1, 3, 4, - 2, 2, 2, 0, - 1, 2, 0, 0, - 3, 4, 0, 0 }; + size_t i; - 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 @@ -72,18 +273,38 @@ _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) gboolean _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) { - int aligned_lut[] = { -1, 1, 1, 1, - 0, 0, 0, -1, - 1, 1, -1, -1, - 0, 0, -1, -1}; - int aligned = aligned_lut[format & 0xf]; - - g_return_val_if_fail (aligned != -1, FALSE); + int aligned = -1; + size_t i; /* NB: currently checking whether the format components are aligned * or not determines whether the format is endian dependent or not. * In the future though we might consider adding formats with * 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; } + +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 (); +} diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h index 09b5feff0..c2659fee0 100644 --- a/cogl/cogl/cogl-pixel-format.h +++ b/cogl/cogl/cogl-pixel-format.h @@ -284,6 +284,17 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); #define COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT(format) \ (((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 #endif /* __COGL_PIXEL_FORMAT_H__ */