[mutter/wip/nielsdg/add-yuv-support: 47/48] WIP: add YUV support
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/nielsdg/add-yuv-support: 47/48] WIP: add YUV support
- Date: Tue, 20 Nov 2018 14:27:16 +0000 (UTC)
commit 3988e2681c6766a9cba81b922e7afb6fd0e7bbe3
Author: Niels De Graef <Niels DeGraef barco com>
Date: Wed Nov 14 12:22:02 2018 +0100
WIP: add YUV support
cogl/cogl/cogl-bitmap-conversion.c | 1 +
cogl/cogl/cogl-types.h | 4 +-
cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 4 +
cogl/cogl/driver/gl/gl/cogl-driver-gl.c | 3 +
cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c | 6 +
cogl/cogl/driver/gl/gles/cogl-driver-gles.c | 3 +
src/Makefile.am | 1 +
src/compositor/meta-planar-texture.c | 149 +++++++++++++++
src/compositor/meta-planar-texture.h | 66 +++++++
src/compositor/meta-shaped-texture-private.h | 3 +-
src/compositor/meta-shaped-texture.c | 229 +++++++++++++++++++-----
src/meson.build | 1 +
src/wayland/meta-wayland-buffer.c | 91 +++++++---
src/wayland/meta-wayland-buffer.h | 5 +-
src/wayland/meta-wayland-shell-surface.c | 6 +-
src/wayland/meta-wayland-surface.c | 10 +-
16 files changed, 499 insertions(+), 83 deletions(-)
---
diff --git a/cogl/cogl/cogl-bitmap-conversion.c b/cogl/cogl/cogl-bitmap-conversion.c
index 9d20a47df..fcd6a38f2 100644
--- a/cogl/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl/cogl-bitmap-conversion.c
@@ -321,6 +321,7 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
+ case COGL_PIXEL_FORMAT_Y_UV:
g_assert_not_reached ();
case COGL_PIXEL_FORMAT_A_8:
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index b351cfd2d..81643bd88 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -353,7 +353,9 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
- COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
+ COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT),
+
+ COGL_PIXEL_FORMAT_Y_UV = 14 /* NV12 */
} CoglPixelFormat;
/**
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
index ba90998ba..957e20761 100644
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -209,6 +209,8 @@ allocate_from_bitmap (CoglTexture2D *tex_2d,
GLenum gl_format;
GLenum gl_type;
+ g_warning ("allocate_from_bitmap()");
+
internal_format =
_cogl_texture_determine_internal_format (tex, cogl_bitmap_get_format (bmp));
@@ -349,6 +351,8 @@ allocate_from_gl_foreign (CoglTexture2D *tex_2d,
GLint gl_compressed = GL_FALSE;
GLenum gl_int_format = 0;
+ g_warning ("allocate_from_egl_image_foreign()");
+
if (!ctx->texture_driver->allows_foreign_gl_target (ctx, GL_TEXTURE_2D))
{
_cogl_set_error (error,
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
index f7454aa07..d627dddf7 100644
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -108,6 +108,9 @@ _cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
required_format = format;
+ if (format == COGL_PIXEL_FORMAT_Y_UV)
+ g_warning ("cogl-driver-gl: GOT NV12!!");
+
/* Find GL equivalents */
switch (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 dc3c98ba2..e053f5e0e 100644
--- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
@@ -99,6 +99,8 @@ _cogl_texture_driver_gen (CoglContext *ctx,
g_assert_not_reached();
}
+ g_warning ("_cogl_texture_driver_gen %d", internal_format);
+
/* If the driver doesn't support alpha textures directly then we'll
* fake them by setting the swizzle parameters */
if (internal_format == COGL_PIXEL_FORMAT_A_8 &&
@@ -222,6 +224,8 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx,
int level_width;
int level_height;
+ g_warning ("uploading subregion to gl");
+
cogl_texture_get_gl_texture (texture, &gl_handle, &gl_target);
data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, &internal_error);
@@ -326,6 +330,8 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx,
CoglBool status = TRUE;
CoglError *internal_error = NULL;
+ g_warning ("uploading to gl");
+
data = _cogl_bitmap_gl_bind (source_bmp,
COGL_BUFFER_ACCESS_READ,
0, /* hints */
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
index cc20a0bd6..fa2e43f82 100644
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -79,6 +79,9 @@ _cogl_driver_pixel_format_to_gl_with_target (CoglContext *context,
required_format = format;
+ if (format == COGL_PIXEL_FORMAT_Y_UV)
+ g_warning ("cogl-driver-gles: GOT NV12!!");
+
/* Find GL equivalents */
switch (format)
{
diff --git a/src/Makefile.am b/src/Makefile.am
index b4f22de0d..12d565740 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -243,6 +243,7 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
compositor/meta-feedback-actor-private.h \
compositor/meta-module.c \
compositor/meta-module.h \
+ compositor/meta-planar-texture.c \
compositor/meta-plugin.c \
compositor/meta-plugin-manager.c \
compositor/meta-plugin-manager.h \
diff --git a/src/compositor/meta-planar-texture.c b/src/compositor/meta-planar-texture.c
new file mode 100644
index 000000000..36f0214cc
--- /dev/null
+++ b/src/compositor/meta-planar-texture.c
@@ -0,0 +1,149 @@
+/*
+ * 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-planar-texture
+ * @title: MetaPlanarTexture
+ * @short_description: A texture that can have multiple planes (e.g. Y, U, V).
+ */
+
+#include "config.h"
+#include "meta-planar-texture.h"
+
+struct _MetaPlanarTexture
+{
+ GObject parent;
+
+ CoglPixelFormat format;
+
+ guint n_planes;
+ CoglTexture **planes;
+};
+
+G_DEFINE_TYPE (MetaPlanarTexture, meta_planar_texture, G_TYPE_OBJECT);
+
+
+CoglPixelFormat
+meta_planar_texture_get_format (MetaPlanarTexture *self)
+{
+ return self->format;
+}
+
+guint
+meta_planar_texture_get_n_planes (MetaPlanarTexture *self)
+{
+ return self->n_planes;
+}
+
+CoglTexture *
+meta_planar_texture_get_plane (MetaPlanarTexture *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 **
+meta_planar_texture_get_planes (MetaPlanarTexture *self)
+{
+ return self->planes;
+}
+
+guint
+meta_planar_texture_get_width (MetaPlanarTexture *self)
+{
+ g_return_val_if_fail (self->n_planes > 0, 0);
+
+ return cogl_texture_get_width (self->planes[0]);
+}
+
+guint
+meta_planar_texture_get_height (MetaPlanarTexture *self)
+{
+ g_return_val_if_fail (self->n_planes > 0, 0);
+
+ return cogl_texture_get_height (self->planes[0]);
+}
+
+static void
+meta_planar_texture_finalize (GObject *object)
+{
+ MetaPlanarTexture *self = META_PLANAR_TEXTURE (object);
+
+ g_free (self->planes);
+ /* XXX do we need to unref the CoglTextures as well here? */
+}
+
+static void
+meta_planar_texture_class_init (MetaPlanarTextureClass *klass)
+{
+ GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
+
+ gobj_class->finalize = meta_planar_texture_finalize;
+}
+
+static void
+meta_planar_texture_init (MetaPlanarTexture *self)
+{
+ self->format = COGL_PIXEL_FORMAT_ANY;
+ self->n_planes = 0;
+ self->planes = NULL;
+}
+
+/**
+ * meta_planar_texture_new:
+ * @format: The format of the #MetaPlanarTexture
+ * @planes: (transfer full): The actual planes of the texture
+ * @n_planes: The number of planes
+ *
+ * Creates a #MetaPlanarTexture with the given @format. Each of the
+ * #CoglTexture<!-- -->s represents a plane.
+ */
+MetaPlanarTexture *
+meta_planar_texture_new (CoglPixelFormat format,
+ CoglTexture **planes, guint n_planes)
+{
+ MetaPlanarTexture *self = g_object_new (META_TYPE_PLANAR_TEXTURE, NULL);
+
+ self->format = format;
+ self->n_planes = n_planes;
+ self->planes = planes;
+
+ return self;
+}
+
+/**
+ * _cogl_pixel_format_get_n_planes:
+ *
+ * Returns the number of planes the given CoglPixelFormat specifies.
+ */
+guint
+_cogl_pixel_format_get_n_planes (CoglPixelFormat format)
+{
+ switch (format)
+ {
+ case COGL_PIXEL_FORMAT_Y_UV:
+ return 2;
+ default:
+ return 1;
+ }
+
+ g_assert_not_reached ();
+}
diff --git a/src/compositor/meta-planar-texture.h b/src/compositor/meta-planar-texture.h
new file mode 100644
index 000000000..616be2781
--- /dev/null
+++ b/src/compositor/meta-planar-texture.h
@@ -0,0 +1,66 @@
+/*
+ * 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_PLANAR_TEXTURE_H__
+#define __META_PLANAR_TEXTURE_H__
+
+#include "cogl/cogl.h"
+
+G_BEGIN_DECLS
+
+#define META_TYPE_PLANAR_TEXTURE (meta_planar_texture_get_type())
+G_DECLARE_FINAL_TYPE (MetaPlanarTexture,
+ meta_planar_texture,
+ META, PLANAR_TEXTURE,
+ GObject)
+
+
+MetaPlanarTexture * meta_planar_texture_new (CoglPixelFormat format,
+ CoglTexture **planes,
+ guint n_planes);
+
+
+CoglPixelFormat meta_planar_texture_get_format (MetaPlanarTexture *self);
+
+guint meta_planar_texture_get_n_planes (MetaPlanarTexture *self);
+
+CoglTexture * meta_planar_texture_get_plane (MetaPlanarTexture *self,
+ guint index);
+
+CoglTexture ** meta_planar_texture_get_planes (MetaPlanarTexture *self);
+
+guint meta_planar_texture_get_width (MetaPlanarTexture *self);
+
+guint meta_planar_texture_get_height (MetaPlanarTexture *self);
+
+/**
+ * _cogl_pixel_format_get_n_planes:
+ * @format: a #CoglPixelFormat
+ *
+ * Returns the number of planes the given CoglPixelFormat specifies.
+ */
+guint
+_cogl_pixel_format_get_n_planes (CoglPixelFormat format);
+
+
+G_END_DECLS
+
+#endif
diff --git a/src/compositor/meta-shaped-texture-private.h b/src/compositor/meta-shaped-texture-private.h
index 284f43e36..4ee61c6bb 100644
--- a/src/compositor/meta-shaped-texture-private.h
+++ b/src/compositor/meta-shaped-texture-private.h
@@ -28,10 +28,11 @@
#define __META_SHAPED_TEXTURE_PRIVATE_H__
#include "meta/meta-shaped-texture.h"
+#include "compositor/meta-planar-texture.h"
ClutterActor *meta_shaped_texture_new (void);
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture);
+ MetaPlanarTexture *texture);
void meta_shaped_texture_set_is_y_inverted (MetaShapedTexture *stex,
gboolean is_y_inverted);
void meta_shaped_texture_set_snippet (MetaShapedTexture *stex,
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 919e7a9b5..fb1b7a4af 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -86,7 +86,7 @@ struct _MetaShapedTexturePrivate
{
MetaTextureTower *paint_tower;
- CoglTexture *texture;
+ MetaPlanarTexture *texture;
CoglTexture *mask_texture;
CoglSnippet *snippet;
@@ -239,19 +239,20 @@ get_base_pipeline (MetaShapedTexture *stex,
{
MetaShapedTexturePrivate *priv = stex->priv;
CoglPipeline *pipeline;
+ guint i = 0;
if (priv->base_pipeline)
return priv->base_pipeline;
pipeline = cogl_pipeline_new (ctx);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 0,
+ for (i = 0; i < meta_planar_texture_get_n_planes (priv->texture); i++)
+ {
+ cogl_pipeline_set_layer_wrap_mode_s (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 0,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_s (pipeline, 1,
- COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
- cogl_pipeline_set_layer_wrap_mode_t (pipeline, 1,
+ cogl_pipeline_set_layer_wrap_mode_t (pipeline, i,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
+ }
+ g_warning ("is_y_inverted = %d", priv->is_y_inverted);
if (!priv->is_y_inverted)
{
CoglMatrix matrix;
@@ -262,8 +263,8 @@ get_base_pipeline (MetaShapedTexture *stex,
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
}
- if (priv->snippet)
- cogl_pipeline_add_layer_snippet (pipeline, 0, priv->snippet);
+ /* if (priv->snippet) */
+ /* cogl_pipeline_add_layer_snippet (pipeline, 0, priv->snippet); */
priv->base_pipeline = pipeline;
@@ -283,14 +284,20 @@ get_masked_pipeline (MetaShapedTexture *stex,
{
MetaShapedTexturePrivate *priv = stex->priv;
CoglPipeline *pipeline;
+ gint i, n_layers = 0;
if (priv->masked_pipeline)
return priv->masked_pipeline;
pipeline = cogl_pipeline_copy (get_base_pipeline (stex, ctx));
- cogl_pipeline_set_layer_combine (pipeline, 1,
- "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
- NULL);
+ n_layers = meta_planar_texture_get_n_planes (pipeline);
+ /* for (i = 0; i < n_layers; i++) */
+ /* { */
+ /* cogl_pipeline_set_layer_combine (pipeline, i, */
+ /* "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", */
+ /* /1* "RGBA = REPLACE (PREVIOUS)", *1/ */
+ /* NULL); */
+ /* } */
priv->masked_pipeline = pipeline;
@@ -350,8 +357,85 @@ paint_clipped_rectangle (CoglFramebuffer *fb,
}
static void
-set_cogl_texture (MetaShapedTexture *stex,
- CoglTexture *cogl_tex)
+check_texture_color_format (MetaShapedTexture *self,
+ MetaPlanarTexture *texture)
+{
+ CoglPixelFormat format = meta_planar_texture_get_format (texture);
+ /* CoglSnippet *snippet1, *snippet2, *snippet3 = NULL; */
+ static CoglSnippet *func_snippet = NULL;
+ static CoglSnippet *snippet3 = NULL;
+ /* static gboolean snippet_set = FALSE; */
+ /* gint i = 0; */
+ gint n_layers = 0;
+
+ n_layers = cogl_pipeline_get_n_layers (self->priv->base_pipeline);
+
+ if (func_snippet == NULL)
+ {
+ /* CoglGstVideoSink version */
+ /* XXX are we using Y_UV or Y_xUxV? Maybe check for RG support? */
+ const gchar *func_snippet_str =
+ "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"
+
+ " color.r = y + 1.59765625 * v;\n"
+ /* " color.r = 0.0;\n" */
+ " color.g = y - 0.390625 * u - 0.8125 * v;\n"
+ /* " color.g = 0.0;\n" */
+ " color.b = y + 2.015625 * u;\n"
+ /* " color.b = 0.0;\n" */
+ " color.a = 1.0;\n"
+ /* " color = vec4 (y, u, u, 1.0);\n" */
+
+ " return color;\n"
+ "}\n";
+
+ func_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_GLOBALS,
+ func_snippet_str,
+ NULL);
+ cogl_pipeline_add_snippet (self->priv->base_pipeline, func_snippet);
+
+ func_snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT_GLOBALS,
+ func_snippet_str,
+ NULL);
+ cogl_pipeline_add_snippet (self->priv->base_pipeline, func_snippet);
+ }
+
+ if (snippet3 == NULL)
+ {
+ snippet3 = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
+ NULL,
+ "cogl_layer = cogl_nv12_to_rgba(cogl_tex_coord0_in.st);\n");
+ }
+
+ switch (format)
+ {
+ case COGL_PIXEL_FORMAT_Y_UV:
+ g_warning ("got a MetaShapedTexture with pixel format NV12!");
+ meta_shaped_texture_set_create_mipmaps (self, FALSE);
+
+ cogl_pipeline_add_layer_snippet (self->priv->base_pipeline, 0, snippet3);
+ cogl_pipeline_add_layer_snippet (self->priv->base_pipeline, 1, snippet3);
+
+ break;
+ default:
+ g_info ("normal pixel format");
+ /* do nothing */
+ break;
+ }
+}
+
+static void
+set_planar_texture (MetaShapedTexture *stex,
+ MetaPlanarTexture *planar_tex)
{
MetaShapedTexturePrivate *priv;
int width, height;
@@ -360,16 +444,14 @@ set_cogl_texture (MetaShapedTexture *stex,
priv = stex->priv;
- if (priv->texture)
- cogl_object_unref (priv->texture);
-
- priv->texture = cogl_tex;
+ g_clear_object (&priv->texture);
+ priv->texture = planar_tex;
- if (cogl_tex != NULL)
+ if (planar_tex != NULL)
{
- cogl_object_ref (cogl_tex);
- width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
- height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
+ g_object_ref (planar_tex);
+ width = meta_planar_texture_get_width (planar_tex);
+ height = meta_planar_texture_get_height (planar_tex);
}
else
{
@@ -377,6 +459,7 @@ set_cogl_texture (MetaShapedTexture *stex,
height = 0;
}
+ /* Do we have a different size? */
if (priv->tex_width != width ||
priv->tex_height != height)
{
@@ -387,13 +470,24 @@ set_cogl_texture (MetaShapedTexture *stex,
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
}
+ /* Check if we need to do color conversion to RGBA */
+ if (planar_tex != NULL && priv->base_pipeline != NULL)
+ {
+ check_texture_color_format (stex, planar_tex);
+ }
+
/* NB: We don't queue a redraw of the actor here because we don't
* know how much of the buffer has changed with respect to the
* previous buffer. We only queue a redraw in response to surface
* damage. */
- if (priv->create_mipmaps)
- meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
+ if (FALSE)
+ /* if (priv->create_mipmaps) */
+ {
+ /* XXX */
+ CoglTexture *cogl_tex = meta_planar_texture_get_plane (planar_tex, 0);
+ meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
+ }
}
static gboolean
@@ -426,13 +520,14 @@ meta_shaped_texture_paint (ClutterActor *actor)
cairo_region_t *blended_tex_region;
CoglContext *ctx;
CoglFramebuffer *fb;
- CoglTexture *paint_tex = NULL;
+ MetaPlanarTexture *paint_tex = NULL;
+ guint n_planes;
ClutterActorBox alloc;
CoglPipelineFilter filter;
gint64 now = g_get_monotonic_time ();
- if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
- return;
+ /* if (priv->clip_region && cairo_region_is_empty (priv->clip_region)) */
+ /* return; */
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
clutter_actor_realize (CLUTTER_ACTOR (stex));
@@ -452,7 +547,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
* Setting the texture quality to high without SGIS_generate_mipmap
* support for TFP textures will result in fallbacks to XGetImage.
*/
- if (priv->create_mipmaps && priv->last_invalidation)
+ if (FALSE)
+ /* if (priv->create_mipmaps && priv->last_invalidation) */
{
gint64 age = now - priv->last_invalidation;
@@ -463,12 +559,13 @@ meta_shaped_texture_paint (ClutterActor *actor)
if (paint_tex == NULL)
{
- paint_tex = COGL_TEXTURE (priv->texture);
+ paint_tex = priv->texture;
if (paint_tex == NULL)
return;
- if (priv->create_mipmaps)
+ if (FALSE)
+ /* if (priv->create_mipmaps) */
{
/* Minus 1000 to ensure we don't fail the age test in timeout */
priv->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
@@ -481,6 +578,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
}
}
+ n_planes = meta_planar_texture_get_n_planes (paint_tex);
+
clutter_actor_get_scale (actor, &tex_scale, NULL);
tex_width = priv->tex_width;
tex_height = priv->tex_height;
@@ -585,8 +684,21 @@ meta_shaped_texture_paint (ClutterActor *actor)
if (!cairo_region_is_empty (region))
{
opaque_pipeline = get_unblended_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
+ g_warning ("Unblended pipeline: adding %d layers", n_planes);
+ for (i = 0; i < n_planes; i++)
+ {
+ CoglTexture *plane = meta_planar_texture_get_plane (paint_tex, i);
+
+
+ cogl_pipeline_set_layer_texture (opaque_pipeline, i, plane);
+ /* cogl_pipeline_set_layer_filters (opaque_pipeline, i, filter, filter); */
+ }
+ cogl_pipeline_set_layer_combine (opaque_pipeline, n_planes,
+ /* "RGB=MODULATE(PREVIOUS, TEXTURE_0[A])\n" */
+ /* "A=REPLACE(PREVIOUS[A])", */
+ /* "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", */
+ "RGBA = REPLACE (PREVIOUS)",
+ NULL);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@@ -613,20 +725,35 @@ meta_shaped_texture_paint (ClutterActor *actor)
if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
{
CoglPipeline *blended_pipeline;
+ guint i;
if (priv->mask_texture == NULL)
{
blended_pipeline = get_unmasked_pipeline (stex, ctx);
+ g_warning ("blended_pipeline = get_unmasked_pipeline (stex, ctx);");
}
else
{
+ g_warning ("blended_pipeline = get_masked_pipeline (stex, ctx);");
blended_pipeline = get_masked_pipeline (stex, ctx);
- cogl_pipeline_set_layer_texture (blended_pipeline, 1, priv->mask_texture);
- cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
+ cogl_pipeline_set_layer_texture (blended_pipeline, n_planes, priv->mask_texture);
+ /* cogl_pipeline_set_layer_filters (blended_pipeline, n_planes, filter, filter); */
}
- cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
- cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
+ for (i = 0; i < n_planes; i++)
+ {
+ CoglTexture *plane = meta_planar_texture_get_plane (paint_tex, i);
+ g_warning ("Blended pipeline: adding layer %d, %p", i, plane);
+
+ cogl_pipeline_set_layer_texture (blended_pipeline, i, plane);
+ /* cogl_pipeline_set_layer_filters (blended_pipeline, i, filter, filter); */
+ cogl_pipeline_set_layer_combine (blended_pipeline, n_planes,
+ /* "RGB=MODULATE(PREVIOUS, TEXTURE_0[A])\n" */
+ /* "A=REPLACE(PREVIOUS[A])", */
+ "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
+ /* "RGBA = REPLACE (PREVIOUS)", */
+ NULL);
+ }
CoglColor color;
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
@@ -861,15 +988,15 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
/**
* meta_shaped_texture_set_texture:
* @stex: The #MetaShapedTexture
- * @pixmap: The #CoglTexture to display
+ * @pixmap: The #MetaPlanarTexture to display
*/
void
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
- CoglTexture *texture)
+ MetaPlanarTexture *texture)
{
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
- set_cogl_texture (stex, texture);
+ set_planar_texture (stex, texture);
}
/**
@@ -918,7 +1045,8 @@ CoglTexture *
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
{
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
- return COGL_TEXTURE (stex->priv->texture);
+
+ return meta_planar_texture_get_plane (stex->priv->texture, 0);
}
/**
@@ -976,19 +1104,19 @@ cairo_surface_t *
meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip)
{
- CoglTexture *texture, *mask_texture;
+ MetaPlanarTexture *texture, *mask_texture;
cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
cairo_surface_t *surface;
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
- texture = COGL_TEXTURE (stex->priv->texture);
+ texture = stex->priv->texture;
if (texture == NULL)
return NULL;
- texture_rect.width = cogl_texture_get_width (texture);
- texture_rect.height = cogl_texture_get_height (texture);
+ texture_rect.width = meta_planar_texture_get_width (texture);
+ texture_rect.height = meta_planar_texture_get_height (texture);
if (clip != NULL)
{
@@ -998,6 +1126,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
return NULL;
}
+ /* XXX */
if (clip != NULL)
texture = cogl_texture_new_from_sub_texture (texture,
clip->x,
@@ -1006,9 +1135,10 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
clip->height);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- cogl_texture_get_width (texture),
- cogl_texture_get_height (texture));
+ meta_planar_texture_get_width (texture),
+ meta_planar_texture_get_height (texture));
+ /* XXX */
cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_stride (surface),
cairo_image_surface_get_data (surface));
@@ -1016,7 +1146,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_surface_mark_dirty (surface);
if (clip != NULL)
- cogl_object_unref (texture);
+ g_object_unref (texture);
mask_texture = stex->priv->mask_texture;
if (mask_texture != NULL)
@@ -1032,8 +1162,8 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
clip->height);
mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
- cogl_texture_get_width (mask_texture),
- cogl_texture_get_height (mask_texture));
+ meta_planar_texture_get_width (mask_texture),
+ meta_planar_texture_get_height (mask_texture));
cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
cairo_image_surface_get_stride (mask_surface),
@@ -1107,5 +1237,6 @@ cullable_iface_init (MetaCullableInterface *iface)
ClutterActor *
meta_shaped_texture_new (void)
{
+ g_warning ("New MetaShapedTexture!");
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
}
diff --git a/src/meson.build b/src/meson.build
index 4ea30b06d..47b32297d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -271,6 +271,7 @@ mutter_sources = [
'compositor/meta-feedback-actor-private.h',
'compositor/meta-module.c',
'compositor/meta-module.h',
+ 'compositor/meta-planar-texture.c',
'compositor/meta-plugin.c',
'compositor/meta-plugin-manager.c',
'compositor/meta-plugin-manager.h',
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index 9fee02d52..d3f08125c 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -184,6 +184,19 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
components = COGL_TEXTURE_COMPONENTS_RGB;
break;
#endif
+ case WL_SHM_FORMAT_NV12:
+ g_warning ("FORMAT IS NV12");
+ case WL_SHM_FORMAT_NV21:
+ g_warning ("FORMAT IS NV21");
+ case WL_SHM_FORMAT_YUV422:
+ g_warning ("FORMAT IS YUV422");
+ case WL_SHM_FORMAT_YVU422:
+ g_warning ("FORMAT IS YVU422");
+ case WL_SHM_FORMAT_YUV444:
+ g_warning ("FORMAT IS YUV444");
+ case WL_SHM_FORMAT_YVU444:
+ g_warning ("FORMAT IS YVU444");
+
default:
g_warn_if_reached ();
format = COGL_PIXEL_FORMAT_ARGB_8888;
@@ -257,12 +270,15 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
EGLDisplay egl_display = cogl_egl_context_get_egl_display (cogl_context);
int format, width, height, y_inverted;
CoglPixelFormat cogl_format;
- EGLImageKHR egl_image;
- CoglTexture2D *texture;
+ guint i, n_planes;
+ GPtrArray *textures;
+ gboolean ret = FALSE;
+ EGLint attrib_list[3] = { EGL_NONE, EGL_NONE, EGL_NONE };
if (buffer->texture)
return TRUE;
+ /* Query the necessary properties */
if (!meta_egl_query_wayland_buffer (egl, egl_display, buffer->resource,
EGL_TEXTURE_FORMAT, &format,
error))
@@ -283,6 +299,7 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
NULL))
y_inverted = EGL_TRUE;
+ /* Map the EGL texture format to CoglPixelFormat, if possible */
switch (format)
{
case EGL_TEXTURE_RGB:
@@ -291,6 +308,10 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
case EGL_TEXTURE_RGBA:
cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
break;
+ case EGL_TEXTURE_Y_UV_WL:
+ g_warning ("Got a NV12 color format texture!!");
+ cogl_format = COGL_PIXEL_FORMAT_Y_UV;
+ break;
default:
g_set_error (error, G_IO_ERROR,
G_IO_ERROR_FAILED,
@@ -298,30 +319,56 @@ egl_image_buffer_attach (MetaWaylandBuffer *buffer,
return FALSE;
}
- /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be used
- * in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
- egl_image = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
- EGL_WAYLAND_BUFFER_WL, buffer->resource,
- NULL,
- error);
- if (egl_image == EGL_NO_IMAGE_KHR)
- return FALSE;
+ n_planes = _cogl_pixel_format_get_n_planes (cogl_format);
+ textures = g_ptr_array_new_full (n_planes, cogl_object_unref);
- texture = cogl_egl_texture_2d_new_from_image (cogl_context,
- width, height,
- cogl_format,
- egl_image,
- error);
+ /* Each EGLImage is a plane in the final texture */
+ for (i = 0; i < n_planes; i++)
+ {
+ EGLImageKHR egl_img;
+ CoglTexture2D *texture;
- meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
+ /* Specify that we want the i'th plane */
+ attrib_list[0] = EGL_WAYLAND_PLANE_WL;
+ attrib_list[1] = i;
- if (!texture)
- return FALSE;
+ /* The WL_bind_wayland_display spec states that EGL_NO_CONTEXT is to be
+ * used in conjunction with the EGL_WAYLAND_BUFFER_WL target. */
+ egl_img = meta_egl_create_image (egl, egl_display, EGL_NO_CONTEXT,
+ EGL_WAYLAND_BUFFER_WL, buffer->resource,
+ attrib_list,
+ error);
+
+ if (egl_img == EGL_NO_IMAGE_KHR)
+ goto out;
+
+ texture = cogl_egl_texture_2d_new_from_image (cogl_context,
+ width, height,
+ cogl_format,
+ egl_img,
+ error);
+
+ meta_egl_destroy_image (egl, egl_display, egl_img, NULL);
- buffer->texture = COGL_TEXTURE (texture);
+ if (!texture)
+ goto out;
+
+ g_ptr_array_add (textures, texture);
+ }
+
+
+ buffer->texture = meta_planar_texture_new (cogl_format,
+ g_ptr_array_free (textures, FALSE),
+ n_planes);
buffer->is_y_inverted = !!y_inverted;
- return TRUE;
+ ret = TRUE;
+
+out:
+ if (!ret)
+ g_ptr_array_free (textures, TRUE);
+
+ return ret;
}
#ifdef HAVE_WAYLAND_EGLSTREAM
@@ -375,7 +422,7 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
g_assert_not_reached ();
}
-CoglTexture *
+MetaPlanarTexture *
meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer)
{
return buffer->texture;
@@ -486,7 +533,7 @@ meta_wayland_buffer_finalize (GObject *object)
{
MetaWaylandBuffer *buffer = META_WAYLAND_BUFFER (object);
- g_clear_pointer (&buffer->texture, cogl_object_unref);
+ g_clear_object (&buffer->texture);
#ifdef HAVE_WAYLAND_EGLSTREAM
g_clear_object (&buffer->egl_stream.stream);
#endif
diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h
index 3709c85ff..42fda4886 100644
--- a/src/wayland/meta-wayland-buffer.h
+++ b/src/wayland/meta-wayland-buffer.h
@@ -29,6 +29,7 @@
#include <wayland-server.h>
#include "cogl/cogl.h"
+#include "compositor/meta-planar-texture.h"
#include "wayland/meta-wayland-types.h"
#include "wayland/meta-wayland-egl-stream.h"
#include "wayland/meta-wayland-dma-buf.h"
@@ -51,7 +52,7 @@ struct _MetaWaylandBuffer
struct wl_resource *resource;
struct wl_listener destroy_listener;
- CoglTexture *texture;
+ MetaPlanarTexture *texture;
gboolean is_y_inverted;
MetaWaylandBufferType type;
@@ -77,7 +78,7 @@ gboolean meta_wayland_buffer_is_realized (MetaWaylandBuff
gboolean meta_wayland_buffer_realize (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
GError **error);
-CoglTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer);
+MetaPlanarTexture * meta_wayland_buffer_get_texture (MetaWaylandBuffer *buffer);
CoglSnippet * meta_wayland_buffer_create_snippet (MetaWaylandBuffer *buffer);
gboolean meta_wayland_buffer_is_y_inverted (MetaWaylandBuffer *buffer);
void meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c
index 50dbb9bcd..6f4115dd1 100644
--- a/src/wayland/meta-wayland-shell-surface.c
+++ b/src/wayland/meta-wayland-shell-surface.c
@@ -153,7 +153,7 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWindow *window;
MetaWaylandBuffer *buffer;
- CoglTexture *texture;
+ MetaPlanarTexture *texture;
double scale;
surface_role_class =
@@ -171,8 +171,8 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
texture = meta_wayland_buffer_get_texture (buffer);
- window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
- window->buffer_rect.height = cogl_texture_get_height (texture) * scale;
+ window->buffer_rect.width = meta_planar_texture_get_width (texture) * scale;
+ window->buffer_rect.height = meta_planar_texture_get_height (texture) * scale;
}
static void
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index b918e296e..3202ab98f 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -648,7 +648,7 @@ meta_wayland_surface_apply_pending_state (MetaWaylandSurface *surface,
if (switched_buffer && meta_wayland_surface_get_actor (surface))
{
MetaShapedTexture *stex;
- CoglTexture *texture;
+ MetaPlanarTexture *texture;
CoglSnippet *snippet;
gboolean is_y_inverted;
@@ -1749,8 +1749,8 @@ meta_wayland_surface_get_width (MetaWaylandSurface *surface)
buffer = surface->buffer_ref.buffer;
if (buffer)
{
- CoglTexture *texture = meta_wayland_buffer_get_texture (buffer);
- return cogl_texture_get_width (texture) / surface->scale;
+ MetaPlanarTexture *texture = meta_wayland_buffer_get_texture (buffer);
+ return meta_planar_texture_get_width (texture) / surface->scale;
}
else
{
@@ -1766,8 +1766,8 @@ meta_wayland_surface_get_height (MetaWaylandSurface *surface)
buffer = surface->buffer_ref.buffer;
if (buffer)
{
- CoglTexture *texture = meta_wayland_buffer_get_texture (buffer);
- return cogl_texture_get_height (texture) / surface->scale;
+ MetaPlanarTexture *texture = meta_wayland_buffer_get_texture (buffer);
+ return meta_planar_texture_get_height (texture) / surface->scale;
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]