diff options
author | Niels De Graef <niels.degraef@barco.com> | 2019-06-19 08:41:44 +0200 |
---|---|---|
committer | Niels De Graef <niels.degraef@barco.com> | 2019-06-24 15:14:01 +0200 |
commit | 89111517bd8d2c6a9ead17988cf74abe2ed674b8 (patch) | |
tree | 2d4bf4c514965732ec40e29c308028d9b6a69df0 | |
parent | 990b0efc17ff2477d27003b541f01671f303888a (diff) | |
download | mutter-89111517bd8d2c6a9ead17988cf74abe2ed674b8.tar.gz |
cogl: Add non-RGBA pixel formats
Up until now, we didn't support any YUV pixel formats. This was for
several reasons: first, we draw onto an RGBA framebuffer, so any
YUV-based color format needs to be converted to RGBA using a shader.
Next, some more complex pixel format have extra properties that we have
not had to deal with right now: they can be located on multiple "planes"
(which means components are not combined in a single texture or memory
block). Some pixel formats also have a notion of "subsampling", where
one does not save a component for each and every pixel, but rather for
every other pixel (possibly in both the horizontal and vertical sense).
To deal with this, we introduce a new type as well:
`CoglPixelFormatConversion` provides a wrapper for the necessary shaders
(which in Cogl are represented by `CoglSnippet`s).
26 files changed, 1195 insertions, 132 deletions
diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c index e7f9c2125..5bb6bdfc4 100644 --- a/cogl/cogl/cogl-atlas-texture.c +++ b/cogl/cogl/cogl-atlas-texture.c @@ -937,12 +937,12 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx, CoglBitmap *bmp; CoglAtlasTexture *atlas_tex; - g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, NULL); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL); g_return_val_if_fail (data != NULL, NULL); /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, diff --git a/cogl/cogl/cogl-atlas.c b/cogl/cogl/cogl-atlas.c index 8bcb491bc..6e1cdc65f 100644 --- a/cogl/cogl/cogl-atlas.c +++ b/cogl/cogl/cogl-atlas.c @@ -193,7 +193,7 @@ _cogl_atlas_get_initial_size (CoglPixelFormat format, initial minimum size. If the format is only 1 byte per pixel we can use 1024x1024, otherwise we'll assume it will take 4 bytes per pixel and use 512x512. */ - if (_cogl_pixel_format_get_bytes_per_pixel (format) == 1) + if (cogl_pixel_format_get_bytes_per_pixel_simple (format) == 1) size = 1024; else size = 512; @@ -291,7 +291,9 @@ _cogl_atlas_create_texture (CoglAtlas *atlas, { uint8_t *clear_data; CoglBitmap *clear_bmp; - int bpp = _cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format); + int bpp; + + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (atlas->texture_format); /* Create a buffer of zeroes to initially clear the texture */ clear_data = g_malloc0 (width * height * bpp); diff --git a/cogl/cogl/cogl-bitmap-conversion.c b/cogl/cogl/cogl-bitmap-conversion.c index b3ebf8773..2930119ec 100644 --- a/cogl/cogl/cogl-bitmap-conversion.c +++ b/cogl/cogl/cogl-bitmap-conversion.c @@ -320,7 +320,37 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format) case COGL_PIXEL_FORMAT_DEPTH_32: case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: case COGL_PIXEL_FORMAT_ANY: + /* No support for YUV or multi-plane formats */ case COGL_PIXEL_FORMAT_YUV: + case COGL_PIXEL_FORMAT_YUYV: + case COGL_PIXEL_FORMAT_YVYU: + case COGL_PIXEL_FORMAT_UYVY: + case COGL_PIXEL_FORMAT_VYUY: + case COGL_PIXEL_FORMAT_AYUV: + case COGL_PIXEL_FORMAT_XRGB8888_A8: + case COGL_PIXEL_FORMAT_XBGR8888_A8: + case COGL_PIXEL_FORMAT_RGBX8888_A8: + case COGL_PIXEL_FORMAT_BGRX8888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + case COGL_PIXEL_FORMAT_NV16: + case COGL_PIXEL_FORMAT_NV61: + case COGL_PIXEL_FORMAT_NV24: + case COGL_PIXEL_FORMAT_NV42: + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: g_assert_not_reached (); case COGL_PIXEL_FORMAT_A_8: diff --git a/cogl/cogl/cogl-bitmap-packing.h b/cogl/cogl/cogl-bitmap-packing.h index 3a1646fbf..1c8bbb5fc 100644 --- a/cogl/cogl/cogl-bitmap-packing.h +++ b/cogl/cogl/cogl-bitmap-packing.h @@ -395,7 +395,37 @@ G_PASTE (_cogl_unpack_, component_size) (CoglPixelFormat format, case COGL_PIXEL_FORMAT_DEPTH_32: case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: case COGL_PIXEL_FORMAT_ANY: + /* No support for YUV or multi-plane formats */ case COGL_PIXEL_FORMAT_YUV: + case COGL_PIXEL_FORMAT_YUYV: + case COGL_PIXEL_FORMAT_YVYU: + case COGL_PIXEL_FORMAT_UYVY: + case COGL_PIXEL_FORMAT_VYUY: + case COGL_PIXEL_FORMAT_AYUV: + case COGL_PIXEL_FORMAT_XRGB8888_A8: + case COGL_PIXEL_FORMAT_XBGR8888_A8: + case COGL_PIXEL_FORMAT_RGBX8888_A8: + case COGL_PIXEL_FORMAT_BGRX8888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + case COGL_PIXEL_FORMAT_NV16: + case COGL_PIXEL_FORMAT_NV61: + case COGL_PIXEL_FORMAT_NV24: + case COGL_PIXEL_FORMAT_NV42: + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: g_assert_not_reached (); } } @@ -751,7 +781,37 @@ G_PASTE (_cogl_pack_, component_size) (CoglPixelFormat format, case COGL_PIXEL_FORMAT_DEPTH_32: case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8: case COGL_PIXEL_FORMAT_ANY: + /* No support for YUV or multi-plane formats */ case COGL_PIXEL_FORMAT_YUV: + case COGL_PIXEL_FORMAT_YUYV: + case COGL_PIXEL_FORMAT_YVYU: + case COGL_PIXEL_FORMAT_UYVY: + case COGL_PIXEL_FORMAT_VYUY: + case COGL_PIXEL_FORMAT_AYUV: + case COGL_PIXEL_FORMAT_XRGB8888_A8: + case COGL_PIXEL_FORMAT_XBGR8888_A8: + case COGL_PIXEL_FORMAT_RGBX8888_A8: + case COGL_PIXEL_FORMAT_BGRX8888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + case COGL_PIXEL_FORMAT_NV16: + case COGL_PIXEL_FORMAT_NV61: + case COGL_PIXEL_FORMAT_NV24: + case COGL_PIXEL_FORMAT_NV42: + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: g_assert_not_reached (); } } diff --git a/cogl/cogl/cogl-bitmap.c b/cogl/cogl/cogl-bitmap.c index 5d5dbc30a..a20d268b7 100644 --- a/cogl/cogl/cogl-bitmap.c +++ b/cogl/cogl/cogl-bitmap.c @@ -136,7 +136,7 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src, (dst->format & ~COGL_PREMULT_BIT), FALSE); - bpp = _cogl_pixel_format_get_bytes_per_pixel (src->format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (src->format); if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error))) { @@ -186,7 +186,7 @@ cogl_bitmap_new_for_data (CoglContext *context, /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); bmp = g_slice_new (CoglBitmap); bmp->context = context; @@ -211,7 +211,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context, GError **error) { static CoglUserDataKey bitmap_free_key; - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); int rowstride = ((width * bpp) + 3) & ~3; uint8_t *data = g_try_malloc (rowstride * height); CoglBitmap *bitmap; @@ -308,7 +308,7 @@ cogl_bitmap_new_with_size (CoglContext *context, /* for now we fallback to cogl_pixel_buffer_new, later, we could ask * libdrm a tiled buffer for instance */ - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); pixel_buffer = cogl_pixel_buffer_new (context, diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c index 26a9b2993..638572dc6 100644 --- a/cogl/cogl/cogl-blit.c +++ b/cogl/cogl/cogl-blit.c @@ -273,7 +273,7 @@ static gboolean _cogl_blit_get_tex_data_begin (CoglBlitData *data) { data->format = _cogl_texture_get_format (data->src_tex); - data->bpp = _cogl_pixel_format_get_bytes_per_pixel (data->format); + data->bpp = cogl_pixel_format_get_bytes_per_pixel_simple (data->format); data->image_data = g_malloc (data->bpp * data->src_width * data->src_height); diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c index de9bfb451..b2bfe6636 100644 --- a/cogl/cogl/cogl-framebuffer.c +++ b/cogl/cogl/cogl-framebuffer.c @@ -1315,7 +1315,7 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer, CoglPixelFormat format, uint8_t *pixels) { - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); CoglBitmap *bitmap; gboolean ret; diff --git a/cogl/cogl/cogl-pixel-format-conversion.c b/cogl/cogl/cogl-pixel-format-conversion.c new file mode 100644 index 000000000..107595445 --- /dev/null +++ b/cogl/cogl/cogl-pixel-format-conversion.c @@ -0,0 +1,182 @@ +/* + * Authored By Niels De Graef <niels.degraef@barco.com> + * + * Copyright (C) 2018 Barco NV + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "cogl-config.h" + +#include "cogl-object-private.h" +#include "cogl-gtype-private.h" +#include "cogl-pixel-format-conversion.h" +#include "cogl-snippet.h" +#include "cogl-pipeline-layer-state.h" +#include "cogl-pipeline-state.h" + +#define _COGL_YUV_TO_RGBA(res, y, u, v) \ + "vec4 " res ";\n" \ + res ".r = (" y ") + 1.59765625 * (" v ");\n" \ + res ".g = (" y ") - 0.390625 * (" u ") - 0.8125 * (" v ");\n" \ + res ".b = (" y ") + 2.015625 * (" u ");\n" \ + res ".a = 1.0;\n" + +/* Shader for a single YUV plane */ +static const char yuv_to_rgba_shader[] = + "vec4\n" + "cogl_yuv_to_rgba (vec2 UV)\n" + "{\n" + " vec4 orig_color = texture2D(cogl_sampler0, UV);\n" + " float y = 1.16438356 * (orig_color.r - 0.0625);\n" + " float u = orig_color.g - 0.5;\n" + " float v = orig_color.b - 0.5;\n" + _COGL_YUV_TO_RGBA ("color", "y", "u", "v") + " return color;\n" + "}\n"; + +/* Shader for 1 Y-plane and 1 UV-plane */ +static const char y_uv_to_rgba_shader[] = + "vec4\n" + "cogl_y_uv_to_rgba (vec2 UV)\n" + "{\n" + " float y = 1.1640625 * (texture2D (cogl_sampler0, UV).x - 0.0625);\n" + " vec2 uv = texture2D (cogl_sampler1, UV).rg;\n" + " uv -= 0.5;\n" + " float u = uv.x;\n" + " float v = uv.y;\n" + _COGL_YUV_TO_RGBA ("color", "y", "u", "v") + " return color;\n" + "}\n"; + +/* Shader for 1 Y-plane, 1 U-plane and 1 V-plane */ +static const char y_u_v_to_rgba_shader[] = + "vec4\n" + "cogl_y_u_v_to_rgba (vec2 UV)\n" + "{\n" + " float y = 1.16438356 * (texture2D(cogl_sampler0, UV).x - 0.0625);\n" + " float u = texture2D(cogl_sampler1, UV).x - 0.5;\n" + " float v = texture2D(cogl_sampler2, UV).x - 0.5;\n" + _COGL_YUV_TO_RGBA ("color", "y", "u", "v") + " return color;\n" + "}\n"; + +struct _CoglPixelFormatConversion +{ + CoglObject _parent; + + CoglSnippet *vertex_declaration_snippet; + CoglSnippet *fragment_declaration_snippet; + + CoglSnippet *fragment_execution_snippet; +}; + +static void +_cogl_pixel_format_conversion_free (CoglPixelFormatConversion *self); + +COGL_OBJECT_DEFINE (PixelFormatConversion, pixel_format_conversion); +COGL_GTYPE_DEFINE_CLASS (PixelFormatConversion, pixel_format_conversion); + + +void +cogl_pixel_format_conversion_attach_to_pipeline (CoglPixelFormatConversion *self, + CoglPipeline *pipeline, + gint layer) +{ + cogl_pipeline_add_snippet (pipeline, self->fragment_declaration_snippet); + cogl_pipeline_add_snippet (pipeline, self->vertex_declaration_snippet); + + cogl_pipeline_add_layer_snippet (pipeline, + layer, + self->fragment_execution_snippet); +} + +static gboolean +get_cogl_snippets (CoglPixelFormat format, + CoglSnippet **vertex_snippet_out, + CoglSnippet **fragment_snippet_out, + CoglSnippet **layer_snippet_out) +{ + const char *global_hook; + const char *layer_hook; + + switch (format) + { + case COGL_PIXEL_FORMAT_AYUV: + global_hook = yuv_to_rgba_shader; + layer_hook = "cogl_layer = cogl_yuv_to_rgba(cogl_tex_coord0_in.st);\n"; + break; + case COGL_PIXEL_FORMAT_NV12: + /* XXX are we using Y_UV or Y_xUxV? Maybe check for RG support? */ + global_hook = y_uv_to_rgba_shader; + layer_hook = "cogl_layer = cogl_y_uv_to_rgba(cogl_tex_coord0_in.st);\n"; + break; + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YUV422: + global_hook = y_u_v_to_rgba_shader; + layer_hook = "cogl_layer = cogl_y_u_v_to_rgba(cogl_tex_coord0_in.st);\n"; + break; + default: + *vertex_snippet_out = NULL; + *fragment_snippet_out = NULL; + *layer_snippet_out = NULL; + return FALSE; + } + + *vertex_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS, + global_hook, + NULL); + + *fragment_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS, + global_hook, + NULL); + + *layer_snippet_out = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, + NULL, + layer_hook); + + return TRUE; +} + +static void +_cogl_pixel_format_conversion_free (CoglPixelFormatConversion *self) +{ + cogl_clear_object (&self->vertex_declaration_snippet); + cogl_clear_object (&self->fragment_declaration_snippet); + cogl_clear_object (&self->fragment_execution_snippet); +} + +CoglPixelFormatConversion * +cogl_pixel_format_conversion_new (CoglPixelFormat format) +{ + CoglPixelFormatConversion *self; + CoglSnippet *vertex_declaration_snippet; + CoglSnippet *fragment_declaration_snippet; + CoglSnippet *fragment_execution_snippet; + + if (!get_cogl_snippets (format, + &vertex_declaration_snippet, + &fragment_declaration_snippet, + &fragment_execution_snippet)) + return NULL; + + self = g_slice_new0 (CoglPixelFormatConversion); + _cogl_pixel_format_conversion_object_new (self); + + self->vertex_declaration_snippet = vertex_declaration_snippet; + self->fragment_declaration_snippet = fragment_declaration_snippet; + self->fragment_execution_snippet = fragment_execution_snippet; + + return self; +} diff --git a/cogl/cogl/cogl-pixel-format-conversion.h b/cogl/cogl/cogl-pixel-format-conversion.h new file mode 100644 index 000000000..f93107a33 --- /dev/null +++ b/cogl/cogl/cogl-pixel-format-conversion.h @@ -0,0 +1,92 @@ +/* + * Authored By Niels De Graef <niels.degraef@barco.com> + * + * Copyright (C) 2018 Barco NV + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __COGL_PIXEL_FORMAT_CONVERSION_H__ +#define __COGL_PIXEL_FORMAT_CONVERSION_H__ + +#include "cogl/cogl-types.h" +#include "cogl/cogl-pipeline.h" + +G_BEGIN_DECLS + +/** + * SECTION:cogl-color-space-conversion + * @title: CoglPixelFormatConversion + * @short_description: A collection of snippets to handle pixel_format conversion + * + * In some use cases, one might generate non-RGBA textures (e.g. YUV), which is + * problematic if you then have to composite them in to an RGBA framebuffer. In + * comes #CoglPixelFormatConversion, which you can attach to a #CoglPipeline to + * do this all for you. Internally, it consists of nothing more than a + * collection of #CoglSnippets which do the right thing for you. + */ + +typedef struct _CoglPixelFormatConversion CoglPixelFormatConversion; +#define COGL_PIXEL_FORMAT_CONVERSION(ptr) ((CoglPixelFormatConversion *) ptr) + + +/** + * cogl_multiplane_texture_get_gtype: + * + * Returns: a #GType that can be used with the GLib type system. + */ +GType cogl_pixel_format_conversion_get_gtype (void); + +/* + * cogl_is_pixel_format_conversion: + * @object: A #CoglObject pointer + * + * Gets whether the given @object references an existing + * CoglPixelFormatConversion. + * + * Return value: %TRUE if the @object references a #CoglPixelFormatConversion, + * %FALSE otherwise + */ +gboolean +cogl_is_pixel_format_conversion (void *object); + +/** + * cogl_pixel_format_conversion_new: + * @format: The input format + * + * Creates a #CoglPixelFormatConversion to convert the given @formatro RGBA. If + * no such conversion is needed, it will return %NULL. + * + * Returns: (transfer full) (nullable): A new #CoglPixelFormatConversion, or + * %NULL if none is needed. + */ +CoglPixelFormatConversion * cogl_pixel_format_conversion_new (CoglPixelFormat format); + +/** + * cogl_pixel_format_conversion_attach_to_pipeline: + * @self: The #CoglPixelFormatConversion you want to add + * @pipeline: The #CoglPipeline which needs the color conversion + * @layer: The layer you want to perform the color space conversion at + * + * Adds color conversion to the given @pipeline at the given @layer. + */ +void cogl_pixel_format_conversion_attach_to_pipeline (CoglPixelFormatConversion *self, + CoglPipeline *pipeline, + int layer); + +G_END_DECLS + +#endif diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c index a62388469..0a28f0993 100644 --- a/cogl/cogl/cogl-pixel-format.c +++ b/cogl/cogl/cogl-pixel-format.c @@ -35,241 +35,667 @@ #include <stdlib.h> #include "cogl-pixel-format.h" +#include "cogl-texture.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) */ + int aligned; /* Is aligned? (bool; -1 if n/a) */ + uint8_t n_planes; + + /* Per plane-information */ + uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES]; /* Bytes per pixel */ + uint8_t hsub[COGL_PIXEL_FORMAT_MAX_PLANES]; /* horizontal subsampling */ + uint8_t vsub[COGL_PIXEL_FORMAT_MAX_PLANES]; /* vertical subsampling */ + CoglPixelFormat subformats[COGL_PIXEL_FORMAT_MAX_PLANES]; /* how to upload to GL */ } CoglPixelFormatInfo; static const CoglPixelFormatInfo format_info_table[] = { { .cogl_format = COGL_PIXEL_FORMAT_ANY, .format_str = "ANY", - .bpp = 0, - .aligned = -1 + .n_planes = 0, + .aligned = -1, + .bpp = { 0 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ANY } }, { .cogl_format = COGL_PIXEL_FORMAT_A_8, .format_str = "A_8", - .bpp = 1, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 1 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_A_8 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGB_565, .format_str = "RGB_565", - .bpp = 2, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGB_565 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444, .format_str = "RGBA_4444", - .bpp = 2, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_4444 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551, .format_str = "RGBA_5551", - .bpp = 2, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_5551 } }, { .cogl_format = COGL_PIXEL_FORMAT_YUV, .format_str = "YUV", - .bpp = 0, - .aligned = -1 + .n_planes = 1, + .aligned = -1, + .bpp = { 0 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_YUV } }, { .cogl_format = COGL_PIXEL_FORMAT_R_8, .format_str = "R_8", - .bpp = 1, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 1 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8 } }, { .cogl_format = COGL_PIXEL_FORMAT_RG_88, .format_str = "RG_88", - .bpp = 2, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RG_88 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGB_888, .format_str = "RGB_888", - .bpp = 3, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 3 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGB_888 } }, { .cogl_format = COGL_PIXEL_FORMAT_BGR_888, .format_str = "BGR_888", - .bpp = 3, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 3 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGR_888 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888, .format_str = "RGBA_8888", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_8888 } }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888, .format_str = "BGRA_8888", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGRA_8888 } }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888, .format_str = "ARGB_8888", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 } }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888, .format_str = "ABGR_8888", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ABGR_8888 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102, .format_str = "RGBA_1010102", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_1010102 } }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102, .format_str = "BGRA_1010102", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGRA_1010102 } }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010, .format_str = "ARGB_2101010", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ARGB_2101010 } }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010, .format_str = "ABGR_2101010", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ABGR_2101010 } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE, .format_str = "RGBA_8888_PRE", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_8888_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE, .format_str = "BGRA_8888_PRE", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGRA_8888_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE, .format_str = "ARGB_8888_PRE", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ARGB_8888_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE, .format_str = "ABGR_8888_PRE", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ABGR_8888_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE, .format_str = "RGBA_4444_PRE", - .bpp = 2, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_4444_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE, .format_str = "RGBA_5551_PRE", - .bpp = 2, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_5551_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE, .format_str = "RGBA_1010102_PRE", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_1010102_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE, .format_str = "BGRA_1010102_PRE", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGRA_1010102_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE, .format_str = "ARGB_2101010_PRE", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ARGB_2101010_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE, .format_str = "ABGR_2101010_PRE", - .bpp = 4, - .aligned = 0 + .n_planes = 1, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ABGR_2101010_PRE } }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, .format_str = "DEPTH_16", - .bpp = 2, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 2 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_DEPTH_16 } }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_32, .format_str = "DEPTH_32", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_DEPTH_32 } }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, .format_str = "DEPTH_24_STENCIL_8", - .bpp = 4, - .aligned = 1 + .n_planes = 1, + .aligned = 1, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 } + }, + /* Packed YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_YUYV, + .format_str = "YUYV", + .n_planes = 2, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_YUYV, COGL_PIXEL_FORMAT_YUYV } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVYU, + .format_str = "YVYU", + .n_planes = 2, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_YVYU, COGL_PIXEL_FORMAT_YVYU } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_UYVY, + .format_str = "UYVY", + .n_planes = 2, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_UYVY, COGL_PIXEL_FORMAT_UYVY } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_VYUY, + .format_str = "VYUY", + .n_planes = 2, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_VYUY, COGL_PIXEL_FORMAT_VYUY } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_AYUV, + .format_str = "AYUV", + .n_planes = 2, + .aligned = 0, + .bpp = { 4 }, + .hsub = { 1, 0, 0, 0 }, + .vsub = { 1, 0, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_AYUV, COGL_PIXEL_FORMAT_AYUV } + }, + /* 2 plane RGB + A */ + { + .cogl_format = COGL_PIXEL_FORMAT_XRGB8888_A8, + .format_str = "XRGB8888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 4, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ARGB_8888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_XBGR8888_A8, + .format_str = "XBGR8888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 4, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_ABGR_8888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBX8888_A8, + .format_str = "RGBX8888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 4, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRX8888_A8, + .format_str = "BGRX8888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 4, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGRA_8888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB888_A8, + .format_str = "RGB888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 3, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGR888_A8, + .format_str = "BGR888_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 3, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_BGR_888, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB565_A8, + .format_str = "RGB565_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 2, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGR565_A8, + .format_str = "BGR565_A8", + .n_planes = 2, + .aligned = 0, + .bpp = { 2, 1 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 } + }, + /* 2 plane YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_NV12, + .format_str = "NV12", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 2, 0, 0 }, + .vsub = { 1, 2, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV21, + .format_str = "NV21", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 2, 0, 0 }, + .vsub = { 1, 2, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV16, + .format_str = "NV16", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 2, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV61, + .format_str = "NV61", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 2, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV24, + .format_str = "NV24", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV42, + .format_str = "NV42", + .n_planes = 2, + .aligned = 0, + .bpp = { 1, 2 }, + .hsub = { 1, 1, 0, 0 }, + .vsub = { 1, 1, 0, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_RG_88 } + }, + /* 3 plane YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_YUV410, + .format_str = "YUV410", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 4, 4, 0 }, + .vsub = { 1, 4, 4, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU410, + .format_str = "YVU410", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 4, 4, 0 }, + .vsub = { 1, 4, 4, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV411, + .format_str = "YUV411", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 4, 4, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU411, + .format_str = "YVU411", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 4, 4, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV420, + .format_str = "YUV420", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 2, 2, 0 }, + .vsub = { 1, 2, 2, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU420, + .format_str = "YVU420", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 2, 2, 0 }, + .vsub = { 1, 2, 2, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV422, + .format_str = "YUV422", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 2, 2, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU422, + .format_str = "YVU422", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 2, 2, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV444, + .format_str = "YUV444", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 1, 1, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU444, + .format_str = "YVU444", + .n_planes = 3, + .aligned = 0, + .bpp = { 1, 1, 1 }, + .hsub = { 1, 1, 1, 0 }, + .vsub = { 1, 1, 1, 0 }, + .subformats = { COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8, COGL_PIXEL_FORMAT_R_8 } }, }; -/* - * Returns the number of bytes-per-pixel of a given format. The bpp - * can be extracted from the least significant nibble of the pixel - * format (see CoglPixelFormat). - * - * The mapping is the following (see discussion on bug #660188): - * - * 0 = undefined - * 1, 8 = 1 bpp (e.g. A_8, G_8) - * 2 = 3 bpp, aligned (e.g. 888) - * 3 = 4 bpp, aligned (e.g. 8888) - * 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551) - * 7 = undefined yuv - * 9 = 2 bpp, aligned - * 10 = undefined - * 11 = undefined - * 12 = 3 bpp, not aligned - * 13 = 4 bpp, not aligned (e.g. 2101010) - * 14-15 = undefined - */ -int -_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) +uint8_t +cogl_pixel_format_get_bytes_per_pixel_simple (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].bpp; + { + g_return_val_if_fail (format_info_table[i].n_planes == 1, 0); + return format_info_table[i].bpp[0]; + } + } + + g_assert_not_reached (); +} + +void +cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, uint8_t *bpp_out) +{ + size_t i, j; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format != format) + continue; + + for (j = 0; j < format_info_table[i].n_planes; j++) + bpp_out[j] = format_info_table[i].bpp[j]; + return; } g_assert_not_reached (); } /* Note: this also refers to the mapping defined above for - * _cogl_pixel_format_get_bytes_per_pixel() */ + * cogl_pixel_format_get_bytes_per_pixel() */ gboolean _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) { @@ -295,6 +721,44 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) return aligned; } +uint8_t +cogl_pixel_format_get_n_planes (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].n_planes; + } + + g_assert_not_reached (); +} + +void +cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format, + uint8_t *horizontal_factors, + uint8_t *vertical_factors) +{ + size_t i, j; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format != format) + continue; + + for (j = 0; j < format_info_table[i].n_planes; j++) + { + horizontal_factors[j] = format_info_table[i].hsub[j]; + vertical_factors[j] = format_info_table[i].vsub[j]; + } + + return; + } + + g_assert_not_reached (); +} + const char * cogl_pixel_format_to_string (CoglPixelFormat format) { @@ -308,3 +772,51 @@ cogl_pixel_format_to_string (CoglPixelFormat format) g_assert_not_reached (); } + +void +cogl_pixel_format_get_subformats (CoglPixelFormat format, + CoglPixelFormat *formats_out) +{ + size_t i, j; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format != format) + continue; + + for (j = 0; j < format_info_table[i].n_planes; j++) + formats_out[j] = format_info_table[i].subformats[j]; + return; + } + + g_assert_not_reached (); +} + +void +cogl_pixel_format_get_cogl_components (CoglPixelFormat format, + guint *components_out) +{ + switch (format) + { + case COGL_PIXEL_FORMAT_NV12: + components_out[0] = COGL_TEXTURE_COMPONENTS_R; + components_out[1] = COGL_TEXTURE_COMPONENTS_RG; + break; + case COGL_PIXEL_FORMAT_NV21: + components_out[0] = COGL_TEXTURE_COMPONENTS_R; + components_out[1] = COGL_TEXTURE_COMPONENTS_RG; + break; + case COGL_PIXEL_FORMAT_YUV422: + components_out[0] = COGL_TEXTURE_COMPONENTS_R; + components_out[1] = COGL_TEXTURE_COMPONENTS_R; + components_out[2] = COGL_TEXTURE_COMPONENTS_R; + break; + case COGL_PIXEL_FORMAT_YUV444: + components_out[0] = COGL_TEXTURE_COMPONENTS_R; + components_out[1] = COGL_TEXTURE_COMPONENTS_R; + components_out[2] = COGL_TEXTURE_COMPONENTS_R; + break; + default: + components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA; + } +} diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h index 6b015f9e2..48b332a84 100644 --- a/cogl/cogl/cogl-pixel-format.h +++ b/cogl/cogl/cogl-pixel-format.h @@ -145,7 +145,7 @@ G_BEGIN_DECLS * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits - * @COGL_PIXEL_FORMAT_YUV: Not currently supported + * @COGL_PIXEL_FORMAT_YUV: Obsolete. See the other YUV-based formats. * @COGL_PIXEL_FORMAT_R_8: Single red component, 8 bits * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits @@ -167,6 +167,35 @@ G_BEGIN_DECLS * @COGL_PIXEL_FORMAT_BGRA_1010102_PRE: Premultiplied BGRA, 32 bits, 10 bpc * @COGL_PIXEL_FORMAT_ARGB_2101010_PRE: Premultiplied ARGB, 32 bits, 10 bpc * @COGL_PIXEL_FORMAT_ABGR_2101010_PRE: Premultiplied ABGR, 32 bits, 10 bpc + * @COGL_PIXEL_FORMAT_YUYV: YUYV, 32 bits, 16 bpc (Y), 8 bpc (U & V) + * @COGL_PIXEL_FORMAT_YVYU: YVYU, 32 bits, 16 bpc (Y), 8 bpc (V & U) + * @COGL_PIXEL_FORMAT_UYVY: UYVY, 32 bits, 16 bpc (Y), 8 bpc (V & U) + * @COGL_PIXEL_FORMAT_VYUY: VYUV, 32 bits, 16 bpc (Y), 8 bpc (V & U) + * @COGL_PIXEL_FORMAT_AYUV: AYUV, 32 bits, 8 bpc + * @COGL_PIXEL_FORMAT_XRGB8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_XBGR8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_RGBX8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_BGRX8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_RGB888_A8: 2 planes: 1 RGB-plane (32-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_BGR888_A8: 2 planes: 1 BGR-plane (32-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_RGB565_A8: 2 planes: 1 RGB-plane (16-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_BGR565_A8: 2 planes: 1 BGR-plane (16-bit), 1 alpha-plane + * @COGL_PIXEL_FORMAT_NV12: 2 planes: 1 Y-plane, 1 UV-plane (2x2 subsampled) + * @COGL_PIXEL_FORMAT_NV21: 2 planes: 1 Y-plane, 1 VU-plane (2x2 subsampled) + * @COGL_PIXEL_FORMAT_NV16: 2 planes: 1 Y-plane, 1 UV-plane (2x1 subsampled) + * @COGL_PIXEL_FORMAT_NV61: 2 planes: 1 Y-plane, 1 VU-plane (2x1 subsampled) + * @COGL_PIXEL_FORMAT_NV24: 2 planes: 1 Y-plane, 1 UV-plane + * @COGL_PIXEL_FORMAT_NV42: 2 planes: 1 Y-plane, 1 VU-plane + * @COGL_PIXEL_FORMAT_YUV410: 3 planes: 1 Y-plane, 1 U-plane (4x4 subsampled), 1 V-plane (4x4 subsampled) + * @COGL_PIXEL_FORMAT_YVU410: 3 planes: 1 Y-plane, 1 V-plane (4x4 subsampled), 1 U-plane (4x4 subsampled) + * @COGL_PIXEL_FORMAT_YUV411: 3 planes: 1 Y-plane, 1 U-plane (4x1 subsampled), 1 V-plane (4x1 subsampled) + * @COGL_PIXEL_FORMAT_YVU411: 3 planes: 1 Y-plane, 1 V-plane (4x1 subsampled), 1 U-plane (4x1 subsampled) + * @COGL_PIXEL_FORMAT_YUV420: 3 planes: 1 Y-plane, 1 U-plane (2x2 subsampled), 1 V-plane (2x2 subsampled) + * @COGL_PIXEL_FORMAT_YVU420: 3 planes: 1 Y-plane, 1 V-plane (2x2 subsampled), 1 U-plane (2x2 subsampled) + * @COGL_PIXEL_FORMAT_YUV422: 3 planes: 1 Y-plane, 1 U-plane (2x1 subsampled), 1 V-plane (2x1 subsampled) + * @COGL_PIXEL_FORMAT_YVU422: 3 planes: 1 Y-plane, 1 V-plane (2x1 subsampled), 1 U-plane (2x1 subsampled) + * @COGL_PIXEL_FORMAT_YUV444: 3 planes: 1 Y-plane, 1 U-plane, 1 V-plane + * @COGL_PIXEL_FORMAT_YVU444: 3 planes: 1 Y-plane, 1 V-plane, 1 U-plane * * Pixel formats used by Cogl. For the formats with a byte per * component, the order of the components specify the order in @@ -230,20 +259,83 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/ COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT), COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT), - COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT) + COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT), + + /* From here on out, we simply enumerate with sequential values in the most + * significant enum byte. See the comments above if you want to know why. */ + + /* The following list is basically synced with Linux's <drm_fourcc.h> */ + + /* Packed YUV */ + COGL_PIXEL_FORMAT_YUYV = (1 << 24), + COGL_PIXEL_FORMAT_YVYU = (2 << 24), + COGL_PIXEL_FORMAT_UYVY = (3 << 24), + COGL_PIXEL_FORMAT_VYUY = (4 << 24), + + COGL_PIXEL_FORMAT_AYUV = (5 << 24), + + /* 2 plane RGB + A */ + COGL_PIXEL_FORMAT_XRGB8888_A8 = ( 6 << 24), + COGL_PIXEL_FORMAT_XBGR8888_A8 = ( 7 << 24), + COGL_PIXEL_FORMAT_RGBX8888_A8 = ( 8 << 24), + COGL_PIXEL_FORMAT_BGRX8888_A8 = ( 9 << 24), + COGL_PIXEL_FORMAT_RGB888_A8 = (10 << 24), + COGL_PIXEL_FORMAT_BGR888_A8 = (11 << 24), + COGL_PIXEL_FORMAT_RGB565_A8 = (12 << 24), + COGL_PIXEL_FORMAT_BGR565_A8 = (13 << 24), + + /* 2 plane YUV */ + COGL_PIXEL_FORMAT_NV12 = (14 << 24), + COGL_PIXEL_FORMAT_NV21 = (15 << 24), + COGL_PIXEL_FORMAT_NV16 = (16 << 24), + COGL_PIXEL_FORMAT_NV61 = (17 << 24), + COGL_PIXEL_FORMAT_NV24 = (18 << 24), + COGL_PIXEL_FORMAT_NV42 = (19 << 24), + + /* 3 plane YUV */ + COGL_PIXEL_FORMAT_YUV410 = (20 << 24), + COGL_PIXEL_FORMAT_YVU410 = (21 << 24), + COGL_PIXEL_FORMAT_YUV411 = (22 << 24), + COGL_PIXEL_FORMAT_YVU411 = (23 << 24), + COGL_PIXEL_FORMAT_YUV420 = (24 << 24), + COGL_PIXEL_FORMAT_YVU420 = (25 << 24), + COGL_PIXEL_FORMAT_YUV422 = (26 << 24), + COGL_PIXEL_FORMAT_YVU422 = (27 << 24), + COGL_PIXEL_FORMAT_YUV444 = (28 << 24), + COGL_PIXEL_FORMAT_YVU444 = (29 << 24) } CoglPixelFormat; +/** + * COGL_PIXEL_FORMAT_MAX_PLANES: + * + * The maximum number of planes + */ +#define COGL_PIXEL_FORMAT_MAX_PLANES (4) + /* - * _cogl_pixel_format_get_bytes_per_pixel: + * cogl_pixel_format_get_bytes_per_pixel: + * @format: a #CoglPixelFormat + * @bpp_out: (inout): A buffer that will be filled with the bytes-per-pixel for each + * plane + * + * Queries how many bytes a pixel of the given @format takes in each plane. + * + * Returns: The no. of bytes in one pixel of the given single-plane @format. + */ +void +cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format, + uint8_t *bpp_out); + +/* + * cogl_pixel_format_get_bytes_per_pixel_simple: * @format: a #CoglPixelFormat * * Queries how many bytes a pixel of the given @format takes. * - * Return value: The number of bytes taken for a pixel of the given - * @format. + * Returns: The no. of bytes in one pixel of the given single-plane @format. */ -int -_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format); +uint8_t +cogl_pixel_format_get_bytes_per_pixel_simple (CoglPixelFormat format); /* * _cogl_pixel_format_has_aligned_components: @@ -285,6 +377,26 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); (((format) & COGL_A_BIT) && (format) != COGL_PIXEL_FORMAT_A_8) /** + * cogl_pixel_format_get_n_planes: + * @format: The format for which to get the number of planes + * + * Returns the number of planes the given CoglPixelFormat specifies. + */ +uint8_t +cogl_pixel_format_get_n_planes (CoglPixelFormat format); + +/** + * cogl_pixel_format_get_subsampling_factors: + * @format: The format to get the subsampling factors from. + * + * Returns the subsampling in both the horizontal as the vertical direction. + */ +void +cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format, + uint8_t *horizontal_factors, + uint8_t *vertical_factors); + +/** * cogl_pixel_format_to_string: * @format: a #CoglPixelFormat * @@ -295,6 +407,14 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format); const char * cogl_pixel_format_to_string (CoglPixelFormat format); +void +cogl_pixel_format_get_subformats (CoglPixelFormat format, + CoglPixelFormat *formats_out); + +void +cogl_pixel_format_get_cogl_components (CoglPixelFormat format, + guint *components_out); + G_END_DECLS #endif /* __COGL_PIXEL_FORMAT_H__ */ diff --git a/cogl/cogl/cogl-texture-2d-sliced.c b/cogl/cogl/cogl-texture-2d-sliced.c index c651557a8..30fdfb3f5 100644 --- a/cogl/cogl/cogl-texture-2d-sliced.c +++ b/cogl/cogl/cogl-texture-2d-sliced.c @@ -163,7 +163,7 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds, tex_2ds->slice_y_spans->len - 1); if (last_x_span->waste > 0 || last_y_span->waste > 0) { - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); CoglSpan *first_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0); CoglSpan *first_y_span @@ -209,7 +209,7 @@ _cogl_texture_2d_sliced_set_waste (CoglTexture2DSliced *tex_2ds, { int bmp_rowstride = cogl_bitmap_get_rowstride (source_bmp); CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (source_format); uint8_t *bmp_data; const uint8_t *src; uint8_t *dst; @@ -972,7 +972,7 @@ cogl_texture_2d_sliced_new_from_data (CoglContext *ctx, /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c index 05cfff42a..d56538557 100644 --- a/cogl/cogl/cogl-texture-2d.c +++ b/cogl/cogl/cogl-texture-2d.c @@ -207,7 +207,7 @@ cogl_texture_2d_new_from_data (CoglContext *ctx, /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c index f57d4a770..299eb2ffe 100644 --- a/cogl/cogl/cogl-texture.c +++ b/cogl/cogl/cogl-texture.c @@ -430,10 +430,14 @@ _cogl_texture_set_region (CoglTexture *texture, gboolean ret; g_return_val_if_fail (format != COGL_PIXEL_FORMAT_ANY, FALSE); + g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE); /* Rowstride from width if none specified */ if (rowstride == 0) - rowstride = _cogl_pixel_format_get_bytes_per_pixel (format) * width; + { + uint8_t bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); + rowstride = bpp * width; + } /* Init source bitmap */ source_bmp = cogl_bitmap_new_for_data (ctx, @@ -471,7 +475,7 @@ cogl_texture_set_region (CoglTexture *texture, { GError *ignore_error = NULL; const uint8_t *first_pixel; - int bytes_per_pixel = _cogl_pixel_format_get_bytes_per_pixel (format); + int bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel_simple (format); gboolean status; /* Rowstride from width if none specified */ @@ -609,7 +613,7 @@ get_texture_bits_via_copy (CoglTexture *texture, full_tex_width = cogl_texture_get_width (texture); full_tex_height = cogl_texture_get_height (texture); - bpp = _cogl_pixel_format_get_bytes_per_pixel (dst_format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (dst_format); full_rowstride = bpp * full_tex_width; full_bits = g_malloc (full_rowstride * full_tex_height); @@ -658,7 +662,7 @@ texture_get_cb (CoglTexture *subtexture, CoglTextureGetData *tg_data = user_data; CoglTexture *meta_texture = tg_data->meta_texture; CoglPixelFormat closest_format = cogl_bitmap_get_format (tg_data->target_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (closest_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (closest_format); unsigned int rowstride = cogl_bitmap_get_rowstride (tg_data->target_bmp); int subtexture_width = cogl_texture_get_width (subtexture); int subtexture_height = cogl_texture_get_height (subtexture); @@ -748,7 +752,7 @@ cogl_texture_get_data (CoglTexture *texture, tex_height = cogl_texture_get_height (texture); /* Rowstride from texture width if none specified */ - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); if (rowstride == 0) rowstride = tex_width * bpp; diff --git a/cogl/cogl/cogl.c b/cogl/cogl/cogl.c index bf46ea055..fc66065a6 100644 --- a/cogl/cogl/cogl.c +++ b/cogl/cogl/cogl.c @@ -330,7 +330,7 @@ cogl_read_pixels (int x, CoglPixelFormat format, uint8_t *pixels) { - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); CoglBitmap *bitmap; _COGL_GET_CONTEXT (ctx, NO_RETVAL); diff --git a/cogl/cogl/deprecated/cogl-auto-texture.c b/cogl/cogl/deprecated/cogl-auto-texture.c index a13020c0d..0503abcbf 100644 --- a/cogl/cogl/deprecated/cogl-auto-texture.c +++ b/cogl/cogl/deprecated/cogl-auto-texture.c @@ -148,7 +148,7 @@ _cogl_texture_new_from_data (CoglContext *ctx, /* Rowstride from width if not given */ if (rowstride == 0) - rowstride = width * _cogl_pixel_format_get_bytes_per_pixel (format); + rowstride = width * cogl_pixel_format_get_bytes_per_pixel_simple (format); /* Wrap the data into a bitmap */ bmp = cogl_bitmap_new_for_data (ctx, diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c index b8fd2f689..07b971f86 100644 --- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c @@ -1303,7 +1303,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, if (!tmp_bmp) goto EXIT; - bpp = _cogl_pixel_format_get_bytes_per_pixel (read_format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (read_format); rowstride = cogl_bitmap_get_rowstride (tmp_bmp); ctx->texture_driver->prep_gl_for_pixels_download (ctx, @@ -1360,7 +1360,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer, else shared_bmp = cogl_object_ref (bitmap); - bpp = _cogl_pixel_format_get_bytes_per_pixel (bmp_format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (bmp_format); ctx->texture_driver->prep_gl_for_pixels_download (ctx, rowstride, diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c index 57d40f3a3..c17a66546 100644 --- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c @@ -250,7 +250,7 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, if (data) { memcpy (tex_2d->first_pixel.data, data, - _cogl_pixel_format_get_bytes_per_pixel (format)); + cogl_pixel_format_get_bytes_per_pixel_simple (format)); _cogl_bitmap_unmap (upload_bmp); } else @@ -259,7 +259,7 @@ allocate_from_bitmap (CoglTexture2D *tex_2d, "glGenerateMipmap fallback"); g_error_free (ignore); memset (tex_2d->first_pixel.data, 0, - _cogl_pixel_format_get_bytes_per_pixel (format)); + cogl_pixel_format_get_bytes_per_pixel_simple (format)); } } @@ -789,7 +789,7 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d, uint8_t *data = _cogl_bitmap_map (upload_bmp, COGL_BUFFER_ACCESS_READ, 0, &ignore); CoglPixelFormat bpp = - _cogl_pixel_format_get_bytes_per_pixel (upload_format); + cogl_pixel_format_get_bytes_per_pixel_simple (upload_format); tex_2d->first_pixel.gl_format = gl_format; tex_2d->first_pixel.gl_type = gl_type; @@ -852,7 +852,7 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d, GLenum gl_format; GLenum gl_type; - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); ctx->driver_vtable->pixel_format_to_gl (ctx, format, diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c index bb42e7910..b0402b7ec 100644 --- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c @@ -260,7 +260,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context, break; case COGL_PIXEL_FORMAT_ANY: + /* No support for YUV or multi-plane formats */ case COGL_PIXEL_FORMAT_YUV: + case COGL_PIXEL_FORMAT_YUYV: + case COGL_PIXEL_FORMAT_YVYU: + case COGL_PIXEL_FORMAT_UYVY: + case COGL_PIXEL_FORMAT_VYUY: + case COGL_PIXEL_FORMAT_AYUV: + case COGL_PIXEL_FORMAT_XRGB8888_A8: + case COGL_PIXEL_FORMAT_XBGR8888_A8: + case COGL_PIXEL_FORMAT_RGBX8888_A8: + case COGL_PIXEL_FORMAT_BGRX8888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + case COGL_PIXEL_FORMAT_NV16: + case COGL_PIXEL_FORMAT_NV61: + case COGL_PIXEL_FORMAT_NV24: + case COGL_PIXEL_FORMAT_NV42: + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: g_assert_not_reached (); break; } diff --git a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c index 1505a2af7..42082871e 100644 --- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c @@ -196,7 +196,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, GLuint gl_handle; uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (source_format); gboolean status = TRUE; GError *internal_error = NULL; int level_width; @@ -302,7 +302,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, { uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (source_format); gboolean status = TRUE; GError *internal_error = NULL; diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c index 829d2a38b..9646e4516 100644 --- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c @@ -198,7 +198,37 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context, break; case COGL_PIXEL_FORMAT_ANY: + /* No support for YUV or multi-plane formats */ case COGL_PIXEL_FORMAT_YUV: + case COGL_PIXEL_FORMAT_YUYV: + case COGL_PIXEL_FORMAT_YVYU: + case COGL_PIXEL_FORMAT_UYVY: + case COGL_PIXEL_FORMAT_VYUY: + case COGL_PIXEL_FORMAT_AYUV: + case COGL_PIXEL_FORMAT_XRGB8888_A8: + case COGL_PIXEL_FORMAT_XBGR8888_A8: + case COGL_PIXEL_FORMAT_RGBX8888_A8: + case COGL_PIXEL_FORMAT_BGRX8888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + case COGL_PIXEL_FORMAT_NV16: + case COGL_PIXEL_FORMAT_NV61: + case COGL_PIXEL_FORMAT_NV24: + case COGL_PIXEL_FORMAT_NV42: + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: g_assert_not_reached (); break; } diff --git a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c index 22130784b..21e6cfa78 100644 --- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c @@ -152,7 +152,7 @@ prepare_bitmap_alignment_for_upload (CoglContext *ctx, GError **error) { CoglPixelFormat format = cogl_bitmap_get_format (src_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); int src_rowstride = cogl_bitmap_get_rowstride (src_bmp); int width = cogl_bitmap_get_width (src_bmp); int alignment = 1; @@ -195,7 +195,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, GLuint gl_handle; uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (source_format); CoglBitmap *slice_bmp; int rowstride; gboolean status = TRUE; @@ -337,7 +337,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, GError **error) { CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); - int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); + int bpp = cogl_pixel_format_get_bytes_per_pixel_simple (source_format); int rowstride; int bmp_width = cogl_bitmap_get_width (source_bmp); int bmp_height = cogl_bitmap_get_height (source_bmp); diff --git a/cogl/cogl/libmutter-cogl.map.in b/cogl/cogl/libmutter-cogl.map.in index 12ae32d6d..8f8a2eaf6 100644 --- a/cogl/cogl/libmutter-cogl.map.in +++ b/cogl/cogl/libmutter-cogl.map.in @@ -42,7 +42,6 @@ global: _cogl_framebuffer_winsys_update_size; _cogl_winsys_egl_make_current; _cogl_winsys_egl_ensure_current; - _cogl_pixel_format_get_bytes_per_pixel*; _cogl_system_error_quark; _cogl_util_next_p2; @unit_tests_symbols@ diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index dab2674c4..513fa9c77 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -89,6 +89,7 @@ cogl_headers = [ 'cogl-pipeline-state.h', 'cogl-pipeline-layer-state.h', 'cogl-pixel-format.h', + 'cogl-pixel-format-conversion.h', 'cogl-primitives.h', 'cogl-texture.h', 'cogl-texture-2d.h', @@ -249,10 +250,11 @@ cogl_sources = [ 'cogl-bitmap-pixbuf.c', 'cogl-clip-stack.h', 'cogl-clip-stack.c', - 'cogl-feature-private.h', - 'cogl-feature-private.c', 'cogl-color-private.h', 'cogl-color.c', + 'cogl-pixel-format-conversion.c', + 'cogl-feature-private.c', + 'cogl-feature-private.h', 'cogl-buffer-private.h', 'cogl-buffer.c', 'cogl-pixel-buffer-private.h', diff --git a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c index df8295685..f1e313104 100644 --- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c +++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c @@ -730,7 +730,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap) image->bits_per_pixel, image->byte_order == LSBFirst); - bpp = _cogl_pixel_format_get_bytes_per_pixel (image_format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (image_format); offset = image->bytes_per_line * src_y + bpp * src_x; _cogl_texture_set_region (tex_pixmap->tex, diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c index f45679d3a..0f191a0d8 100644 --- a/src/wayland/meta-wayland-buffer.c +++ b/src/wayland/meta-wayland-buffer.c @@ -489,7 +489,7 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer, cairo_rectangle_int_t rect; shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL); - bpp = _cogl_pixel_format_get_bytes_per_pixel (format); + bpp = cogl_pixel_format_get_bytes_per_pixel_simple (format); cairo_region_get_rectangle (region, i, &rect); if (!_cogl_texture_set_region (texture, |