diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index ae02d86c0..8f3acfb45 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -327,6 +327,8 @@ cogl_sources_c = \
$(srcdir)/winsys/cogl-winsys-stub.c \
$(srcdir)/cogl-config-private.h \
$(srcdir)/cogl-config.c \
+ $(srcdir)/cogl-boxed-value.h \
+ $(srcdir)/cogl-boxed-value.c \
$(NULL)
if SUPPORT_XLIB
diff --git a/cogl/cogl-boxed-value.c b/cogl/cogl-boxed-value.c
new file mode 100644
index 000000000..ec1d4d5fa
--- /dev/null
+++ b/cogl/cogl-boxed-value.c
@@ -0,0 +1,286 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+
+#include "cogl-boxed-value.h"
+#include "cogl-context-private.h"
+
+gboolean
+_cogl_boxed_value_equal (const CoglBoxedValue *bva,
+ const CoglBoxedValue *bvb)
+{
+ const void *pa, *pb;
+
+ if (bva->type != bvb->type)
+ return FALSE;
+
+ switch (bva->type)
+ {
+ case COGL_BOXED_NONE:
+ return TRUE;
+
+ case COGL_BOXED_INT:
+ if (bva->size != bvb->size || bva->count != bvb->count)
+ return FALSE;
+
+ if (bva->count == 1)
+ {
+ pa = bva->v.int_value;
+ pb = bvb->v.int_value;
+ }
+ else
+ {
+ pa = bva->v.int_array;
+ pb = bvb->v.int_array;
+ }
+
+ return !memcmp (pa, pb, sizeof (int) * bva->size * bva->count);
+
+ case COGL_BOXED_FLOAT:
+ if (bva->size != bvb->size || bva->count != bvb->count)
+ return FALSE;
+
+ if (bva->count == 1)
+ {
+ pa = bva->v.float_value;
+ pb = bvb->v.float_value;
+ }
+ else
+ {
+ pa = bva->v.float_array;
+ pb = bvb->v.float_array;
+ }
+
+ return !memcmp (pa, pb, sizeof (float) * bva->size * bva->count);
+
+ case COGL_BOXED_MATRIX:
+ if (bva->size != bvb->size ||
+ bva->count != bvb->count ||
+ bva->transpose != bvb->transpose)
+ return FALSE;
+
+ if (bva->count == 1)
+ {
+ pa = bva->v.matrix;
+ pb = bvb->v.matrix;
+ }
+ else
+ {
+ pa = bva->v.array;
+ pb = bvb->v.array;
+ }
+
+ return !memcmp (pa, pb,
+ sizeof (float) * bva->size * bva->size * bva->count);
+ }
+
+ g_warn_if_reached ();
+
+ return FALSE;
+}
+
+static void
+_cogl_boxed_value_set_x (CoglBoxedValue *bv,
+ int size,
+ int count,
+ CoglBoxedType type,
+ gsize value_size,
+ gconstpointer value,
+ gboolean transpose)
+{
+ if (count == 1)
+ {
+ if (bv->count > 1)
+ g_free (bv->v.array);
+
+ memcpy (bv->v.float_value, value, value_size);
+ }
+ else
+ {
+ if (bv->count > 1)
+ {
+ if (bv->count != count ||
+ bv->size != size ||
+ bv->type != type)
+ {
+ g_free (bv->v.array);
+ bv->v.array = g_malloc (count * value_size);
+ }
+ }
+ else
+ bv->v.array = g_malloc (count * value_size);
+
+ memcpy (bv->v.array, value, count * value_size);
+ }
+
+ bv->type = type;
+ bv->size = size;
+ bv->count = count;
+ bv->transpose = transpose;
+}
+
+void
+_cogl_boxed_value_set_1f (CoglBoxedValue *bv,
+ float value)
+{
+ _cogl_boxed_value_set_x (bv,
+ 1, 1, COGL_BOXED_FLOAT,
+ sizeof (float), &value, FALSE);
+}
+
+void
+_cogl_boxed_value_set_1i (CoglBoxedValue *bv,
+ int value)
+{
+ _cogl_boxed_value_set_x (bv,
+ 1, 1, COGL_BOXED_INT,
+ sizeof (int), &value, FALSE);
+}
+
+void
+_cogl_boxed_value_set_float (CoglBoxedValue *bv,
+ int n_components,
+ int count,
+ const float *value)
+{
+ _cogl_boxed_value_set_x (bv,
+ n_components, count,
+ COGL_BOXED_FLOAT,
+ sizeof (float) * n_components, value, FALSE);
+}
+
+void
+_cogl_boxed_value_set_int (CoglBoxedValue *bv,
+ int n_components,
+ int count,
+ const int *value)
+{
+ _cogl_boxed_value_set_x (bv,
+ n_components, count,
+ COGL_BOXED_INT,
+ sizeof (int) * n_components, value, FALSE);
+}
+
+void
+_cogl_boxed_value_set_matrix (CoglBoxedValue *bv,
+ int dimensions,
+ int count,
+ gboolean transpose,
+ const float *value)
+{
+ _cogl_boxed_value_set_x (bv,
+ dimensions, count,
+ COGL_BOXED_MATRIX,
+ sizeof (float) * dimensions * dimensions,
+ value,
+ transpose);
+}
+
+void
+_cogl_boxed_value_destroy (CoglBoxedValue *bv)
+{
+ if (bv->count > 1)
+ g_free (bv->v.array);
+}
+
+void
+_cogl_boxed_value_set_uniform (CoglContext *ctx,
+ GLint location,
+ const CoglBoxedValue *value)
+{
+ switch (value->type)
+ {
+ case COGL_BOXED_NONE:
+ break;
+
+ case COGL_BOXED_INT:
+ {
+ const int *ptr;
+
+ if (value->count == 1)
+ ptr = value->v.int_value;
+ else
+ ptr = value->v.int_array;
+
+ switch (value->size)
+ {
+ case 1: ctx->glUniform1iv (location, value->count, ptr); break;
+ case 2: ctx->glUniform2iv (location, value->count, ptr); break;
+ case 3: ctx->glUniform3iv (location, value->count, ptr); break;
+ case 4: ctx->glUniform4iv (location, value->count, ptr); break;
+ }
+ }
+ break;
+
+ case COGL_BOXED_FLOAT:
+ {
+ const float *ptr;
+
+ if (value->count == 1)
+ ptr = value->v.float_value;
+ else
+ ptr = value->v.float_array;
+
+ switch (value->size)
+ {
+ case 1: ctx->glUniform1fv (location, value->count, ptr); break;
+ case 2: ctx->glUniform2fv (location, value->count, ptr); break;
+ case 3: ctx->glUniform3fv (location, value->count, ptr); break;
+ case 4: ctx->glUniform4fv (location, value->count, ptr); break;
+ }
+ }
+ break;
+
+ case COGL_BOXED_MATRIX:
+ {
+ const float *ptr;
+
+ if (value->count == 1)
+ ptr = value->v.matrix;
+ else
+ ptr = value->v.float_array;
+
+ switch (value->size)
+ {
+ case 2:
+ ctx->glUniformMatrix2fv (location, value->count,
+ value->transpose, ptr);
+ break;
+ case 3:
+ ctx->glUniformMatrix3fv (location, value->count,
+ value->transpose, ptr);
+ break;
+ case 4:
+ ctx->glUniformMatrix4fv (location, value->count,
+ value->transpose, ptr);
+ break;
+ }
+ }
+ break;
+ }
+}
diff --git a/cogl/cogl-boxed-value.h b/cogl/cogl-boxed-value.h
new file mode 100644
index 000000000..dada36f27
--- /dev/null
+++ b/cogl/cogl-boxed-value.h
@@ -0,0 +1,100 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ *
+ */
+
+#ifndef __COGL_BOXED_VALUE_H
+#define __COGL_BOXED_VALUE_H
+
+#include
+
+#include "cogl-context.h"
+
+typedef enum {
+ COGL_BOXED_NONE,
+ COGL_BOXED_INT,
+ COGL_BOXED_FLOAT,
+ COGL_BOXED_MATRIX
+} CoglBoxedType;
+
+typedef struct _CoglBoxedValue
+{
+ CoglBoxedType type;
+ int size, count;
+ gboolean transpose;
+
+ union {
+ float float_value[4];
+ int int_value[4];
+ float matrix[16];
+ float *float_array;
+ int *int_array;
+ void *array;
+ } v;
+} CoglBoxedValue;
+
+#define _cogl_boxed_value_init(bv) \
+ G_STMT_START { \
+ CoglBoxedValue *_bv = (bv); \
+ _bv->type = COGL_BOXED_NONE; \
+ _bv->count = 1; \
+ } G_STMT_END
+
+gboolean
+_cogl_boxed_value_equal (const CoglBoxedValue *bva,
+ const CoglBoxedValue *bvb);
+
+void
+_cogl_boxed_value_set_1f (CoglBoxedValue *bv,
+ float value);
+
+void
+_cogl_boxed_value_set_1i (CoglBoxedValue *bv,
+ int value);
+
+void
+_cogl_boxed_value_set_float (CoglBoxedValue *bv,
+ int n_components,
+ int count,
+ const float *value);
+
+void
+_cogl_boxed_value_set_int (CoglBoxedValue *bv,
+ int n_components,
+ int count,
+ const int *value);
+
+void
+_cogl_boxed_value_set_matrix (CoglBoxedValue *bv,
+ int dimensions,
+ int count,
+ gboolean transpose,
+ const float *value);
+
+void
+_cogl_boxed_value_destroy (CoglBoxedValue *bv);
+
+void
+_cogl_boxed_value_set_uniform (CoglContext *ctx,
+ int location,
+ const CoglBoxedValue *value);
+
+#endif /* __COGL_BOXED_VALUE_H */
diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h
index 946f8bca7..6d0013756 100644
--- a/cogl/cogl-internal.h
+++ b/cogl/cogl-internal.h
@@ -32,29 +32,6 @@
#include
#endif
-typedef enum {
- COGL_BOXED_NONE,
- COGL_BOXED_INT,
- COGL_BOXED_FLOAT,
- COGL_BOXED_MATRIX
-} CoglBoxedType;
-
-typedef struct _CoglBoxedValue
-{
- CoglBoxedType type;
- int size, count;
- gboolean transpose;
-
- union {
- float float_value[4];
- int int_value[4];
- float matrix[16];
- float *float_array;
- int *int_array;
- void *array;
- } v;
-} CoglBoxedValue;
-
#ifdef COGL_GL_DEBUG
const char *
diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
index 4d0453644..5b07e5efe 100644
--- a/cogl/cogl-pipeline-private.h
+++ b/cogl/cogl-pipeline-private.h
@@ -36,6 +36,7 @@
#include "cogl-profile.h"
#include "cogl-queue.h"
#include "cogl-internal.h"
+#include "cogl-boxed-value.h"
#include
diff --git a/cogl/cogl-program.c b/cogl/cogl-program.c
index 316b16425..d0fb6f084 100644
--- a/cogl/cogl-program.c
+++ b/cogl/cogl-program.c
@@ -189,71 +189,34 @@ cogl_program_get_uniform_location (CoglHandle handle,
return program->custom_uniforms->len - 1;
}
-static void
-cogl_program_uniform_x (CoglHandle handle,
- int uniform_no,
- int size,
- int count,
- CoglBoxedType type,
- gsize value_size,
- gconstpointer value,
- gboolean transpose)
+static CoglProgramUniform *
+cogl_program_modify_uniform (CoglProgram *program,
+ int uniform_no)
{
- CoglProgram *program = handle;
+ CoglProgramUniform *uniform;
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_program (program), NULL);
+ _COGL_RETURN_VAL_IF_FAIL (uniform_no >= 0 &&
+ uniform_no < program->custom_uniforms->len,
+ NULL);
- _COGL_RETURN_IF_FAIL (cogl_is_program (handle));
- _COGL_RETURN_IF_FAIL (program != NULL);
+ uniform = &g_array_index (program->custom_uniforms,
+ CoglProgramUniform, uniform_no);
+ uniform->dirty = TRUE;
- if (uniform_no >= 0 && uniform_no < program->custom_uniforms->len &&
- size >= 1 && size <= 4 && count >= 1)
- {
- CoglProgramUniform *uniform =
- &g_array_index (program->custom_uniforms,
- CoglProgramUniform, uniform_no);
-
- if (count == 1)
- {
- if (uniform->value.count > 1)
- g_free (uniform->value.v.array);
-
- memcpy (uniform->value.v.float_value, value, value_size);
- }
- else
- {
- if (uniform->value.count > 1)
- {
- if (uniform->value.count != count ||
- uniform->value.size != size ||
- uniform->value.type != type)
- {
- g_free (uniform->value.v.array);
- uniform->value.v.array = g_malloc (count * value_size);
- }
- }
- else
- uniform->value.v.array = g_malloc (count * value_size);
-
- memcpy (uniform->value.v.array, value, count * value_size);
- }
-
- uniform->value.type = type;
- uniform->value.size = size;
- uniform->value.count = count;
- uniform->value.transpose = transpose;
- uniform->dirty = TRUE;
- }
+ return uniform;
}
void
cogl_program_uniform_1f (int uniform_no,
float value)
{
+ CoglProgramUniform *uniform;
+
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_program_uniform_x (ctx->current_program,
- uniform_no, 1, 1, COGL_BOXED_FLOAT,
- sizeof (float), &value, FALSE);
+
+ uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no);
+ _cogl_boxed_value_set_1f (&uniform->value, value);
}
void
@@ -261,19 +224,22 @@ cogl_program_set_uniform_1f (CoglHandle handle,
int uniform_location,
float value)
{
- cogl_program_uniform_x (handle,
- uniform_location, 1, 1, COGL_BOXED_FLOAT,
- sizeof (float), &value, FALSE);
+ CoglProgramUniform *uniform;
+
+ uniform = cogl_program_modify_uniform (handle, uniform_location);
+ _cogl_boxed_value_set_1f (&uniform->value, value);
}
void
cogl_program_uniform_1i (int uniform_no,
int value)
{
+ CoglProgramUniform *uniform;
+
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_program_uniform_x (ctx->current_program,
- uniform_no, 1, 1, COGL_BOXED_INT,
- sizeof (int), &value, FALSE);
+
+ uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no);
+ _cogl_boxed_value_set_1i (&uniform->value, value);
}
void
@@ -281,21 +247,24 @@ cogl_program_set_uniform_1i (CoglHandle handle,
int uniform_location,
int value)
{
- cogl_program_uniform_x (handle,
- uniform_location, 1, 1, COGL_BOXED_INT,
- sizeof (int), &value, FALSE);
+ CoglProgramUniform *uniform;
+
+ uniform = cogl_program_modify_uniform (handle, uniform_location);
+ _cogl_boxed_value_set_1i (&uniform->value, value);
}
void
cogl_program_uniform_float (int uniform_no,
int size,
int count,
- const GLfloat *value)
+ const float *value)
{
+ CoglProgramUniform *uniform;
+
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_program_uniform_x (ctx->current_program,
- uniform_no, size, count, COGL_BOXED_FLOAT,
- sizeof (float) * size, value, FALSE);
+
+ uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no);
+ _cogl_boxed_value_set_float (&uniform->value, size, count, value);
}
void
@@ -305,22 +274,24 @@ cogl_program_set_uniform_float (CoglHandle handle,
int count,
const float *value)
{
- cogl_program_uniform_x (handle,
- uniform_location, n_components, count,
- COGL_BOXED_FLOAT,
- sizeof (float) * n_components, value, FALSE);
+ CoglProgramUniform *uniform;
+
+ uniform = cogl_program_modify_uniform (handle, uniform_location);
+ _cogl_boxed_value_set_float (&uniform->value, n_components, count, value);
}
void
cogl_program_uniform_int (int uniform_no,
int size,
int count,
- const GLint *value)
+ const int *value)
{
+ CoglProgramUniform *uniform;
+
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_program_uniform_x (ctx->current_program,
- uniform_no, size, count, COGL_BOXED_INT,
- sizeof (int) * size, value, FALSE);
+
+ uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no);
+ _cogl_boxed_value_set_int (&uniform->value, size, count, value);
}
void
@@ -330,10 +301,10 @@ cogl_program_set_uniform_int (CoglHandle handle,
int count,
const int *value)
{
- cogl_program_uniform_x (handle,
- uniform_location, n_components, count,
- COGL_BOXED_INT,
- sizeof (int) * n_components, value, FALSE);
+ CoglProgramUniform *uniform;
+
+ uniform = cogl_program_modify_uniform (handle, uniform_location);
+ _cogl_boxed_value_set_int (&uniform->value, n_components, count, value);
}
void
@@ -344,14 +315,14 @@ cogl_program_set_uniform_matrix (CoglHandle handle,
gboolean transpose,
const float *value)
{
- _COGL_RETURN_IF_FAIL (cogl_is_program (handle));
+ CoglProgramUniform *uniform;
- cogl_program_uniform_x (handle,
- uniform_location, dimensions, count,
- COGL_BOXED_MATRIX,
- sizeof (float) * dimensions * dimensions,
- value,
- transpose);
+ uniform = cogl_program_modify_uniform (handle, uniform_location);
+ _cogl_boxed_value_set_matrix (&uniform->value,
+ dimensions,
+ count,
+ transpose,
+ value);
}
void
@@ -361,9 +332,12 @@ cogl_program_uniform_matrix (int uniform_no,
gboolean transpose,
const float *value)
{
+ CoglProgramUniform *uniform;
+
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
- cogl_program_set_uniform_matrix (ctx->current_program,
- uniform_no, size, count, transpose, value);
+
+ uniform = cogl_program_modify_uniform (ctx->current_program, uniform_no);
+ _cogl_boxed_value_set_matrix (&uniform->value, size, count, transpose, value);
}
/* ARBfp local parameters can be referenced like:
@@ -398,84 +372,6 @@ get_local_param_index (const char *uniform_name)
return _index;
}
-static void
-_cogl_program_flush_uniform_glsl (GLint location,
- CoglBoxedValue *value)
-{
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
- switch (value->type)
- {
- case COGL_BOXED_NONE:
- break;
-
- case COGL_BOXED_INT:
- {
- int *ptr;
-
- if (value->count == 1)
- ptr = value->v.int_value;
- else
- ptr = value->v.int_array;
-
- switch (value->size)
- {
- case 1: ctx->glUniform1iv (location, value->count, ptr); break;
- case 2: ctx->glUniform2iv (location, value->count, ptr); break;
- case 3: ctx->glUniform3iv (location, value->count, ptr); break;
- case 4: ctx->glUniform4iv (location, value->count, ptr); break;
- }
- }
- break;
-
- case COGL_BOXED_FLOAT:
- {
- float *ptr;
-
- if (value->count == 1)
- ptr = value->v.float_value;
- else
- ptr = value->v.float_array;
-
- switch (value->size)
- {
- case 1: ctx->glUniform1fv (location, value->count, ptr); break;
- case 2: ctx->glUniform2fv (location, value->count, ptr); break;
- case 3: ctx->glUniform3fv (location, value->count, ptr); break;
- case 4: ctx->glUniform4fv (location, value->count, ptr); break;
- }
- }
- break;
-
- case COGL_BOXED_MATRIX:
- {
- float *ptr;
-
- if (value->count == 1)
- ptr = value->v.matrix;
- else
- ptr = value->v.float_array;
-
- switch (value->size)
- {
- case 2:
- ctx->glUniformMatrix2fv (location, value->count,
- value->transpose, ptr);
- break;
- case 3:
- ctx->glUniformMatrix3fv (location, value->count,
- value->transpose, ptr);
- break;
- case 4:
- ctx->glUniformMatrix4fv (location, value->count,
- value->transpose, ptr);
- break;
- }
- }
- break;
- }
-}
-
#ifdef HAVE_COGL_GL
static void
@@ -536,8 +432,9 @@ _cogl_program_flush_uniforms (CoglProgram *program,
switch (_cogl_program_get_language (program))
{
case COGL_SHADER_LANGUAGE_GLSL:
- _cogl_program_flush_uniform_glsl (uniform->location,
- &uniform->value);
+ _cogl_boxed_value_set_uniform (ctx,
+ uniform->location,
+ &uniform->value);
break;
case COGL_SHADER_LANGUAGE_ARBFP: