I'm trying to add full screen color management to mutter using GLSL. To do this, I'm passing a few kb of data to the ClutterShader, and managing to segfault mutter in a spectacular way.
Digging into the problem a little more, clutter seems to have a hardcoded size of 4 native values, and a 4x4 2d matrix. In practice, this is next-to-useless for me. If you try to use clutter_value_set_shader_float() with a size greater than 4, you don't get an error, you just get random memory corruption. That ain't so great. :-) I've attached a patch to make the clutter shader types use dynamically allocated memory, which allows me to pass the few kb of data to my fragment shader. Comments please. Thanks. Richard.
From f641d0a92ce059d71a5da68ba2eaaffc7e3507e6 Mon Sep 17 00:00:00 2001 From: Richard Hughes <[email protected]> Date: Tue, 15 Jun 2010 22:46:47 +0100 Subject: [PATCH 2/2] Allocate dynamic memory in ClutterValues rather than hardcoding very small numbers --- clutter/clutter-shader-types.c | 32 ++++++++++++++++++++++---------- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/clutter/clutter-shader-types.c b/clutter/clutter-shader-types.c index 2c35cb8..8da28ac 100644 --- a/clutter/clutter-shader-types.c +++ b/clutter/clutter-shader-types.c @@ -81,20 +81,20 @@ static GTypeFundamentalInfo shader_matrix_finfo = { 0, }; struct _ClutterShaderFloat { - gint size; - GLfloat value[4]; + gint size; + GLfloat *value; }; struct _ClutterShaderInt { - gint size; - GLint value[4]; + gint size; + GLint *value; }; struct _ClutterShaderMatrix { - gint size; - GLfloat value[16]; + gint size; + GLfloat *value; }; static gpointer @@ -114,7 +114,10 @@ clutter_value_init_shader_float (GValue *value) static void clutter_value_free_shader_float (GValue *value) { - g_slice_free (ClutterShaderFloat, value->data[0].v_pointer); + ClutterShaderFloat *shader_float; + shader_float = value->data[0].v_pointer; + g_free (shader_float->value); + g_slice_free (ClutterShaderFloat, shader_float); } static void @@ -205,7 +208,10 @@ clutter_value_init_shader_int (GValue *value) static void clutter_value_free_shader_int (GValue *value) { - g_slice_free (ClutterShaderInt, value->data[0].v_pointer); + ClutterShaderInt *shader_int; + shader_int = value->data[0].v_pointer; + g_free (shader_int->value); + g_slice_free (ClutterShaderInt, shader_int); } static void @@ -296,7 +302,10 @@ clutter_value_init_shader_matrix (GValue *value) static void clutter_value_free_shader_matrix (GValue *value) { - g_slice_free (ClutterShaderMatrix, value->data[0].v_pointer); + ClutterShaderMatrix *shader_matrix; + shader_matrix = value->data[0].v_pointer; + g_free (shader_matrix->value); + g_slice_free (ClutterShaderMatrix, shader_matrix); } static void @@ -403,6 +412,7 @@ clutter_value_set_shader_float (GValue *value, shader_float = value->data[0].v_pointer; shader_float->size = size; + shader_float->value = g_new0 (GLfloat, size); for (i = 0; i < size; i++) shader_float->value[i] = floats[i]; @@ -432,6 +442,7 @@ clutter_value_set_shader_int (GValue *value, shader_int = value->data[0].v_pointer; shader_int->size = size; + shader_int->value = g_new0 (GLint, size); for (i = 0; i < size; i++) shader_int->value[i] = (GLint) ints[i]; @@ -440,7 +451,7 @@ clutter_value_set_shader_int (GValue *value, /** * clutter_value_set_shader_matrix: * @value: a #GValue - * @size: number of floating point values in @floats + * @size: dimension of the floating point 2D array in @matrix * @matrix: a matrix of floating point values * * Sets @matrix as the contents of @value. The passed #GValue @@ -461,6 +472,7 @@ clutter_value_set_shader_matrix (GValue *value, shader_matrix = value->data[0].v_pointer; shader_matrix->size = size; + shader_matrix->value = g_new0 (GLfloat, size * size); for (i = 0; i < size * size; i++) shader_matrix->value[i] = matrix[i]; -- 1.7.1
