[mutter/wip/nielsdg/n-planes: 2/2] cogl: Add a notion of pixel format planes



commit aa2b2a2c981041c93ea83fcf8edeff413adae108
Author: Niels De Graef <niels degraef barco com>
Date:   Mon Oct 14 18:56:25 2019 +0200

    cogl: Add a notion of pixel format planes
    
    As we will start adding support for more pixel formats, we will need to
    define a notion of planes. This commit doesn't make any functional
    change, but starts adding the idea of pixel formats and how they (at
    this point only theoretically) can have multple planes.
    
    Since a lot of code in Mutter assumes we only get to deal with single
    plane pixel formats, this commit also adds assertions and if-checks to
    make sure we don't accidentally try something that doesn't make sense.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/858

 cogl/cogl/cogl-atlas-texture.c                     |   3 +-
 cogl/cogl/cogl-atlas.c                             |  11 +-
 cogl/cogl/cogl-bitmap.c                            |  26 ++-
 cogl/cogl/cogl-blit.c                              |   6 +-
 cogl/cogl/cogl-framebuffer.c                       |   5 +-
 cogl/cogl/cogl-pixel-format.c                      | 207 ++++++++++++---------
 cogl/cogl/cogl-pixel-format.h                      |  37 +++-
 cogl/cogl/cogl-texture-2d-sliced.c                 |  16 +-
 cogl/cogl/cogl-texture-2d.c                        |   3 +-
 cogl/cogl/cogl-texture.c                           |  26 ++-
 cogl/cogl/cogl.c                                   |   6 +-
 cogl/cogl/deprecated/cogl-auto-texture.c           |   3 +-
 cogl/cogl/driver/gl/cogl-framebuffer-gl.c          |   6 +-
 cogl/cogl/driver/gl/cogl-texture-2d-gl.c           |  23 ++-
 cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c    |  15 +-
 .../cogl/driver/gl/gles/cogl-texture-driver-gles.c |  23 ++-
 cogl/cogl/libmutter-cogl.map.in                    |   1 -
 cogl/cogl/winsys/cogl-texture-pixmap-x11.c         |   5 +-
 src/wayland/meta-wayland-buffer.c                  |  16 +-
 19 files changed, 298 insertions(+), 140 deletions(-)
---
diff --git a/cogl/cogl/cogl-atlas-texture.c b/cogl/cogl/cogl-atlas-texture.c
index e7f9c2125..766d747d3 100644
--- a/cogl/cogl/cogl-atlas-texture.c
+++ b/cogl/cogl/cogl-atlas-texture.c
@@ -938,11 +938,12 @@ cogl_atlas_texture_new_from_data (CoglContext *ctx,
   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 (format, 0);
 
   /* 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..729a2153f 100644
--- a/cogl/cogl/cogl-atlas.c
+++ b/cogl/cogl/cogl-atlas.c
@@ -182,6 +182,8 @@ _cogl_atlas_get_initial_size (CoglPixelFormat format,
 
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
+  g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1);
+
   ctx->driver_vtable->pixel_format_to_gl (ctx,
                                           format,
                                           &gl_intformat,
@@ -193,7 +195,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 (format, 0) == 1)
     size = 1024;
   else
     size = 512;
@@ -287,11 +289,16 @@ _cogl_atlas_create_texture (CoglAtlas *atlas,
 
   _COGL_GET_CONTEXT (ctx, NULL);
 
+  g_return_val_if_fail (
+    cogl_pixel_format_get_n_planes (atlas->texture_format) == 1,
+    NULL);
+
   if ((atlas->flags & COGL_ATLAS_CLEAR_TEXTURE))
     {
       uint8_t *clear_data;
       CoglBitmap *clear_bmp;
-      int bpp = _cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format);
+      uint8_t bpp = cogl_pixel_format_get_bytes_per_pixel (atlas->texture_format,
+                                                           0);
 
       /* Create a buffer of zeroes to initially clear the texture */
       clear_data = g_malloc0 (width * height * bpp);
diff --git a/cogl/cogl/cogl-bitmap.c b/cogl/cogl/cogl-bitmap.c
index 5d5dbc30a..9489036ee 100644
--- a/cogl/cogl/cogl-bitmap.c
+++ b/cogl/cogl/cogl-bitmap.c
@@ -127,7 +127,7 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
 {
   uint8_t *srcdata;
   uint8_t *dstdata;
-  int bpp;
+  uint8_t bpp;
   int line;
   gboolean succeeded = FALSE;
 
@@ -135,8 +135,10 @@ _cogl_bitmap_copy_subregion (CoglBitmap *src,
   g_return_val_if_fail ((src->format & ~COGL_PREMULT_BIT) ==
                         (dst->format & ~COGL_PREMULT_BIT),
                         FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (src->format) == 1,
+                        FALSE);
 
-  bpp = _cogl_pixel_format_get_bytes_per_pixel (src->format);
+  bpp = cogl_pixel_format_get_bytes_per_pixel (src->format, 0);
 
   if ((srcdata = _cogl_bitmap_map (src, COGL_BUFFER_ACCESS_READ, 0, error)))
     {
@@ -183,10 +185,11 @@ cogl_bitmap_new_for_data (CoglContext *context,
   CoglBitmap *bmp;
 
   g_return_val_if_fail (cogl_is_context (context), NULL);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 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 (format, 0);
 
   bmp = g_slice_new (CoglBitmap);
   bmp->context = context;
@@ -211,11 +214,18 @@ _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 rowstride = ((width * bpp) + 3) & ~3;
-  uint8_t *data = g_try_malloc (rowstride * height);
+  uint8_t bpp;
+  int rowstride;
+  uint8_t *data;
   CoglBitmap *bitmap;
 
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, NULL);
+
+  /* Try to malloc the data */
+  bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
+  rowstride = ((width * bpp) + 3) & ~3;
+  data = g_try_malloc (rowstride * height);
+
   if (!data)
     {
       g_set_error_literal (error, COGL_SYSTEM_ERROR,
@@ -224,6 +234,7 @@ _cogl_bitmap_new_with_malloc_buffer (CoglContext *context,
       return NULL;
     }
 
+  /* Now create the bitmap */
   bitmap = cogl_bitmap_new_for_data (context,
                                      width, height,
                                      format,
@@ -305,10 +316,11 @@ cogl_bitmap_new_with_size (CoglContext *context,
 
   /* creating a buffer to store "any" format does not make sense */
   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);
 
   /* 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 (format, 0);
 
   pixel_buffer =
     cogl_pixel_buffer_new (context,
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index 3340d6c50..0946f26d0 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -276,7 +276,11 @@ 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);
+
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (data->format) == 1,
+                        FALSE);
+
+  data->bpp = cogl_pixel_format_get_bytes_per_pixel (data->format, 0);
 
   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 e3e112f8c..154790f83 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -1316,10 +1316,13 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
                               CoglPixelFormat format,
                               uint8_t *pixels)
 {
-  int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
+  uint8_t bpp;
   CoglBitmap *bitmap;
   gboolean ret;
 
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
   bitmap = cogl_bitmap_new_for_data (framebuffer->context,
                                      width, height,
                                      format,
diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c
index a8c0857a6..7b79a6264 100644
--- a/cogl/cogl/cogl-pixel-format.c
+++ b/cogl/cogl/cogl-pixel-format.c
@@ -41,235 +41,254 @@ typedef struct _CoglPixelFormatInfo
 {
   CoglPixelFormat cogl_format;
   const char *format_str;
-  int bpp;                         /* Bytes per pixel                 */
   int aligned;                     /* Aligned components? (-1 if n/a) */
+  uint8_t n_planes;
+
+  /* Per-plane information */
+  uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES];  /* Bytes per pixel              */
 } 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 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_A_8,
     .format_str = "A_8",
-    .bpp = 1,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 1 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGB_565,
     .format_str = "RGB_565",
-    .bpp = 2,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444,
     .format_str = "RGBA_4444",
-    .bpp = 2,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551,
     .format_str = "RGBA_5551",
-    .bpp = 2,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_YUV,
     .format_str = "YUV",
-    .bpp = 0,
-    .aligned = -1
+    .n_planes = 1,
+    .aligned = -1,
+    .bpp = { 0 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_G_8,
     .format_str = "G_8",
-    .bpp = 1,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 1 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RG_88,
     .format_str = "RG_88",
-    .bpp = 2,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGB_888,
     .format_str = "RGB_888",
-    .bpp = 3,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 3 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_BGR_888,
     .format_str = "BGR_888",
-    .bpp = 3,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 3 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888,
     .format_str = "RGBA_8888",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888,
     .format_str = "BGRA_8888",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888,
     .format_str = "ARGB_8888",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888,
     .format_str = "ABGR_8888",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102,
     .format_str = "RGBA_1010102",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102,
     .format_str = "BGRA_1010102",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010,
     .format_str = "ARGB_2101010",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010,
     .format_str = "ABGR_2101010",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE,
     .format_str = "RGBA_8888_PRE",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE,
     .format_str = "BGRA_8888_PRE",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE,
     .format_str = "ARGB_8888_PRE",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE,
     .format_str = "ABGR_8888_PRE",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE,
     .format_str = "RGBA_4444_PRE",
-    .bpp = 2,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE,
     .format_str = "RGBA_5551_PRE",
-    .bpp = 2,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE,
     .format_str = "RGBA_1010102_PRE",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE,
     .format_str = "BGRA_1010102_PRE",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE,
     .format_str = "ARGB_2101010_PRE",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE,
     .format_str = "ABGR_2101010_PRE",
-    .bpp = 4,
-    .aligned = 0
+    .n_planes = 1,
+    .aligned = 0,
+    .bpp = { 4 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16,
     .format_str = "DEPTH_16",
-    .bpp = 2,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 2 }
   },
   {
     .cogl_format = COGL_PIXEL_FORMAT_DEPTH_32,
     .format_str = "DEPTH_32",
-    .bpp = 4,
-    .aligned = 1
+    .n_planes = 1,
+    .aligned = 1,
+    .bpp = { 4 }
   },
   {
     .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 }
   },
 };
 
-/*
- * 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 (CoglPixelFormat format,
+                                       uint8_t         plane)
 {
   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 (plane < format_info_table[i].n_planes, 0);
+
+          return format_info_table[i].bpp[plane];
+        }
     }
 
   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 +314,20 @@ _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 ();
+}
+
 const char *
 cogl_pixel_format_to_string (CoglPixelFormat format)
 {
diff --git a/cogl/cogl/cogl-pixel-format.h b/cogl/cogl/cogl-pixel-format.h
index c2659fee0..6039fab0d 100644
--- a/cogl/cogl/cogl-pixel-format.h
+++ b/cogl/cogl/cogl-pixel-format.h
@@ -233,17 +233,27 @@ typedef enum /*< prefix=COGL_PIXEL_FORMAT >*/
   COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
 } CoglPixelFormat;
 
-/*
- * _cogl_pixel_format_get_bytes_per_pixel:
- * @format: a #CoglPixelFormat
+/**
+ * COGL_PIXEL_FORMAT_MAX_PLANES:
+ *
+ * The maximum number of planes of a pixel format (see also
+ * cogl_pixel_format_get_planes()).
+ */
+#define COGL_PIXEL_FORMAT_MAX_PLANES (4)
+
+/**
+ * cogl_pixel_format_get_bytes_per_pixel:
+ * @format: The pixel format
+ * @plane: The index of the plane (should not be more than the number of planes
+ *         in the given format).
  *
- * Queries how many bytes a pixel of the given @format takes.
+ * Queries the number of bytes per pixel for a given format in the given plane.
  *
- * Return value: The number of bytes taken for a pixel of the given
- *               @format.
+ * Returns: The number of bytes per pixel in the given format's given plane.
  */
-int
-_cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format);
+uint8_t
+cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format,
+                                       uint8_t         plane);
 
 /*
  * _cogl_pixel_format_has_aligned_components:
@@ -284,6 +294,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_get_n_planes:
+ * @format: The format for which to get the number of planes
+ *
+ * Returns the number of planes the given CoglPixelFormat specifies.
+ *
+ * Returns: The no. of planes of @format (at most %COGL_PIXEL_FORMAT_MAX_PLANES)
+ */
+uint8_t
+cogl_pixel_format_get_n_planes (CoglPixelFormat format);
+
 /**
  * cogl_pixel_format_to_string:
  * @format: a #CoglPixelFormat
diff --git a/cogl/cogl/cogl-texture-2d-sliced.c b/cogl/cogl/cogl-texture-2d-sliced.c
index c651557a8..959c4a078 100644
--- a/cogl/cogl/cogl-texture-2d-sliced.c
+++ b/cogl/cogl/cogl-texture-2d-sliced.c
@@ -155,6 +155,9 @@ _cogl_texture_2d_sliced_allocate_waste_buffer (CoglTexture2DSliced *tex_2ds,
   CoglSpan *last_y_span;
   uint8_t *waste_buf = NULL;
 
+  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);
+
   /* If the texture has any waste then allocate a buffer big enough to
      fill the gaps */
   last_x_span = &g_array_index (tex_2ds->slice_x_spans, CoglSpan,
@@ -163,7 +166,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);
+      uint8_t bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
       CoglSpan  *first_x_span
         = &g_array_index (tex_2ds->slice_x_spans, CoglSpan, 0);
       CoglSpan  *first_y_span
@@ -209,17 +212,23 @@ _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);
+      uint8_t bpp;
       uint8_t *bmp_data;
       const uint8_t *src;
       uint8_t *dst;
       unsigned int wy, wx;
       CoglBitmap *waste_bmp;
 
+      /* We only support single plane formats here */
+      if (cogl_pixel_format_get_n_planes (source_format) == 1)
+        return FALSE;
+
       bmp_data = _cogl_bitmap_map (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error);
       if (bmp_data == NULL)
         return FALSE;
 
+      bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0);
+
       if (need_x)
         {
           src = (bmp_data + ((src_y + (int) y_iter->intersect_start - dst_y) *
@@ -968,11 +977,12 @@ cogl_texture_2d_sliced_new_from_data (CoglContext *ctx,
   CoglTexture2DSliced *tex_2ds;
 
   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 (format, 0);
 
   /* 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 1adf719a3..3d53a0ecd 100644
--- a/cogl/cogl/cogl-texture-2d.c
+++ b/cogl/cogl/cogl-texture-2d.c
@@ -204,11 +204,12 @@ cogl_texture_2d_new_from_data (CoglContext *ctx,
   CoglTexture2D *tex_2d;
 
   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 (format, 0);
 
   /* 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 96bada164..3d6324beb 100644
--- a/cogl/cogl/cogl-texture.c
+++ b/cogl/cogl/cogl-texture.c
@@ -430,10 +430,11 @@ _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;
+    rowstride = cogl_pixel_format_get_bytes_per_pixel (format, 0) * width;
 
   /* Init source bitmap */
   source_bmp = cogl_bitmap_new_for_data (ctx,
@@ -471,10 +472,14 @@ 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);
+  uint8_t bytes_per_pixel;
   gboolean status;
 
+  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 */
+  bytes_per_pixel = cogl_pixel_format_get_bytes_per_pixel (format, 0);
   if (rowstride == 0)
     rowstride = bytes_per_pixel * width;
 
@@ -603,13 +608,16 @@ get_texture_bits_via_copy (CoglTexture *texture,
   unsigned int full_rowstride;
   uint8_t *full_bits;
   gboolean ret = TRUE;
-  int bpp;
+  uint8_t bpp;
   int full_tex_width, full_tex_height;
 
+  g_return_val_if_fail (dst_format != COGL_PIXEL_FORMAT_ANY, FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (dst_format) == 1, FALSE);
+
   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 (dst_format, 0);
 
   full_rowstride = bpp * full_tex_width;
   full_bits = g_malloc (full_rowstride * full_tex_height);
@@ -658,7 +666,8 @@ 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);
+  /* We already asserted that we have a single plane format */
+  uint8_t bpp = cogl_pixel_format_get_bytes_per_pixel (closest_format, 0);
   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);
@@ -725,7 +734,7 @@ cogl_texture_get_data (CoglTexture *texture,
                       uint8_t *data)
 {
   CoglContext *ctx = texture->context;
-  int bpp;
+  uint8_t bpp;
   int byte_size;
   CoglPixelFormat closest_format;
   GLenum closest_gl_format;
@@ -744,11 +753,14 @@ cogl_texture_get_data (CoglTexture *texture,
   if (format == COGL_PIXEL_FORMAT_ANY)
     format = texture_format;
 
+  /* We only support single plane formats */
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, 0);
+
   tex_width = cogl_texture_get_width (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 (format, 0);
   if (rowstride == 0)
     rowstride = tex_width * bpp;
 
diff --git a/cogl/cogl/cogl.c b/cogl/cogl/cogl.c
index 886c9aa7b..e1e6d03fb 100644
--- a/cogl/cogl/cogl.c
+++ b/cogl/cogl/cogl.c
@@ -330,11 +330,15 @@ cogl_read_pixels (int x,
                   CoglPixelFormat format,
                   uint8_t *pixels)
 {
-  int bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
+  uint8_t bpp;
   CoglBitmap *bitmap;
 
+  g_return_if_fail (format != COGL_PIXEL_FORMAT_ANY);
+  g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1);
+
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
+  bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
   bitmap = cogl_bitmap_new_for_data (ctx,
                                      width, height,
                                      format,
diff --git a/cogl/cogl/deprecated/cogl-auto-texture.c b/cogl/cogl/deprecated/cogl-auto-texture.c
index a13020c0d..0e1d7467e 100644
--- a/cogl/cogl/deprecated/cogl-auto-texture.c
+++ b/cogl/cogl/deprecated/cogl-auto-texture.c
@@ -144,11 +144,12 @@ _cogl_texture_new_from_data (CoglContext *ctx,
   CoglTexture *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 (format, 0);
 
   /* 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 57507673e..94b1decde 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -1226,6 +1226,8 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
   gboolean pack_invert_set;
   int status = FALSE;
 
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
+
   _cogl_framebuffer_flush_state (framebuffer,
                                  framebuffer,
                                  COGL_FRAMEBUFFER_STATE_BIND);
@@ -1300,7 +1302,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 (read_format, 0);
       rowstride = cogl_bitmap_get_rowstride (tmp_bmp);
 
       ctx->texture_driver->prep_gl_for_pixels_download (ctx,
@@ -1357,7 +1359,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 (bmp_format, 0);
 
       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 04bac1b7b..946f4a247 100644
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -82,6 +82,10 @@ _cogl_texture_2d_gl_can_create (CoglContext *ctx,
   GLenum gl_format;
   GLenum gl_type;
 
+  /* We only support single plane formats for now */
+  if (cogl_pixel_format_get_n_planes (internal_format) != 1)
+    return FALSE;
+
   ctx->driver_vtable->pixel_format_to_gl (ctx,
                                           internal_format,
                                           &gl_intformat,
@@ -250,7 +254,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 (format, 0));
           _cogl_bitmap_unmap (upload_bmp);
         }
       else
@@ -259,7 +263,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 (format, 0));
         }
     }
 
@@ -778,6 +782,11 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
 
   upload_format = cogl_bitmap_get_format (upload_bmp);
 
+  /* Only support single plane formats */
+  if (upload_format == COGL_PIXEL_FORMAT_ANY ||
+      cogl_pixel_format_get_n_planes (upload_format) != 1)
+    return FALSE;
+
   ctx->driver_vtable->pixel_format_to_gl (ctx,
                                           upload_format,
                                           NULL, /* internal gl format */
@@ -791,8 +800,7 @@ _cogl_texture_2d_gl_copy_from_bitmap (CoglTexture2D *tex_2d,
       GError *ignore = NULL;
       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);
+      uint8_t bpp = cogl_pixel_format_get_bytes_per_pixel (upload_format, 0);
 
       tex_2d->first_pixel.gl_format = gl_format;
       tex_2d->first_pixel.gl_type = gl_type;
@@ -847,12 +855,15 @@ _cogl_texture_2d_gl_get_data (CoglTexture2D *tex_2d,
                               uint8_t *data)
 {
   CoglContext *ctx = COGL_TEXTURE (tex_2d)->context;
-  int bpp;
+  uint8_t bpp;
   int width = COGL_TEXTURE (tex_2d)->width;
   GLenum gl_format;
   GLenum gl_type;
 
-  bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
+  g_return_if_fail (format != COGL_PIXEL_FORMAT_ANY);
+  g_return_if_fail (cogl_pixel_format_get_n_planes (format) == 1);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
 
   ctx->driver_vtable->pixel_format_to_gl (ctx,
                                           format,
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 eabdf6e36..6bbcdf398 100644
--- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
@@ -188,12 +188,17 @@ _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);
+  uint8_t bpp;
   gboolean status = TRUE;
   GError *internal_error = NULL;
   int level_width;
   int level_height;
 
+  g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1,
+                        FALSE);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0);
   cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
 
   data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
@@ -294,10 +299,16 @@ _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);
+  uint8_t bpp;
   gboolean status = TRUE;
   GError *internal_error = NULL;
 
+  g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1,
+                        FALSE);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0);
+
   data = _cogl_bitmap_gl_bind (source_bmp,
                                COGL_BUFFER_ACCESS_READ,
                                0, /* hints */
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 7c163596b..885f66a52 100644
--- a/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c
+++ b/cogl/cogl/driver/gl/gles/cogl-texture-driver-gles.c
@@ -152,11 +152,16 @@ 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);
+  uint8_t bpp;
   int src_rowstride = cogl_bitmap_get_rowstride (src_bmp);
   int width = cogl_bitmap_get_width (src_bmp);
   int alignment = 1;
 
+  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);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
+
   if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE) ||
       src_rowstride == 0)
     return cogl_object_ref (src_bmp);
@@ -195,7 +200,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);
+  uint8_t bpp;
   CoglBitmap *slice_bmp;
   int rowstride;
   gboolean status = TRUE;
@@ -203,6 +208,12 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
   int level_width;
   int level_height;
 
+  g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1,
+                        FALSE);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0);
+
   cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
 
   /* If we have the GL_EXT_unpack_subimage extension then we can
@@ -337,7 +348,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);
+  uint8_t bpp;
   int rowstride;
   int bmp_width = cogl_bitmap_get_width (source_bmp);
   int bmp_height = cogl_bitmap_get_height (source_bmp);
@@ -346,6 +357,12 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
   GError *internal_error = NULL;
   gboolean status = TRUE;
 
+  g_return_val_if_fail (source_format != COGL_PIXEL_FORMAT_ANY, FALSE);
+  g_return_val_if_fail (cogl_pixel_format_get_n_planes (source_format) == 1,
+                        FALSE);
+
+  bpp = cogl_pixel_format_get_bytes_per_pixel (source_format, 0);
+
   bmp = prepare_bitmap_alignment_for_upload (ctx, source_bmp, error);
   if (!bmp)
     return FALSE;
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/winsys/cogl-texture-pixmap-x11.c b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
index df8295685..c3333fd4b 100644
--- a/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
+++ b/cogl/cogl/winsys/cogl-texture-pixmap-x11.c
@@ -621,7 +621,7 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
   XImage *image;
   int src_x, src_y;
   int x, y, width, height;
-  int bpp;
+  uint8_t bpp;
   int offset;
   GError *ignore = NULL;
 
@@ -729,8 +729,9 @@ _cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
                                         image->depth,
                                         image->bits_per_pixel,
                                         image->byte_order == LSBFirst);
+  g_return_if_fail (cogl_pixel_format_get_n_planes (image_format) == 1);
 
-  bpp = _cogl_pixel_format_get_bytes_per_pixel (image_format);
+  bpp = cogl_pixel_format_get_bytes_per_pixel (image_format, 0);
   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 cdaad26eb..29c89f912 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -477,22 +477,30 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
   struct wl_shm_buffer *shm_buffer;
   int i, n_rectangles;
   gboolean set_texture_failed = FALSE;
+  CoglPixelFormat format;
 
   n_rectangles = cairo_region_num_rectangles (region);
 
   shm_buffer = wl_shm_buffer_get (buffer->resource);
   wl_shm_buffer_begin_access (shm_buffer);
 
+  shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
+
+  /* We shouldn't be getting multi-plane texture formats. */
+  if (cogl_pixel_format_get_n_planes (format) != 1)
+    {
+      wl_shm_buffer_end_access (shm_buffer);
+      return FALSE;
+    }
+
   for (i = 0; i < n_rectangles; i++)
     {
       const uint8_t *data = wl_shm_buffer_get_data (shm_buffer);
       int32_t stride = wl_shm_buffer_get_stride (shm_buffer);
-      CoglPixelFormat format;
-      int bpp;
       cairo_rectangle_int_t rect;
+      uint8_t bpp;
 
-      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 (format, 0);
       cairo_region_get_rectangle (region, i, &rect);
 
       if (!_cogl_texture_set_region (texture,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]