[mutter/wip/nielsdg/add-yuv-support: 4/5] cogl: Add CoglMultiPlaneTexture for complex formats
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/nielsdg/add-yuv-support: 4/5] cogl: Add CoglMultiPlaneTexture for complex formats
- Date: Fri, 21 Jun 2019 14:33:49 +0000 (UTC)
commit b575f1065c37878541357a9ba56b5cacc09d074c
Author: Niels De Graef <niels degraef barco com>
Date: Wed Nov 14 12:22:02 2018 +0100
cogl: Add CoglMultiPlaneTexture for complex formats
Mutter always assumed that any texture it got was
representable by a `CoglTexture`, which does not have this kind of
concept. This also has the useful feature that each `CoglTexture`
corresponds to a single layer in a `CoglPipeline`.
To deal with this, we introduce a new object: a `CoglMultiPlaneTexture`
consists of multiple `CoglTexture`s, each representing a plane in the
texture we got. It also provides knows when to use a
CoglPixelFormatConversion.
cogl/cogl/cogl-multi-plane-texture.c | 157 +++++++++++++++++++++++++++
cogl/cogl/cogl-multi-plane-texture.h | 187 +++++++++++++++++++++++++++++++++
cogl/cogl/cogl-texture-2d.c | 4 +
cogl/cogl/cogl-texture-2d.h | 1 +
cogl/cogl/cogl.h | 2 +
cogl/cogl/meson.build | 2 +
cogl/cogl/winsys/cogl-winsys-egl-x11.c | 1 +
7 files changed, 354 insertions(+)
---
diff --git a/cogl/cogl/cogl-multi-plane-texture.c b/cogl/cogl/cogl-multi-plane-texture.c
new file mode 100644
index 000000000..db12e3471
--- /dev/null
+++ b/cogl/cogl/cogl-multi-plane-texture.c
@@ -0,0 +1,157 @@
+/*
+ * 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-multi-plane-texture.h"
+#include "cogl-gtype-private.h"
+#include "cogl-texture-private.h"
+#include "cogl-texture-2d-sliced.h"
+
+struct _CoglMultiPlaneTexture
+{
+ CoglObject _parent;
+
+ CoglPixelFormat format;
+
+ uint8_t n_planes;
+ CoglTexture **planes;
+};
+
+static void
+_cogl_multi_plane_texture_free (CoglMultiPlaneTexture *self);
+
+COGL_OBJECT_DEFINE (MultiPlaneTexture, multi_plane_texture);
+COGL_GTYPE_DEFINE_CLASS (MultiPlaneTexture, multi_plane_texture);
+
+
+CoglPixelFormat
+cogl_multi_plane_texture_get_format (CoglMultiPlaneTexture *self)
+{
+ return self->format;
+}
+
+uint8_t
+cogl_multi_plane_texture_get_n_planes (CoglMultiPlaneTexture *self)
+{
+ return self->n_planes;
+}
+
+CoglTexture *
+cogl_multi_plane_texture_get_plane (CoglMultiPlaneTexture *self, guint index)
+{
+ g_return_val_if_fail (self->n_planes > 0, NULL);
+ g_return_val_if_fail (index < self->n_planes, NULL);
+
+ return self->planes[index];
+}
+
+CoglTexture **
+cogl_multi_plane_texture_get_planes (CoglMultiPlaneTexture *self)
+{
+ return self->planes;
+}
+
+guint
+cogl_multi_plane_texture_get_width (CoglMultiPlaneTexture *self)
+{
+ g_return_val_if_fail (self->n_planes > 0, 0);
+
+ return cogl_texture_get_width (self->planes[0]);
+}
+
+guint
+cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self)
+{
+ g_return_val_if_fail (self->n_planes > 0, 0);
+
+ return cogl_texture_get_height (self->planes[0]);
+}
+
+static void
+_cogl_multi_plane_texture_free (CoglMultiPlaneTexture *self)
+{
+ uint8_t i = 0;
+
+ for (i = 0; i < self->n_planes; i++)
+ cogl_object_unref (self->planes[i]);
+
+ g_free (self->planes);
+}
+
+CoglMultiPlaneTexture *
+cogl_multi_plane_texture_new (CoglPixelFormat format,
+ CoglTexture **planes, uint8_t n_planes)
+{
+ CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
+
+ _cogl_multi_plane_texture_object_new (self);
+
+ self->format = format;
+ self->n_planes = n_planes;
+ self->planes = planes;
+
+ return self;
+}
+
+CoglMultiPlaneTexture *
+cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
+ CoglTexture *plane)
+{
+ CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
+
+ _cogl_multi_plane_texture_object_new (self);
+
+ self->format = format;
+ self->n_planes = 1;
+ self->planes = g_malloc (sizeof (CoglTexture *));
+ self->planes[0] = plane;
+
+ return self;
+}
+
+char *
+cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self)
+{
+ g_autoptr(GString) str = NULL;
+ g_autofree char *ret = NULL;
+ uint8_t i;
+
+ str = g_string_new ("");
+ g_string_append_printf (str, "CoglMultiPlaneTexture (%p) {\n", self);
+ g_string_append_printf (str, " .format = %s;\n", cogl_pixel_format_to_string (self->format));
+ 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];
+
+ g_string_append_printf (str, " (%p) { .format = %s },\n",
+ plane,
+ cogl_pixel_format_to_string (_cogl_texture_get_format (plane)));
+ }
+
+ 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/cogl/cogl/cogl-multi-plane-texture.h b/cogl/cogl/cogl-multi-plane-texture.h
new file mode 100644
index 000000000..f69ff23bd
--- /dev/null
+++ b/cogl/cogl/cogl-multi-plane-texture.h
@@ -0,0 +1,187 @@
+/*
+ * 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_MULTI_PLANE_TEXTURE_H__
+#define __COGL_MULTI_PLANE_TEXTURE_H__
+
+#include "cogl/cogl-texture.h"
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION:cogl-multi-plane-texture
+ * @title: CoglMultiPlaneTexture
+ * @short_description: A non-primitive texture that can have multiple planes.
+ *
+ * #CoglMultiPlaneTexture 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 #CoglMultiPlaneTexture 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
+ * #CoglMultiPlaneTexture 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 cogl_multi_plane_texture_get_width() and its analogous version
+ * for the height to get the correct size of the texture.
+ */
+
+typedef struct _CoglMultiPlaneTexture CoglMultiPlaneTexture;
+#define COGL_MULTI_PLANE_TEXTURE(tex) ((CoglMultiPlaneTexture *) tex)
+
+
+/**
+ * cogl_multi_plane_texture_get_gtype:
+ *
+ * Returns: a #GType that can be used with the GLib type system.
+ */
+GType cogl_multi_plane_texture_get_gtype (void);
+
+/**
+ * cogl_is_multi_plane_texture:
+ * @object: A #CoglObject pointer
+ *
+ * Gets whether the given @object references an existing CoglMultiPlaneTexture.
+ *
+ * Return value: %TRUE if the @object references a #CoglMultiPlaneTexture,
+ * %FALSE otherwise
+ */
+gboolean
+cogl_is_multi_plane_texture (void *object);
+
+/**
+ * cogl_multi_plane_texture_new:
+ * @format: The format of the #CoglMultiPlaneTexture
+ * @planes: (transfer full): The actual planes of the texture
+ * @n_planes: The number of planes
+ *
+ * Creates a #CoglMultiPlaneTexture with the given @format. Each of the
+ * #CoglTexture<!-- -->s represents a plane.
+ *
+ * Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
+ * cogl_object_unref() when you're done with it.
+ */
+CoglMultiPlaneTexture * cogl_multi_plane_texture_new (CoglPixelFormat format,
+ CoglTexture **planes,
+ uint8_t n_planes);
+
+/**
+ * cogl_multi_plane_texture_new_single_plane:
+ * @format: The format of the #CoglMultiPlaneTexture
+ * @plane: (transfer full): The actual planes of the texture
+ *
+ * Creates a #CoglMultiPlaneTexture for a "simple" texture, i.e. with only one
+ * plane.
+ *
+ * Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
+ * cogl_object_unref() when you're done with it.
+ */
+CoglMultiPlaneTexture * cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
+ CoglTexture *plane);
+
+/**
+ * cogl_multi_plane_texture_get_format:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * Returns the pixel format that is used by this texture.
+ *
+ * Returns: The pixel format that is used by this #CoglMultiPlaneTexture.
+ */
+CoglPixelFormat cogl_multi_plane_texture_get_format (CoglMultiPlaneTexture *self);
+
+/**
+ * cogl_multi_plane_texture_get_n_planes:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * 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 #CoglMultiPlaneTexture.
+ */
+uint8_t cogl_multi_plane_texture_get_n_planes (CoglMultiPlaneTexture *self);
+
+/**
+ * cogl_multi_plane_texture_get_plane:
+ * @self: a #CoglMultiPlaneTexture
+ * @index: the index of the plane
+ *
+ * Returns the n'th plane of the #CoglMultiPlaneTexture. Note that it is a
+ * programming error to use with an index larger than
+ * cogl_multi_plane_texture_get_n_planes().
+ *
+ * Returns: (transfer none): The plane at the given @index.
+ */
+CoglTexture * cogl_multi_plane_texture_get_plane (CoglMultiPlaneTexture *self,
+ guint index);
+
+/**
+ * cogl_multi_plane_texture_get_planes:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * Returns all planes of the #CoglMultiPlaneTexture.
+ *
+ * Returns: (transfer none): The planes of this texture.
+ */
+CoglTexture ** cogl_multi_plane_texture_get_planes (CoglMultiPlaneTexture *self);
+
+/**
+ * cogl_multi_plane_texture_get_width:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * Returns the width of the #CoglMultiPlaneTexture. 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.
+ */
+guint cogl_multi_plane_texture_get_width (CoglMultiPlaneTexture *self);
+
+/**
+ * cogl_multi_plane_texture_get_height:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * Returns the height of the #CoglMultiPlaneTexture. 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.
+ */
+guint cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self);
+
+/**
+ * cogl_multi_plane_texture_to_string:
+ * @self: a #CoglMultiPlaneTexture
+ *
+ * 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 * cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self);
+
+G_END_DECLS
+
+#endif
diff --git a/cogl/cogl/cogl-texture-2d.c b/cogl/cogl/cogl-texture-2d.c
index d56538557..cd8fce68a 100644
--- a/cogl/cogl/cogl-texture-2d.c
+++ b/cogl/cogl/cogl-texture-2d.c
@@ -239,6 +239,7 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
+ CoglTextureComponents components,
EGLImageKHR image,
GError **error)
{
@@ -263,6 +264,9 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
tex = _cogl_texture_2d_create_base (ctx, width, height, format, loader);
+ /* Make sure we've set the right components before allocating */
+ cogl_texture_set_components (COGL_TEXTURE (tex), components);
+
if (!cogl_texture_allocate (COGL_TEXTURE (tex), error))
{
cogl_object_unref (tex);
diff --git a/cogl/cogl/cogl-texture-2d.h b/cogl/cogl/cogl-texture-2d.h
index 5fc97179e..e5b91172d 100644
--- a/cogl/cogl/cogl-texture-2d.h
+++ b/cogl/cogl/cogl-texture-2d.h
@@ -218,6 +218,7 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
int width,
int height,
CoglPixelFormat format,
+ CoglTextureComponents components,
EGLImageKHR image,
GError **error);
diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h
index 1c251cc88..654adfd26 100644
--- a/cogl/cogl/cogl.h
+++ b/cogl/cogl/cogl.h
@@ -59,6 +59,7 @@
#include <cogl/cogl1-context.h>
#include <cogl/cogl-bitmap.h>
#include <cogl/cogl-color.h>
+#include <cogl/cogl-pixel-format-conversion.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-matrix-stack.h>
#include <cogl/cogl-offscreen.h>
@@ -108,6 +109,7 @@
#include <cogl/cogl-sub-texture.h>
#include <cogl/cogl-atlas-texture.h>
#include <cogl/cogl-meta-texture.h>
+#include <cogl/cogl-multi-plane-texture.h>
#include <cogl/cogl-primitive-texture.h>
#include <cogl/cogl-index-buffer.h>
#include <cogl/cogl-attribute-buffer.h>
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index 513fa9c77..23532fb3f 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -82,6 +82,7 @@ cogl_headers = [
'cogl-color.h',
'cogl-framebuffer.h',
'cogl-matrix.h',
+ 'cogl-multi-plane-texture.h',
'cogl-object.h',
'cogl-offscreen.h',
'cogl-onscreen.h',
@@ -322,6 +323,7 @@ cogl_sources = [
'cogl-atlas-texture-private.h',
'cogl-atlas-texture.c',
'cogl-meta-texture.c',
+ 'cogl-multi-plane-texture.c',
'cogl-primitive-texture.c',
'cogl-blit.h',
'cogl-blit.c',
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
index 9735c7605..220f3b141 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
@@ -800,6 +800,7 @@ _cogl_winsys_texture_pixmap_x11_create (CoglTexturePixmapX11 *tex_pixmap)
tex->width,
tex->height,
texture_format,
+ COGL_TEXTURE_COMPONENTS_RGBA,
egl_tex_pixmap->image,
NULL));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]