[mutter/wip/nielsdg/add-yuv-support: 11/11] WIP
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/nielsdg/add-yuv-support: 11/11] WIP
- Date: Mon, 17 Jun 2019 14:05:37 +0000 (UTC)
commit dbf179fa7da8d484231ea6213c023a9ec672e51b
Author: Niels De Graef <niels degraef barco com>
Date: Sat Jun 15 06:35:52 2019 +0200
WIP
cogl/cogl/cogl-multi-plane-texture.c | 52 ------------
cogl/cogl/cogl-multi-plane-texture.h | 18 ----
cogl/cogl/cogl-pixel-format-conversion.c | 47 ++++++++---
cogl/cogl/driver/gl/cogl-texture-2d-gl.c | 4 -
cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c | 2 -
src/compositor/meta-shaped-texture.c | 2 -
src/wayland/meta-wayland-buffer.c | 108 +++++++++++++++++-------
src/wayland/meta-wayland-dma-buf.c | 9 +-
8 files changed, 112 insertions(+), 130 deletions(-)
---
diff --git a/cogl/cogl/cogl-multi-plane-texture.c b/cogl/cogl/cogl-multi-plane-texture.c
index e9cb916ab..209291579 100644
--- a/cogl/cogl/cogl-multi-plane-texture.c
+++ b/cogl/cogl/cogl-multi-plane-texture.c
@@ -127,58 +127,6 @@ cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
return self;
}
-CoglMultiPlaneTexture *
-cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
- CoglBitmap **bitmaps, guint n_planes,
- GError **error)
-{
- guint i = 0;
- CoglMultiPlaneTexture *self = g_slice_new0 (CoglMultiPlaneTexture);
-
- _cogl_multi_plane_texture_object_new (self);
-
- self->format = format;
- self->n_planes = n_planes;
- self->planes = g_malloc (sizeof (CoglTexture *) * n_planes);
-
- for (i = 0; i < n_planes; i++)
- {
- CoglTexture *plane;
-
- plane = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (bitmaps[i]));
-
- if (!cogl_texture_allocate (plane, error))
- {
- g_clear_pointer (&plane, cogl_object_unref);
-
- /* There's a chance we failed due to the buffer being NPOT size.
- * If so, try again with CoglTexture2DSliced (which does support this) */
- if (g_error_matches (*error,
- COGL_TEXTURE_ERROR,
- COGL_TEXTURE_ERROR_SIZE))
- {
- CoglTexture2DSliced *plane_sliced;
-
- g_clear_error (error);
-
- plane_sliced =
- cogl_texture_2d_sliced_new_from_bitmap (bitmaps[i],
- COGL_TEXTURE_MAX_WASTE);
- plane = COGL_TEXTURE (plane_sliced);
-
- if (!cogl_texture_allocate (plane, error))
- cogl_clear_object (&plane);
- }
- }
-
- cogl_object_unref (bitmaps[i]);
- self->planes[i] = plane;
- }
-
-
- return self;
-}
-
gchar *
cogl_multi_plane_texture_to_string (CoglMultiPlaneTexture *self)
{
diff --git a/cogl/cogl/cogl-multi-plane-texture.h b/cogl/cogl/cogl-multi-plane-texture.h
index c0d8d89b9..5a46cfa74 100644
--- a/cogl/cogl/cogl-multi-plane-texture.h
+++ b/cogl/cogl/cogl-multi-plane-texture.h
@@ -100,24 +100,6 @@ CoglMultiPlaneTexture * cogl_multi_plane_texture_new (CoglPixelFormat format,
CoglMultiPlaneTexture * cogl_multi_plane_texture_new_single_plane (CoglPixelFormat format,
CoglTexture *plane);
-/**
- * cogl_multi_plane_texture_new_from_bitmaps:
- * @format: The format of the new #CoglMultiPlaneTexture
- * @bitmaps: (transfer full): The planes of the texture, each as a #CoglBitmap
- * @n_planes: the number of planes the texture contains
- * @error: (out): Will be set if an error occurred
- *
- * Creates a #CoglMultiPlaneTexture from the given bitmaps and makes sure the
- * planes are uploaded to the GPU.
- *
- * Returns: (transfer full): A new #CoglMultiPlaneTexture. Use
- * cogl_object_unref() when you're done with it.
- */
-CoglMultiPlaneTexture *
-cogl_multi_plane_texture_new_from_bitmaps (CoglPixelFormat format,
- CoglBitmap **bitmaps, guint n_planes,
- GError **error);
-
/**
* cogl_multi_plane_texture_get_format:
* @self: a #CoglMultiPlaneTexture
diff --git a/cogl/cogl/cogl-pixel-format-conversion.c b/cogl/cogl/cogl-pixel-format-conversion.c
index 6b505705e..e0d926e1a 100644
--- a/cogl/cogl/cogl-pixel-format-conversion.c
+++ b/cogl/cogl/cogl-pixel-format-conversion.c
@@ -26,17 +26,31 @@
#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" \
+#define _COGL_YUV_TO_RGBA(res, y, u, v) \
+ "vec4 " res ";\n" \
+ 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[] =
+/* Shader for a single YUV plane */
+static const gchar yuv_to_rgba_shader[] =
"vec4\n"
- "cogl_nv12_to_rgba (vec2 UV)\n"
+ "cogl_yuv_to_rgba (vec2 UV)\n"
+ "{\n"
+ " vec4 orig_color = texture2D(cogl_sampler0, UV);\n"
+ " float y = 1.16438356 * (orig_color.r - 0.0625);\n"
+ " float u = orig_color.g - 0.5;\n"
+ " float v = orig_color.b - 0.5;\n"
+ _COGL_YUV_TO_RGBA ("color", "y", "u", "v")
+ " return color;\n"
+ "}\n";
+
+/* Shader for 1 Y-plane and 1 UV-plane */
+static const gchar y_uv_to_rgba_shader[] =
+ "vec4\n"
+ "cogl_y_uv_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"
@@ -46,11 +60,11 @@ static const gchar nv12_to_rgba_shader[] =
" return color;\n"
"}\n";
-static const gchar yuv_to_rgba_shader[] =
+/* Shader for 1 Y-plane, 1 U-plane and 1 V-plane */
+static const gchar y_u_v_to_rgba_shader[] =
"vec4\n"
- "cogl_yuv_to_rgba (vec2 UV)\n"
+ "cogl_y_u_v_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"
@@ -99,14 +113,19 @@ get_cogl_snippets (CoglPixelFormat format,
switch (format)
{
- case COGL_PIXEL_FORMAT_YUV444:
+ case COGL_PIXEL_FORMAT_AYUV:
global_hook = yuv_to_rgba_shader;
- layer_hook = "cogl_layer = cogl_yuv_to_rgba(cogl_tex_coord0_in.st);\n";
+ 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";
+ global_hook = y_uv_to_rgba_shader;
+ layer_hook = "cogl_layer = cogl_y_uv_to_rgba(cogl_tex_coord0_in.st);\n";
+ break;
+ case COGL_PIXEL_FORMAT_YUV444:
+ case COGL_PIXEL_FORMAT_YUV422:
+ global_hook = y_u_v_to_rgba_shader;
+ layer_hook = "cogl_layer = cogl_y_u_v_to_rgba(cogl_tex_coord0_in.st);\n";
break;
default:
*vertex_snippet_out = NULL;
diff --git a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
index fe4a53dfc..2f9e3424c 100644
--- a/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
+++ b/cogl/cogl/driver/gl/cogl-texture-2d-gl.c
@@ -202,8 +202,6 @@ 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));
@@ -344,8 +342,6 @@ 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-texture-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
index 84d87138c..f5e9a4732 100644
--- a/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-texture-driver-gl.c
@@ -98,8 +98,6 @@ _cogl_texture_driver_gen (CoglContext *ctx,
g_assert_not_reached();
}
- g_warning ("_cogl_texture_driver_gen %s", cogl_pixel_format_to_string (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 &&
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index c6dfa76e7..c8a8f46e0 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -279,8 +279,6 @@ set_clip_region (MetaShapedTexture *stex,
static void
meta_shaped_texture_reset_pipelines (MetaShapedTexture *stex)
{
- g_warning ("resetting pipelines!");
-
cogl_clear_object (&stex->pixel_format_conversion);
cogl_clear_object (&stex->base_pipeline);
diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c
index 3de148f7a..969d9b26d 100644
--- a/src/wayland/meta-wayland-buffer.c
+++ b/src/wayland/meta-wayland-buffer.c
@@ -178,6 +178,7 @@ shm_buffer_get_cogl_pixel_format (struct wl_shm_buffer *shm_buffer,
#elif G_BYTE_ORDER == G_LITTLE_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
+ components_out[0] = COGL_TEXTURE_COMPONENTS_RGBA;
break;
case WL_SHM_FORMAT_XRGB8888:
format = COGL_PIXEL_FORMAT_BGRA_8888;
@@ -243,11 +244,11 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
CoglPixelFormat format;
CoglTextureComponents components[3];
guint i, n_planes;
- uint8_t h_factors[3], v_factors[3];
+ uint8_t h_factors[3], v_factors[3], bpp[3];
CoglPixelFormat subformats[3];
gsize plane_offset = 0;
guint8 *data;
- GPtrArray *bitmaps;
+ GPtrArray *planes;
/* Query the necessary parameters */
shm_buffer = wl_shm_buffer_get (buffer->resource);
@@ -258,8 +259,7 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
n_planes = cogl_pixel_format_get_n_planes (format);
cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
cogl_pixel_format_get_subformats (format, subformats);
-
- g_warning ("Got SHM buffer, format %s", cogl_pixel_format_to_string (format));
+ cogl_pixel_format_get_bytes_per_pixel_ (format, bpp);
if (*texture &&
cogl_multi_plane_texture_get_width (*texture) == width &&
@@ -278,41 +278,81 @@ shm_buffer_attach (MetaWaylandBuffer *buffer,
wl_shm_buffer_begin_access (shm_buffer);
data = wl_shm_buffer_get_data (shm_buffer);
- bitmaps = g_ptr_array_new_full (n_planes, cogl_object_unref);
+ planes = g_ptr_array_new_full (n_planes, cogl_object_unref);
for (i = 0; i < n_planes; i++)
{
- CoglBitmap *bitmap;
+ int plane_stride;
+ CoglBitmap *plane_bitmap;
+ CoglTexture *plane_texture;
+
+ /* Adjust the stride: map to the amount of pixels and calculate how many
+ * bytes that takes in the current plane */
+ plane_stride = (stride / bpp[0]) * bpp[i] / h_factors[i];
+
+ /* Define the bitmap that of this plane */
+ plane_bitmap = cogl_bitmap_new_for_data (cogl_context,
+ width / h_factors[i],
+ height / v_factors[i],
+ subformats[i],
+ plane_stride,
+ data + plane_offset);
+ g_assert (plane_bitmap);
+
+ /* Create a texture out of it so we can upload it to the GPU */
+ plane_texture = COGL_TEXTURE (cogl_texture_2d_new_from_bitmap (plane_bitmap));
+
+ /* Separately set the components (necessary for e.g. XRGB, NV12) */
+ cogl_texture_set_components (plane_texture, components[i]);
+
+ if (!cogl_texture_allocate (plane_texture, error))
+ {
+ CoglTexture2DSliced *texture_sliced;
+
+ cogl_clear_object (&plane_texture);
+
+ /* If it didn't work due to an NPOT size, try again with an atlas texture */
+ if (!g_error_matches (*error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE))
+ {
+ cogl_object_unref (plane_bitmap);
+ goto failure;
+ }
- /* Calculate the plane start in the buffer (consider subsampling) */
- if (i > 0)
- plane_offset += (stride / h_factors[i-1]) * (height / v_factors[i-1]);
+ g_clear_error (error);
- g_warning ("Creating plane %u, h_factor = %u, v_factor = %u, plane_offset = %lu",
- i, h_factors[i], v_factors[i], plane_offset);
+ texture_sliced =
+ cogl_texture_2d_sliced_new_from_bitmap (plane_bitmap,
+ COGL_TEXTURE_MAX_WASTE);
+ plane_texture = COGL_TEXTURE (texture_sliced);
- bitmap = cogl_bitmap_new_for_data (cogl_context,
- width / h_factors[i],
- height / v_factors[i],
- subformats[i],
- stride / h_factors[i],
- data + plane_offset);
- g_assert (bitmap);
+ cogl_texture_set_components (plane_texture, components[i]);
- g_ptr_array_add (bitmaps, bitmap);
+ if (!cogl_texture_allocate (plane_texture, error))
+ {
+ cogl_clear_object (&plane_texture);
+ goto failure;
+ }
+ }
+
+ g_ptr_array_add (planes, plane_texture);
+
+ /* Calculate the next plane start in the buffer (consider subsampling) */
+ plane_offset += plane_stride * (height / v_factors[i]);
}
- *texture = cogl_multi_plane_texture_new_from_bitmaps (format,
- (CoglBitmap **) g_ptr_array_free (bitmaps, FALSE),
- n_planes, error);
+ *texture = cogl_multi_plane_texture_new (format,
+ (CoglTexture **) g_ptr_array_free (planes, FALSE),
+ n_planes);
wl_shm_buffer_end_access (shm_buffer);
*changed_texture = TRUE;
buffer->is_y_inverted = TRUE;
- g_warning ("Got the following multiplane texture:\n%s", cogl_multi_plane_texture_to_string (*texture));
-
return TRUE;
+
+failure:
+ *texture = NULL;
+ return FALSE;
}
static gboolean
@@ -578,6 +618,8 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
stride = wl_shm_buffer_get_stride (shm_buffer);
height = wl_shm_buffer_get_height (shm_buffer);
shm_buffer_get_cogl_pixel_format (shm_buffer, &format, components);
+
+ /* Fetch some properties from the pixel format */
cogl_pixel_format_get_subformats (format, subformats);
cogl_pixel_format_get_subsampling_factors (format, h_factors, v_factors);
cogl_pixel_format_get_bytes_per_pixel_ (format, bpp);
@@ -587,16 +629,15 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
for (i = 0; i < n_planes; i++)
{
CoglTexture *plane;
+ int plane_stride;
plane = cogl_multi_plane_texture_get_plane (texture, i);
-
- /* Calculate the plane start in the buffer (consider subsampling) */
- if (i > 0)
- plane_offset += (stride / h_factors[i-1]) * (height / v_factors[i-1]);
+ plane_stride = (stride / bpp[0]) * bpp[i] / h_factors[i];
for (j = 0; j < n_rectangles; j++)
{
cairo_rectangle_int_t rect;
+ gsize rect_offset;
cairo_region_get_rectangle (region, j, &rect);
@@ -604,12 +645,16 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
if (rect.height == 0 || rect.width == 0)
continue;
+ rect_offset = plane_offset
+ + rect.y * plane_stride / v_factors[i] /* Find the right row */
+ + rect.x * bpp[i] / h_factors[i]; /* and the right column */
+
if (!_cogl_texture_set_region (plane,
rect.width / h_factors[i],
rect.height / v_factors[i],
subformats[i],
- stride,
- data + plane_offset + rect.x * bpp[i] + rect.y * stride,
+ plane_stride,
+ data + rect_offset,
rect.x, rect.y,
0,
error))
@@ -618,6 +663,9 @@ process_shm_buffer_damage (MetaWaylandBuffer *buffer,
goto out;
}
}
+
+ /* Calculate the next plane start in the buffer (consider subsampling) */
+ plane_offset += plane_stride * (height / v_factors[i]);
}
out:
diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c
index 839fa1e4d..fea412b2d 100644
--- a/src/wayland/meta-wayland-dma-buf.c
+++ b/src/wayland/meta-wayland-dma-buf.c
@@ -625,16 +625,9 @@ dma_buf_bind (struct wl_client *client,
send_modifiers (resource, DRM_FORMAT_XRGB8888);
send_modifiers (resource, DRM_FORMAT_ARGB2101010);
send_modifiers (resource, DRM_FORMAT_RGB565);
+ send_modifiers (resource, DRM_FORMAT_AYUV);
send_modifiers (resource, DRM_FORMAT_NV12);
- send_modifiers (resource, DRM_FORMAT_YUV410);
- send_modifiers (resource, DRM_FORMAT_YVU410);
- send_modifiers (resource, DRM_FORMAT_YUV411);
- send_modifiers (resource, DRM_FORMAT_YVU420);
- send_modifiers (resource, DRM_FORMAT_YVU420);
send_modifiers (resource, DRM_FORMAT_YUV422);
- send_modifiers (resource, DRM_FORMAT_YVU422);
- send_modifiers (resource, DRM_FORMAT_YUV444);
- send_modifiers (resource, DRM_FORMAT_YVU444);
}
gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]