[mutter/wip/nielsdg/add-yuv-support] WIP
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/nielsdg/add-yuv-support] WIP
- Date: Wed, 28 Nov 2018 16:31:15 +0000 (UTC)
commit 529b87bc17cf26c701d9cb156977cae4f0e93a06
Author: Niels De Graef <Niels DeGraef barco com>
Date: Mon Nov 26 15:40:47 2018 +0100
WIP
cogl/cogl/Makefile.am | 3 +
cogl/cogl/cogl-colorspace-conversion.c | 163 +++++++++++++++++++++++++++++++++
cogl/cogl/cogl-colorspace-conversion.h | 92 +++++++++++++++++++
cogl/cogl/cogl-multi-plane-texture.c | 72 ---------------
cogl/cogl/cogl-multi-plane-texture.h | 26 +++---
cogl/cogl/cogl-types.h | 14 +++
cogl/cogl/cogl.c | 100 ++++++++++++++++++++
cogl/cogl/cogl.h | 1 +
cogl/cogl/meson.build | 6 +-
src/compositor/meta-shaped-texture.c | 37 ++++----
src/wayland/meta-wayland-buffer.c | 78 +++++++++++-----
src/wayland/meta-wayland.c | 7 +-
12 files changed, 467 insertions(+), 132 deletions(-)
---
diff --git a/cogl/cogl/Makefile.am b/cogl/cogl/Makefile.am
index e86aa2a37..85b85d2e4 100644
--- a/cogl/cogl/Makefile.am
+++ b/cogl/cogl/Makefile.am
@@ -62,6 +62,7 @@ cogl_1_public_h = \
cogl1-context.h \
cogl-bitmap.h \
cogl-color.h \
+ cogl-colorspace-conversion.h \
cogl-framebuffer.h \
cogl-matrix.h \
cogl-offscreen.h \
@@ -116,6 +117,7 @@ cogl_nonintrospected_h = \
cogl-error.h \
cogl-bitmap.h \
cogl-color.h \
+ cogl-colorspace-conversion.h \
cogl-matrix.h \
cogl-texture.h \
cogl-types.h \
@@ -238,6 +240,7 @@ cogl_sources_c = \
cogl-feature-private.c \
cogl-color-private.h \
cogl-color.c \
+ cogl-colorspace-conversion.c \
cogl-buffer-private.h \
cogl-buffer.c \
cogl-pixel-buffer-private.h \
diff --git a/cogl/cogl/cogl-colorspace-conversion.c b/cogl/cogl/cogl-colorspace-conversion.c
new file mode 100644
index 000000000..35d580bbe
--- /dev/null
+++ b/cogl/cogl/cogl-colorspace-conversion.c
@@ -0,0 +1,163 @@
+/*
+ * 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-colorspace-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) \
+ 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"
+
+static const gchar nv12_to_rgba_shader[] =
+ "vec4\n"
+ "cogl_nv12_to_rgba (vec2 UV)\n"
+ "{\n"
+ " vec4 color;\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";
+
+static const gchar yuv_to_rgba_shader[] =
+ "vec4\n"
+ "cogl_yuv_to_rgba (vec2 UV)\n"
+ "{\n"
+ " vec4 color;\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 _CoglColorspaceConversion
+{
+ CoglObject _parent;
+
+ CoglSnippet *vertex_declaration_snippet;
+ CoglSnippet *fragment_declaration_snippet;
+
+ CoglSnippet *fragment_execution_snippet;
+};
+
+static void
+_cogl_colorspace_conversion_free (CoglColorspaceConversion *self);
+
+COGL_OBJECT_DEFINE (ColorspaceConversion, colorspace_conversion);
+COGL_GTYPE_DEFINE_CLASS (ColorspaceConversion, colorspace_conversion);
+
+
+void
+cogl_colorspace_conversion_attach_to_pipeline (CoglColorspaceConversion *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 gchar *global_hook;
+ const gchar *layer_hook;
+
+ switch (format)
+ {
+ case COGL_PIXEL_FORMAT_YUV444:
+ 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 = nv12_to_rgba_shader;
+ layer_hook = "cogl_layer = cogl_nv12_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_colorspace_conversion_free (CoglColorspaceConversion *self)
+{
+ cogl_clear_object (&self->vertex_declaration_snippet);
+ cogl_clear_object (&self->fragment_declaration_snippet);
+ cogl_clear_object (&self->fragment_execution_snippet);
+}
+
+CoglColorspaceConversion *
+cogl_colorspace_conversion_new (CoglPixelFormat format)
+{
+ CoglColorspaceConversion *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 (CoglColorspaceConversion);
+ _cogl_colorspace_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-colorspace-conversion.h b/cogl/cogl/cogl-colorspace-conversion.h
new file mode 100644
index 000000000..9c421054d
--- /dev/null
+++ b/cogl/cogl/cogl-colorspace-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_COLORSPACE_CONVERSION_H__
+#define __COGL_COLORSPACE_CONVERSION_H__
+
+#include "cogl/cogl-types.h"
+#include "cogl/cogl-pipeline.h"
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION:cogl-color-space-conversion
+ * @title: CoglColorspaceConversion
+ * @short_description: A collection of snippets to handle colorspace 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 #CoglColorspaceConversion, 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 _CoglColorspaceConversion CoglColorspaceConversion;
+#define COGL_COLORSPACE_CONVERSION(ptr) ((CoglColorspaceConversion *) ptr)
+
+
+/**
+ * cogl_multiplane_texture_get_gtype:
+ *
+ * Returns: a #GType that can be used with the GLib type system.
+ */
+GType cogl_colorspace_conversion_get_gtype (void);
+
+/*
+ * cogl_is_colorspace_conversion:
+ * @object: A #CoglObject pointer
+ *
+ * Gets whether the given @object references an existing
+ * CoglColorspaceConversion.
+ *
+ * Return value: %TRUE if the @object references a #CoglColorspaceConversion,
+ * %FALSE otherwise
+ */
+gboolean
+cogl_is_colorspace_conversion (void *object);
+
+/**
+ * cogl_colorspace_conversion_new:
+ * @format: The input format
+ *
+ * Creates a #CoglColorspaceConversion to convert the given @formatro RGBA. If
+ * no such conversion is needed, it will return %NULL.
+ *
+ * Returns: (transfer full) (nullable): A new #CoglColorspaceConversion, or
+ * %NULL if none is needed.
+ */
+CoglColorspaceConversion * cogl_colorspace_conversion_new (CoglPixelFormat format);
+
+/**
+ * cogl_colorspace_conversion_attach_to_pipeline:
+ * @self: The #CoglColorspaceConversion 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_colorspace_conversion_attach_to_pipeline (CoglColorspaceConversion *self,
+ CoglPipeline *pipeline,
+ gint layer);
+
+G_END_DECLS
+
+#endif
diff --git a/cogl/cogl/cogl-multi-plane-texture.c b/cogl/cogl/cogl-multi-plane-texture.c
index f02d1b983..8d297258d 100644
--- a/cogl/cogl/cogl-multi-plane-texture.c
+++ b/cogl/cogl/cogl-multi-plane-texture.c
@@ -23,38 +23,6 @@
#include "cogl-multi-plane-texture.h"
#include "cogl-gtype-private.h"
-#define _COGL_YUV_TO_RGBA(res, y, u, v) \
- 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"
-
-static const gchar nv12_to_rgba_shader[] =
- "vec4\n"
- "cogl_nv12_to_rgba (vec2 UV)\n"
- "{\n"
- " vec4 color;\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";
-
-static const gchar yuv_to_rgba_shader[] =
- "vec4\n"
- "cogl_yuv_to_rgba (vec2 UV)\n"
- "{\n"
- " vec4 color;\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 _CoglMultiPlaneTexture
{
CoglObject _parent;
@@ -115,46 +83,6 @@ cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self)
return cogl_texture_get_height (self->planes[0]);
}
-void
-cogl_multi_plane_texture_create_color_conversion_snippets (CoglMultiPlaneTexture *self,
- CoglSnippet **vertex_snippet_out,
- CoglSnippet **fragment_snippet_out,
- CoglSnippet **layer_snippet_out)
-{
- const gchar *global_hook;
- const gchar *layer_hook;
-
- switch (self->format)
- {
- case COGL_PIXEL_FORMAT_YUV444:
- 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 = nv12_to_rgba_shader;
- layer_hook = "cogl_layer = cogl_nv12_to_rgba(cogl_tex_coord0_in.st);\n";
- break;
- default:
- *vertex_snippet_out = NULL;
- *fragment_snippet_out = NULL;
- *layer_snippet_out = NULL;
- return;
- }
-
- *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);
-}
-
static void
_cogl_multi_plane_texture_free (CoglMultiPlaneTexture *self)
{
diff --git a/cogl/cogl/cogl-multi-plane-texture.h b/cogl/cogl/cogl-multi-plane-texture.h
index aa5fc6d77..c4b3aed31 100644
--- a/cogl/cogl/cogl-multi-plane-texture.h
+++ b/cogl/cogl/cogl-multi-plane-texture.h
@@ -52,12 +52,24 @@ typedef struct _CoglMultiPlaneTexture CoglMultiPlaneTexture;
/**
- * cogl_multiplane_texture_get_gtype:
+ * 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
@@ -159,18 +171,6 @@ guint cogl_multi_plane_texture_get_width (CoglMultiPlaneTexture *se
*/
guint cogl_multi_plane_texture_get_height (CoglMultiPlaneTexture *self);
-/**
- * cogl_multi_plane_texture_create_color_conversion_snippets:
- *
- * Creates a trio of #CoglSnippets that allow you to use this texture inside
- * your pipeline. If no such shader is needed (e.g. because you already have
- * a single-plane RGBA texture), then they will be set to %NULL.
- */
-void cogl_multi_plane_texture_create_color_conversion_snippets (CoglMultiPlaneTexture *self,
- CoglSnippet **vertex_snippet_out,
- CoglSnippet **fragment_snippet_out,
- CoglSnippet **layer_snippet_out);
-
G_END_DECLS
#endif
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index 7e3c2a971..195a5cd3b 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -408,6 +408,7 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
/**
* 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.
*/
@@ -416,6 +417,7 @@ 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.
*/
@@ -424,6 +426,18 @@ cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format,
guint *horizontal_factors,
guint *vertical_factors);
+void
+cogl_pixel_format_get_bits_per_pixel (CoglPixelFormat format, guint *bpp_out);
+
+/**
+ * cogl_pixel_format_get_components:
+ *
+ * XXX make some comments here about (consistently) uploading multiple textures
+ */
+/* void */
+/* cogl_pixel_format_get_texture_components (CoglPixelFormat format, */
+/* CoglTextureComponents *components_out); */
+
/**
* CoglFeatureFlags:
* @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support
diff --git a/cogl/cogl/cogl.c b/cogl/cogl/cogl.c
index 964026180..01ca70769 100644
--- a/cogl/cogl/cogl.c
+++ b/cogl/cogl/cogl.c
@@ -796,6 +796,43 @@ _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format)
return bpp_lut [format & 0xf];
}
+/*
+ * XXX document.
+ *
+ * XXX lol, this is even per macropixel, not per pixel :D
+ */
+void
+cogl_pixel_format_get_bits_per_pixel (CoglPixelFormat format, guint *bpp_out)
+{
+ /* "old" formats */
+ if (format & (0xff << 24))
+ {
+ switch (format)
+ {
+ case COGL_PIXEL_FORMAT_NV12:
+ case COGL_PIXEL_FORMAT_NV21:
+ bpp_out[0] = 8;
+ bpp_out[1] = 4;
+ break;
+ case COGL_PIXEL_FORMAT_YUV420:
+ case COGL_PIXEL_FORMAT_YVU420:
+ bpp_out[0] = 8;
+ bpp_out[1] = 2;
+ bpp_out[2] = 2;
+ break;
+ }
+ }
+ else
+ {
+ int bpp_lut[] = { 0, 1, 3, 4,
+ 2, 2, 2, 0,
+ 1, 2, 0, 0,
+ 3, 4, 0, 0 };
+
+ bpp_out[0] = 8 * bpp_lut [format & 0xf];
+ }
+}
+
/* Note: this also refers to the mapping defined above for
* _cogl_pixel_format_get_bytes_per_pixel() */
CoglBool
@@ -939,3 +976,66 @@ cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format,
break;
}
}
+
+/* void */
+/* cogl_pixel_format_get_texture_components (CoglPixelFormat format, */
+/* CoglTextureComponents *components_out) */
+/* { */
+/* /1* Check for Pre-YUV formats *1/ */
+/* if (format & 0xf000) */
+/* { */
+/* switch (format) */
+/* { */
+/* /1* 2 planes *1/ */
+/* case COGL_PIXEL_FORMAT_NV12: */
+/* case COGL_PIXEL_FORMAT_NV21: */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_R; */
+/* components_out[1] = COGL_TEXTURE_COMPONENTS_RG; */
+/* break; */
+
+/* /1* XXX TODO *1/ */
+/* /1* case COGL_PIXEL_FORMAT_XRGB88888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_XBGR88888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_RGBX88888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_BGRX88888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_RGB888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_BGR888_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_RGB565_A8: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_BGR565_A8: *1/ */
+
+/* /1* /2* 3 planes *2/ *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YUV410: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YVU410: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YUV411: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YVU411: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YUV420: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YVU420: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YUV422: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YVU422: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YUV444: *1/ */
+/* /1* case COGL_PIXEL_FORMAT_YVU444: *1/ */
+
+/* default: */
+/* /1* XXX At this point, we might crash 'n burn *1/ */
+/* g_assert_not_reached (); */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_RGB; */
+/* break; */
+/* } */
+/* } */
+/* else */
+/* { */
+/* if (format == COGL_PIXEL_FORMAT_ANY) */
+/* format = COGL_PIXEL_FORMAT_RGBA_8888_PRE; */
+
+/* if (format == COGL_PIXEL_FORMAT_A_8) */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_A; */
+/* else if (format == COGL_PIXEL_FORMAT_RG_88) */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_RG; */
+/* else if (format & COGL_DEPTH_BIT) */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_DEPTH; */
+/* else if (format & COGL_A_BIT) */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA; */
+/* else */
+/* components_out[0] = COGL_TEXTURE_COMPONENTS_RGB; */
+/* } */
+/* } */
diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h
index 84595b595..41c785627 100644
--- a/cogl/cogl/cogl.h
+++ b/cogl/cogl/cogl.h
@@ -61,6 +61,7 @@
#include <cogl/cogl1-context.h>
#include <cogl/cogl-bitmap.h>
#include <cogl/cogl-color.h>
+#include <cogl/cogl-colorspace-conversion.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-matrix-stack.h>
#include <cogl/cogl-offscreen.h>
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index 76a42442b..664ee9908 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -79,6 +79,7 @@ cogl_headers = [
'cogl1-context.h',
'cogl-bitmap.h',
'cogl-color.h',
+ 'cogl-colorspace-conversion.h',
'cogl-framebuffer.h',
'cogl-matrix.h',
'cogl-object.h',
@@ -250,10 +251,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-colorspace-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/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 546c58461..939e2e455 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -94,6 +94,8 @@ struct _MetaShapedTexturePrivate
CoglPipeline *masked_pipeline;
CoglPipeline *unblended_pipeline;
+ CoglColorspaceConversion *colorspace_conversion;
+
gboolean is_y_inverted;
/* The region containing only fully opaque pixels */
@@ -220,7 +222,8 @@ meta_shaped_texture_dispose (GObject *object)
meta_texture_tower_free (priv->paint_tower);
priv->paint_tower = NULL;
- g_clear_object (&priv->texture);
+ cogl_clear_object (&priv->colorspace_conversion);
+ cogl_clear_object (&priv->texture);
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
meta_shaped_texture_set_mask_texture (self, NULL);
@@ -361,32 +364,26 @@ static void
check_texture_color_format (MetaShapedTexture *self,
CoglMultiPlaneTexture *texture)
{
+ MetaShapedTexturePrivate *priv = self->priv;
CoglPixelFormat format = cogl_multi_plane_texture_get_format (texture);
- static CoglSnippet *func1 = NULL, *func2 = NULL, *snippet3 = NULL;
- guint n_layers = 0;
+ guint n_layers = cogl_pipeline_get_n_layers (priv->base_pipeline);
- n_layers = cogl_pipeline_get_n_layers (self->priv->base_pipeline);
-
- if (func1 != NULL)
+ if (priv->colorspace_conversion != NULL)
return;
- cogl_multi_plane_texture_create_color_conversion_snippets (texture,
- &func1,
- &func2,
- &snippet3);
+ cogl_clear_object (&priv->colorspace_conversion);
+ priv->colorspace_conversion = cogl_colorspace_conversion_new (format);
- /* Check if a snippet is actually necessary */
- if (func1 != NULL)
- {
- cogl_pipeline_add_snippet (self->priv->base_pipeline, func1);
- cogl_pipeline_add_snippet (self->priv->base_pipeline, func2);
- meta_shaped_texture_set_create_mipmaps (self, FALSE);
+ /* Check if a snippet is actually necessary */
+ if (priv->colorspace_conversion == NULL)
+ return;
- cogl_pipeline_add_layer_snippet (self->priv->base_pipeline,
- n_layers - 1,
- snippet3);
- }
+ /* XXX disable for now, our changes are still incompatible with texturetower*/
+ meta_shaped_texture_set_create_mipmaps (self, FALSE);
+ cogl_colorspace_conversion_attach_to_pipeline (priv->colorspace_conversion,
+ priv->base_pipeline,
+ n_layers - 1);
}
static void
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index 263826151..3e247dacf 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -163,7 +163,6 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
CoglTextureComponents *components_out)
{
CoglPixelFormat format;
- CoglTextureComponents components = COGL_TEXTURE_COMPONENTS_RGBA;
g_warning ("SHM BUFFER_FORMAT: %d", wl_shm_buffer_get_format (shm_buffer));
switch (wl_shm_buffer_get_format (shm_buffer))
@@ -171,10 +170,11 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_ARGB_8888;
- components = COGL_TEXTURE_COMPONENTS_RGB;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
@@ -182,38 +182,52 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
- components = COGL_TEXTURE_COMPONENTS_RGB;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGB;
break;
#endif
case WL_SHM_FORMAT_NV12:
format = COGL_PIXEL_FORMAT_NV12;
- g_warning ("FORMAT IS NV12");
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
break;
case WL_SHM_FORMAT_NV21:
- g_warning ("FORMAT IS NV21");
+ format = COGL_PIXEL_FORMAT_NV21;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_RG;
break;
case WL_SHM_FORMAT_YUV422:
- g_warning ("FORMAT IS YUV422");
+ format = COGL_PIXEL_FORMAT_YUV422;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
break;
case WL_SHM_FORMAT_YVU422:
- g_warning ("FORMAT IS YVU422");
+ format = COGL_PIXEL_FORMAT_YVU422;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
break;
case WL_SHM_FORMAT_YUV444:
- g_warning ("FORMAT IS YUV444");
+ format = COGL_PIXEL_FORMAT_YUV444;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
break;
case WL_SHM_FORMAT_YVU444:
- g_warning ("FORMAT IS YVU444");
+ format = COGL_PIXEL_FORMAT_YVU444;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[1] = COGL_TEXTURE_COMPONENTS_A;
+ components_out[2] = COGL_TEXTURE_COMPONENTS_A;
break;
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
}
if (format_out)
*format_out = format;
- if (components_out)
- *components_out = components;
}
static gboolean
@@ -226,7 +240,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
struct wl_shm_buffer *shm_buffer;
int stride, width, height;
CoglPixelFormat format;
- CoglTextureComponents components;
+ CoglTextureComponents components[3];
guint i, n_planes;
guint h_factors[3], v_factors[3];
gsize offset = 0;
@@ -243,7 +257,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
width = wl_shm_buffer_get_width (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
- shm_buffer_get_cogl_pixel_format (shm_buffer, &format, &components);
+ shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
n_planes = cogl_pixel_format_get_n_planes (format);
cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
@@ -252,6 +266,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
data = wl_shm_buffer_get_data (shm_buffer);
planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
+ g_warning ("Attaching SHM buffer");
for (i = 0; i < n_planes; i++)
{
CoglBitmap *bitmap;
@@ -265,16 +280,19 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
else
offset += (stride / h_factors[i-1]) * (height / v_factors[i-1]);
+ g_warning ("Creating plane %d, h_factor = %d, v_factor = %d, offset = %d", i, h_factors[i],
v_factors[i], offset);
+
bitmap = cogl_bitmap_new_for_data (cogl_context,
width / h_factors[i],
height / v_factors[i],
+ /* COGL_PIXEL_FORMAT_ARGB_8888, */
format,
stride, /* XXX Do we need to change this too?*/
data + offset);
g_assert (bitmap);
plane = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmap));
- cogl_texture_set_components (COGL_TEXTURE (plane), components);
+ cogl_texture_set_components (COGL_TEXTURE (plane), components[i]);
cogl_object_unref (bitmap);
@@ -507,35 +525,47 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
struct wl_shm_buffer *shm_buffer;
int i, n_rectangles;
gboolean set_texture_failed = FALSE;
+ CoglPixelFormat format;
+ CoglTextureComponents components[3];
+ guint bpp[3];
+ guint h_factors[3], v_factors[3];
+ guint n_planes = cogl_multi_plane_texture_get_n_planes (buffer->texture);
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, components);
+ /* XXX */
+ cogl_pixel_format_get_bits_per_pixel (format, bpp);
+ cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
+ /* XXX manually overwriting format */
+ /* format = COGL_PIXEL_FORMAT_ARGB_8888; */
+
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;
- guint n_planes;
- int bpp;
cairo_rectangle_int_t rect;
- shm_buffer_get_cogl_pixel_format (shm_buffer, &format, NULL);
- /* XXX */
- bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
cairo_region_get_rectangle (region, i, &rect);
- for (i = 0; i < cogl_multi_plane_texture_get_n_planes (buffer->texture); i++)
+ for (i = 0; i < n_planes; i++)
{
- CoglTexture *plane = cogl_multi_plane_texture_get_plane (buffer->texture, i);
+ CoglTexture *plane;
+ guint offset = ((guint) (rect.x * bpp[i] / 8.0)) + rect.y * stride;
+
+ plane = cogl_multi_plane_texture_get_plane (buffer->texture, i);
+
+ g_warning ("Creating plane %d, h_factor = %d, v_factor = %d, offset = %d, bpp = %d", i, h_factors[i],
v_factors[i], offset, bpp[i]);
if (!_cogl_texture_set_region (plane,
- rect.width, rect.height,
+ rect.width / h_factors[i],
+ rect.height / v_factors[i],
format,
stride,
- data + rect.x * bpp + rect.y * stride,
+ data + offset,
rect.x, rect.y,
0,
error))
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index d2436d6b6..8c5c60d5c 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -319,7 +319,12 @@ add_supported_shm_formats (struct wl_display *display)
/* Note that a Wayland compositor should support WL_SHM_FORMAT_ARGB8888 and
* WL_SHM_FORMAT_XRGB8888 by default, so no need to add it here. */
static const guint32 SUPPORTED_FORMATS[] = {
- WL_SHM_FORMAT_NV12
+ WL_SHM_FORMAT_NV12,
+ WL_SHM_FORMAT_NV21,
+ WL_SHM_FORMAT_YUV422,
+ WL_SHM_FORMAT_YVU422,
+ WL_SHM_FORMAT_YUV444,
+ WL_SHM_FORMAT_YVU444
};
for (i = 0; i < G_N_ELEMENTS (SUPPORTED_FORMATS); i++)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]