[mutter/wip/nielsdg/meta-multi-texture-wip: 1/7] compositor: Add MetaMultiTexture class




commit efbd155a843c40f023ef3d3770c558aefbd67a64
Author: Niels De Graef <niels degraef barco com>
Date:   Wed Oct 16 12:11:33 2019 +0200

    compositor: Add MetaMultiTexture class
    
    In future commits, we want to be able to handle more complex textures,
    such as video frames which are encoded in a YUV-pixel format and have
    multiple planes (which each map to a separate texture).
    
    To accomplish this, we introduce a new object `MetaMultiTexture`: this
    object can deal with more complex formats by handling multiple
    `CoglTexture`s. In a later stage, it will be able to add `CoglSnippet`s
    to perform e.g. pixel format conversion (for example from YUV to RGBA).

 src/compositor/meta-multi-texture-format.c | 317 +++++++++++++++++++++++++++++
 src/compositor/meta-multi-texture.c        | 285 ++++++++++++++++++++++++++
 src/meson.build                            |   2 +
 src/meta/meson.build                       |   2 +
 src/meta/meta-multi-texture-format.h       | 129 ++++++++++++
 src/meta/meta-multi-texture.h              |  72 +++++++
 6 files changed, 807 insertions(+)
---
diff --git a/src/compositor/meta-multi-texture-format.c b/src/compositor/meta-multi-texture-format.c
new file mode 100644
index 0000000000..e838bb1822
--- /dev/null
+++ b/src/compositor/meta-multi-texture-format.c
@@ -0,0 +1,317 @@
+/*
+ * 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/>.
+ */
+
+/**
+ * SECTION:meta-multi-texture-format
+ * @title: MetaMultiTextureFormat
+ * @short_description: A representation for complex pixel formats
+ *
+ * Some pixel formats that are used in the wild are a bit more complex than
+ * just ARGB and all its variants. For example: a component might be put in a
+ * different plane (i.e. at a different place in memory). Another example are
+ * formats that use Y, U, and V components rather than RGB; if we composit them
+ * onto an RGBA framebuffer, we have to make sure for example that these get
+ * converted to the right color format first (using e.g. a shader).
+ */
+
+#include "meta/meta-multi-texture-format.h"
+
+#include <cogl/cogl.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct _MetaMultiTextureFormatInfo
+{
+  MetaMultiTextureFormat multi_format;
+  uint8_t n_planes;
+
+  /* Per plane-information */
+  uint8_t bpp[COGL_PIXEL_FORMAT_MAX_PLANES];        /* Bytes per pixel (without subsampling) */
+  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]; /* influences how we deal with it on a GL level 
*/
+} MetaMultiTextureFormatInfo;
+
+/* NOTE: The actual enum values are used as the index, so you don't need to
+ * loop over the table */
+static MetaMultiTextureFormatInfo multi_format_table[] = {
+  /* Simple */
+  {
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ANY },
+  },
+  /* Packed YUV */
+  { /* YUYV */
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
+  },
+  { /* YVYU */
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
+  },
+  { /* UYVY */
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
+  },
+  { /* VYUY */
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
+  },
+  { /* AYUV */
+    .n_planes = 1,
+    .bpp  = { 4 },
+    .hsub = { 1 },
+    .vsub = { 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888 },
+  },
+  /* 2 plane RGB + A */
+  { /* XRGB8888_A8 */
+    .n_planes = 2,
+    .bpp  = { 4, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ARGB_8888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* XBGR8888_A8 */
+    .n_planes = 2,
+    .bpp  = { 4, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_ABGR_8888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* RGBX8888_A8 */
+    .n_planes = 2,
+    .bpp  = { 4, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_RGBA_8888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* BGRX8888_A8 */
+    .n_planes = 2,
+    .bpp  = { 4, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_BGRA_8888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* RGB888_A8 */
+    .n_planes = 2,
+    .bpp  = { 3, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* BGR888_A8 */
+    .n_planes = 2,
+    .bpp  = { 3, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_BGR_888, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* RGB565_A8 */
+    .n_planes = 2,
+    .bpp  = { 2, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 },
+  },
+  { /* BGR565_A8 */
+    .n_planes = 2,
+    .bpp  = { 2, 1 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_RGB_565, COGL_PIXEL_FORMAT_A_8 },
+  },
+  /* 2 plane YUV */
+  { /* NV12 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 2 },
+    .vsub = { 1, 2 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  { /* NV21 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 2 },
+    .vsub = { 1, 2 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  { /* NV16 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 2 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  { /* NV61 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 2 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  { /* NV24 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  { /* NV42 */
+    .n_planes = 2,
+    .bpp  = { 1, 2 },
+    .hsub = { 1, 1 },
+    .vsub = { 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_RG_88 },
+  },
+  /* 3 plane YUV */
+  { /* YUV410 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 4, 4 },
+    .vsub = { 1, 4, 4 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YVU410 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 4, 4 },
+    .vsub = { 1, 4, 4 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YUV411 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 4, 4 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YVU411 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 4, 4 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YUV420 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 2, 2 },
+    .vsub = { 1, 2, 2 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YVU420 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 2, 2 },
+    .vsub = { 1, 2, 2 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YUV422 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 2, 2 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YVU422 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 2, 2 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YUV444 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 1, 1 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+  { /* YVU444 */
+    .n_planes = 3,
+    .bpp  = { 1, 1, 1 },
+    .hsub = { 1, 1, 1 },
+    .vsub = { 1, 1, 1 },
+    .subformats = { COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8, COGL_PIXEL_FORMAT_G_8 },
+  },
+};
+
+void
+meta_multi_texture_format_get_bytes_per_pixel (MetaMultiTextureFormat format,
+                                               uint8_t               *bpp_out)
+{
+  size_t i;
+
+  g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
+
+  for (i = 0; i < multi_format_table[format].n_planes; i++)
+    bpp_out[i] = multi_format_table[format].bpp[i];
+}
+
+int
+meta_multi_texture_format_get_n_planes (MetaMultiTextureFormat format)
+{
+  g_return_val_if_fail (format < G_N_ELEMENTS (multi_format_table), 0);
+
+  return multi_format_table[format].n_planes;
+}
+
+void
+meta_multi_texture_format_get_subsampling_factors (MetaMultiTextureFormat format,
+                                                   uint8_t               *horizontal_factors,
+                                                   uint8_t               *vertical_factors)
+{
+  size_t i;
+
+  g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
+
+  for (i = 0; i < multi_format_table[format].n_planes; i++)
+    {
+      horizontal_factors[i] = multi_format_table[format].hsub[i];
+      vertical_factors[i] = multi_format_table[format].vsub[i];
+    }
+}
+
+void
+meta_multi_texture_format_get_subformats (MetaMultiTextureFormat format,
+                                          CoglPixelFormat       *formats_out)
+{
+  size_t i;
+
+  g_return_if_fail (format < G_N_ELEMENTS (multi_format_table));
+
+  for (i = 0; i < multi_format_table[format].n_planes; i++)
+    formats_out[i] = multi_format_table[format].subformats[i];
+}
diff --git a/src/compositor/meta-multi-texture.c b/src/compositor/meta-multi-texture.c
new file mode 100644
index 0000000000..ad2a1357b4
--- /dev/null
+++ b/src/compositor/meta-multi-texture.c
@@ -0,0 +1,285 @@
+/*
+ * 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/>.
+ */
+
+/**
+ * SECTION:meta-multi-texture
+ * @title: MetaMultiTexture
+ * @short_description: A texture that can have multiple planes.
+ *
+ * #MetaMultiTexture allows one to deal with non-trivial formats that
+ * have multiple planes, requires subsampling and/or aren't in RGB. A common
+ * example of this are decoded video frames, which often use something in the
+ * YUV colorspace, combined with subsampling.
+ *
+ * The basic idea of a #MetaMultiTexture is the following:
+ * - Each plane is represented by a separate #CoglTexture. That means that you
+ *   should add each of these planes as a layer to your CoglPipeline.
+ * - When dealing with a color space that is not RGB, you can ask the
+ *   #MetaMultiTexture to create a shader for you that does the conversion
+ *   in the GPU.
+ * - In case you need to deal with memory access in a format with subsampling,
+ *   you can use meta_multi_texture_get_width() and its analogous version
+ *   for the height to get the correct size of the texture.
+ */
+
+#include "meta/meta-multi-texture.h"
+#include "meta/meta-enum-types.h"
+
+struct _MetaMultiTexture
+{
+  GObject parent_instance;
+
+  MetaMultiTextureFormat format;
+
+  guint n_planes;
+  CoglTexture **planes;
+};
+
+G_DEFINE_TYPE (MetaMultiTexture, meta_multi_texture, G_TYPE_OBJECT);
+
+/**
+ * meta_multi_texture_get_format:
+ * @self: a #MetaMultiTexture
+ *
+ * Returns the #MetaMultiTextureFormat that is used by this texture.
+ *
+ * Returns: The texture format that is used by this #MetaMultiTexture.
+ */
+MetaMultiTextureFormat
+meta_multi_texture_get_format (MetaMultiTexture *self)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), META_MULTI_TEXTURE_FORMAT_SIMPLE);
+
+  return self->format;
+}
+
+/**
+ * meta_multi_texture_is_simple:
+ * @self: a #MetaMultiTexture
+ *
+ * A small function that checks whether the given multi texture uses a "simple"
+ * format, i.e. one that can be represented by a #CoglPixelFormat.
+ *
+ * Returns: Whether the texture format is #META_MULTI_TEXTURE_FORMAT_SIMPLE
+ */
+gboolean
+meta_multi_texture_is_simple (MetaMultiTexture *self)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), FALSE);
+
+  return self->format == META_MULTI_TEXTURE_FORMAT_SIMPLE;
+}
+
+/**
+ * meta_multi_texture_get_n_planes:
+ * @self: a #MetaMultiTexture
+ *
+ * Returns the number of planes for this texture. Note that this is entirely
+ * dependent on the #CoglPixelFormat that is used. For example, simple RGB
+ * textures will have a single plane, while some more convoluted formats like
+ * NV12 and YUV 4:4:4 can have 2 and 3 planes respectively.
+ *
+ * Returns: The number of planes in this #MetaMultiTexture.
+ */
+guint
+meta_multi_texture_get_n_planes (MetaMultiTexture *self)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
+
+  return self->n_planes;
+}
+
+/**
+ * meta_multi_texture_get_plane:
+ * @self: a #MetaMultiTexture
+ * @index: the index of the plane
+ *
+ * Returns the n'th plane of the #MetaMultiTexture. Note that it's a programming
+ * error to use with an index larger than meta_multi_texture_get_n_planes().
+ *
+ * Returns: (transfer none): The plane at the given @index.
+ */
+CoglTexture *
+meta_multi_texture_get_plane (MetaMultiTexture *self, guint index)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
+  g_return_val_if_fail (index < self->n_planes, NULL);
+
+  return self->planes[index];
+}
+
+/**
+ * meta_multi_texture_get_width:
+ * @self: a #MetaMultiTexture
+ *
+ * Returns the width of the #MetaMultiTexture. Prefer this over calling
+ * cogl_texture_get_width() on one of the textures, as that might give a
+ * different size when dealing with subsampling.
+ *
+ * Returns: The width of the texture.
+ */
+int
+meta_multi_texture_get_width (MetaMultiTexture *self)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
+
+  return cogl_texture_get_width (self->planes[0]);
+}
+
+/**
+ * meta_multi_texture_get_height:
+ * @self: a #MetaMultiTexture
+ *
+ * Returns the height of the #MetaMultiTexture. Prefer this over calling
+ * cogl_texture_get_height() on one of the textures, as that might give a
+ * different size when dealing with subsampling.
+ *
+ * Returns: The height of the texture.
+ */
+int
+meta_multi_texture_get_height (MetaMultiTexture *self)
+{
+  g_return_val_if_fail (META_IS_MULTI_TEXTURE (self), 0);
+
+  return cogl_texture_get_height (self->planes[0]);
+}
+
+static void
+meta_multi_texture_finalize (GObject *object)
+{
+  MetaMultiTexture *self = META_MULTI_TEXTURE (object);
+  int i;
+
+  for (i = 0; i < self->n_planes; i++)
+    cogl_clear_object (&self->planes[i]);
+
+  g_free (self->planes);
+
+  G_OBJECT_CLASS (meta_multi_texture_parent_class)->finalize (object);
+}
+
+static void
+meta_multi_texture_init (MetaMultiTexture *self)
+{
+}
+
+static void
+meta_multi_texture_class_init (MetaMultiTextureClass *klass)
+{
+  GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
+
+  gobj_class->finalize = meta_multi_texture_finalize;
+}
+
+/**
+ * meta_multi_texture_new:
+ * @format: The format of the #MetaMultiTexture
+ * @planes: (transfer full): The actual planes of the texture
+ * @n_planes: The number of planes
+ *
+ * Creates a #MetaMultiTexture with the given @format. Each of the
+ * #CoglTexture<!-- -->s represents a plane.
+ *
+ * Returns: (transfer full): A new #MetaMultiTexture. Use g_object_unref() when
+ * you're done with it.
+ */
+MetaMultiTexture *
+meta_multi_texture_new (MetaMultiTextureFormat format,
+                        CoglTexture          **planes,
+                        guint                  n_planes)
+{
+  MetaMultiTexture *self;
+
+  g_return_val_if_fail (planes != NULL, NULL);
+  g_return_val_if_fail (n_planes > 0, NULL);
+
+  self = g_object_new (META_TYPE_MULTI_TEXTURE, NULL);
+  self->format = format;
+  self->n_planes = n_planes;
+  self->planes = planes;
+
+  return self;
+}
+
+/**
+ * meta_multi_texture_new_simple:
+ * @plane: (transfer full): The single plane of the texture
+ *
+ * Creates a #MetaMultiTexture for a "simple" texture, i.e. with only one
+ * plane, in a format that can be represented using #CoglPixelFormat.
+ *
+ * Returns: (transfer full): A new #MetaMultiTexture. Use g_object_unref() when
+ * you're done with it.
+ */
+MetaMultiTexture *
+meta_multi_texture_new_simple (CoglTexture *plane)
+{
+  MetaMultiTexture *self;
+
+  g_return_val_if_fail (plane != NULL, NULL);
+
+  self = g_object_new (META_TYPE_MULTI_TEXTURE, NULL);
+  self->format = META_MULTI_TEXTURE_FORMAT_SIMPLE;
+  self->n_planes = 1;
+  self->planes = g_malloc (sizeof (CoglTexture *));
+  self->planes[0] = plane;
+
+  return self;
+}
+
+/**
+ * meta_multi_texture_to_string:
+ * @self: a #MetaMultiTexture
+ *
+ * Returns a string representation of @self, useful for debugging purposes.
+ *
+ * Returns: (transfer full): A string representation of @self. Use g_free() when
+ * done with it.
+ */
+char *
+meta_multi_texture_to_string (MetaMultiTexture *self)
+{
+  g_autoptr(GString) str = NULL;
+  g_autofree char *format_str = NULL;
+  g_autofree char *ret = NULL;
+  uint8_t i;
+
+  str = g_string_new ("");
+  g_string_append_printf (str, "MetaMultiTexture (%p) {\n", self);
+  format_str = g_enum_to_string (META_TYPE_MULTI_TEXTURE_FORMAT, self->format);
+  g_string_append_printf (str, "  .format   =  %s;\n", format_str);
+  g_string_append_printf (str, "  .n_planes =  %u;\n", self->n_planes);
+  g_string_append (str, "  .planes   =  {\n");
+
+  for (i = 0; i < self->n_planes; i++)
+    {
+      CoglTexture *plane = self->planes[i];
+      CoglPixelFormat plane_format = _cogl_texture_get_format (plane);
+
+      g_string_append_printf (str, "    (%p) { .format = %s },\n",
+                              plane,
+                              cogl_pixel_format_to_string (plane_format));
+    }
+
+  g_string_append (str, "  }\n");
+  g_string_append (str, "}");
+
+  ret = g_string_free (g_steal_pointer (&str), FALSE);
+  return g_steal_pointer (&ret);
+}
diff --git a/src/meson.build b/src/meson.build
index 3683907ff3..c031dd80c2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -315,6 +315,8 @@ mutter_sources = [
   'compositor/meta-later.c',
   'compositor/meta-module.c',
   'compositor/meta-module.h',
+  'compositor/meta-multi-texture.c',
+  'compositor/meta-multi-texture-format.c',
   'compositor/meta-plugin.c',
   'compositor/meta-plugin-manager.c',
   'compositor/meta-plugin-manager.h',
diff --git a/src/meta/meson.build b/src/meta/meson.build
index a096ee4dd7..064d54a9ab 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -22,6 +22,8 @@ mutter_public_headers = [
   'meta-launch-context.h',
   'meta-later.h',
   'meta-monitor-manager.h',
+  'meta-multi-texture.h',
+  'meta-multi-texture-format.h',
   'meta-plugin.h',
   'meta-remote-access-controller.h',
   'meta-selection.h',
diff --git a/src/meta/meta-multi-texture-format.h b/src/meta/meta-multi-texture-format.h
new file mode 100644
index 0000000000..e5ae4e8493
--- /dev/null
+++ b/src/meta/meta-multi-texture-format.h
@@ -0,0 +1,129 @@
+/*
+ * 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 __META_MULTI_TEXTURE_FORMAT_H__
+#define __META_MULTI_TEXTURE_FORMAT_H__
+
+#include <glib.h>
+#include <cogl/cogl.h>
+#include <meta/common.h>
+
+G_BEGIN_DECLS
+
+/**
+ * MetaMultiTextureFormat:
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_SIMPLE: Any format supported by Cogl (see #CoglPixelFormat)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUYV: YUYV, 32 bits, 16 bpc (Y), 8 bpc (U & V)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVYU: YVYU, 32 bits, 16 bpc (Y), 8 bpc (V & U)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_UYVY: UYVY, 32 bits, 16 bpc (Y), 8 bpc (V & U)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_VYUY: VYUV, 32 bits, 16 bpc (Y), 8 bpc (V & U)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_AYUV: AYUV, 32 bits, 8 bpc
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_XRGB8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_XBGR8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_RGBX8888_A8: 2 planes: 1 RGB-plane (64-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_BGRX8888_A8: 2 planes: 1 BGR-plane (64-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_RGB888_A8: 2 planes: 1 RGB-plane (32-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_BGR888_A8: 2 planes: 1 BGR-plane (32-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_RGB565_A8: 2 planes: 1 RGB-plane (16-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_BGR565_A8: 2 planes: 1 BGR-plane (16-bit), 1 alpha-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV12: 2 planes: 1 Y-plane, 1 UV-plane (2x2 subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV21: 2 planes: 1 Y-plane, 1 VU-plane (2x2 subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV16: 2 planes: 1 Y-plane, 1 UV-plane (2x1 subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV61: 2 planes: 1 Y-plane, 1 VU-plane (2x1 subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV24: 2 planes: 1 Y-plane, 1 UV-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_NV42: 2 planes: 1 Y-plane, 1 VU-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV410: 3 planes: 1 Y-plane, 1 U-plane (4x4 subsampled), 1 V-plane (4x4 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU410: 3 planes: 1 Y-plane, 1 V-plane (4x4 subsampled), 1 U-plane (4x4 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV411: 3 planes: 1 Y-plane, 1 U-plane (4x1 subsampled), 1 V-plane (4x1 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU411: 3 planes: 1 Y-plane, 1 V-plane (4x1 subsampled), 1 U-plane (4x1 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV420: 3 planes: 1 Y-plane, 1 U-plane (2x2 subsampled), 1 V-plane (2x2 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU420: 3 planes: 1 Y-plane, 1 V-plane (2x2 subsampled), 1 U-plane (2x2 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV422: 3 planes: 1 Y-plane, 1 U-plane (2x1 subsampled), 1 V-plane (2x1 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU422: 3 planes: 1 Y-plane, 1 V-plane (2x1 subsampled), 1 U-plane (2x1 
subsampled)
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YUV444: 3 planes: 1 Y-plane, 1 U-plane, 1 V-plane
+ * @META_MULTI_TEXTURE_FORMAT_FORMAT_YVU444: 3 planes: 1 Y-plane, 1 V-plane, 1 U-plane
+ *
+ * XXX write docs
+ */
+typedef enum _MetaMultiTextureFormat
+{
+  META_MULTI_TEXTURE_FORMAT_SIMPLE,
+
+  /* The following list is somewhat synced with Linux's <drm_fourcc.h> */
+
+  /* Packed YUV */
+  META_MULTI_TEXTURE_FORMAT_YUYV,
+  META_MULTI_TEXTURE_FORMAT_YVYU,
+  META_MULTI_TEXTURE_FORMAT_UYVY,
+  META_MULTI_TEXTURE_FORMAT_VYUY,
+
+  META_MULTI_TEXTURE_FORMAT_AYUV,
+
+  /* 2 plane RGB + A */
+  META_MULTI_TEXTURE_FORMAT_XRGB8888_A8,
+  META_MULTI_TEXTURE_FORMAT_XBGR8888_A8,
+  META_MULTI_TEXTURE_FORMAT_RGBX8888_A8,
+  META_MULTI_TEXTURE_FORMAT_BGRX8888_A8,
+  META_MULTI_TEXTURE_FORMAT_RGB888_A8,
+  META_MULTI_TEXTURE_FORMAT_BGR888_A8,
+  META_MULTI_TEXTURE_FORMAT_RGB565_A8,
+  META_MULTI_TEXTURE_FORMAT_BGR565_A8,
+
+  /* 2 plane YUV */
+  META_MULTI_TEXTURE_FORMAT_NV12,
+  META_MULTI_TEXTURE_FORMAT_NV21,
+  META_MULTI_TEXTURE_FORMAT_NV16,
+  META_MULTI_TEXTURE_FORMAT_NV61,
+  META_MULTI_TEXTURE_FORMAT_NV24,
+  META_MULTI_TEXTURE_FORMAT_NV42,
+
+  /* 3 plane YUV */
+  META_MULTI_TEXTURE_FORMAT_YUV410,
+  META_MULTI_TEXTURE_FORMAT_YVU410,
+  META_MULTI_TEXTURE_FORMAT_YUV411,
+  META_MULTI_TEXTURE_FORMAT_YVU411,
+  META_MULTI_TEXTURE_FORMAT_YUV420,
+  META_MULTI_TEXTURE_FORMAT_YVU420,
+  META_MULTI_TEXTURE_FORMAT_YUV422,
+  META_MULTI_TEXTURE_FORMAT_YVU422,
+  META_MULTI_TEXTURE_FORMAT_YUV444,
+  META_MULTI_TEXTURE_FORMAT_YVU444
+} MetaMultiTextureFormat;
+
+META_EXPORT
+void  meta_multi_texture_format_get_bytes_per_pixel     (MetaMultiTextureFormat format,
+                                                         uint8_t               *bpp_out);
+
+META_EXPORT
+int   meta_multi_texture_format_get_n_planes            (MetaMultiTextureFormat format);
+
+META_EXPORT
+void  meta_multi_texture_format_get_subsampling_factors (MetaMultiTextureFormat format,
+                                                         uint8_t               *horizontal_factors,
+                                                         uint8_t               *vertical_factors);
+
+META_EXPORT
+void  meta_multi_texture_format_get_subformats          (MetaMultiTextureFormat format,
+                                                         CoglPixelFormat       *formats_out);
+
+G_END_DECLS
+
+#endif
diff --git a/src/meta/meta-multi-texture.h b/src/meta/meta-multi-texture.h
new file mode 100644
index 0000000000..3c895e5055
--- /dev/null
+++ b/src/meta/meta-multi-texture.h
@@ -0,0 +1,72 @@
+/*
+ * 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 __META_MULTI_TEXTURE_H__
+#define __META_MULTI_TEXTURE_H__
+
+#include <glib-object.h>
+#include <cogl/cogl.h>
+#include <meta/common.h>
+
+#include "meta/meta-multi-texture-format.h"
+
+G_BEGIN_DECLS
+
+#define META_TYPE_MULTI_TEXTURE (meta_multi_texture_get_type ())
+META_EXPORT
+G_DECLARE_FINAL_TYPE (MetaMultiTexture, meta_multi_texture,
+                      META, MULTI_TEXTURE,
+                      GObject)
+
+
+META_EXPORT
+MetaMultiTexture *     meta_multi_texture_new              (MetaMultiTextureFormat format,
+                                                            CoglTexture          **planes,
+                                                            guint                  n_planes);
+
+META_EXPORT
+MetaMultiTexture *     meta_multi_texture_new_simple       (CoglTexture    *plane);
+
+META_EXPORT
+MetaMultiTextureFormat meta_multi_texture_get_format       (MetaMultiTexture *self);
+
+META_EXPORT
+gboolean               meta_multi_texture_is_simple        (MetaMultiTexture *self);
+
+META_EXPORT
+guint                  meta_multi_texture_get_n_planes     (MetaMultiTexture *self);
+
+META_EXPORT
+CoglTexture *          meta_multi_texture_get_plane        (MetaMultiTexture *self,
+                                                            guint index);
+
+META_EXPORT
+int                    meta_multi_texture_get_width        (MetaMultiTexture *self);
+
+META_EXPORT
+int                    meta_multi_texture_get_height       (MetaMultiTexture *self);
+
+META_EXPORT
+char *                 meta_multi_texture_to_string        (MetaMultiTexture *self);
+
+G_END_DECLS
+
+#endif


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