cogl-program: Move the code for CoglBoxedValue to its own file

The code for manipulating CoglBoxedValues is now separated from
cogl-program.c into its own file. That way when we add support for
setting uniform values on a CoglPipeline the code for storing the
values can be shared.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2011-10-27 16:54:50 +01:00
parent d706991579
commit 256f5791fd
6 changed files with 454 additions and 191 deletions

View File

@ -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

286
cogl/cogl-boxed-value.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#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;
}
}

100
cogl/cogl-boxed-value.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*
*
*/
#ifndef __COGL_BOXED_VALUE_H
#define __COGL_BOXED_VALUE_H
#include <glib.h>
#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 */

View File

@ -32,29 +32,6 @@
#include <X11/Xutil.h>
#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 *

View File

@ -36,6 +36,7 @@
#include "cogl-profile.h"
#include "cogl-queue.h"
#include "cogl-internal.h"
#include "cogl-boxed-value.h"
#include <glib.h>

View File

@ -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: