mutter/cogl/cogl-boxed-value.c
Robert Bragg 36c85da3b8 Remove cogl-internal.h
This remove cogl-internal.h in favour of using cogl-private.h. Some
things in cogl-internal.h were moved to driver/gl/cogl-util-gl-private.h
and the _cogl_gl_error_to_string function whose prototype was moved from
cogl-internal.h to cogl-util-gl-private.h has had its implementation
moved from cogl.c to cogl-util-gl.c

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit 01cc82ece091aa3bec4c07fdd6bc9e5135fca573)
2013-01-22 17:48:17 +00:00

371 lines
9.5 KiB
C

/*
* 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"
#include "cogl-util-gl-private.h"
CoglBool
_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)
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_tranpose (float *dst,
int size,
const float *src)
{
int y, x;
/* If the value is transposed we'll just transpose it now as it
* is copied into the boxed value instead of passing TRUE to
* glUniformMatrix because that is not supported on GLES and it
* doesn't seem like the GL driver would be able to do anything
* much smarter than this anyway */
for (y = 0; y < size; y++)
for (x = 0; x < size; x++)
*(dst++) = src[y + x * size];
}
static void
_cogl_boxed_value_set_x (CoglBoxedValue *bv,
int size,
int count,
CoglBoxedType type,
size_t value_size,
const void *value,
CoglBool transpose)
{
if (count == 1)
{
if (bv->count > 1)
g_free (bv->v.array);
if (transpose)
_cogl_boxed_value_tranpose (bv->v.float_value,
size,
value);
else
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);
if (transpose)
{
int value_num;
for (value_num = 0; value_num < count; value_num++)
_cogl_boxed_value_tranpose (bv->v.float_array +
value_num * size * size,
size,
(const float *) value +
value_num * size * size);
}
else
memcpy (bv->v.array, value, count * value_size);
}
bv->type = type;
bv->size = size;
bv->count = count;
}
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,
CoglBool 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_copy (CoglBoxedValue *dst,
const CoglBoxedValue *src)
{
*dst = *src;
if (src->count > 1)
{
switch (src->type)
{
case COGL_BOXED_NONE:
break;
case COGL_BOXED_INT:
dst->v.int_array = g_memdup (src->v.int_array,
src->size * src->count * sizeof (int));
break;
case COGL_BOXED_FLOAT:
dst->v.float_array = g_memdup (src->v.float_array,
src->size *
src->count *
sizeof (float));
break;
case COGL_BOXED_MATRIX:
dst->v.float_array = g_memdup (src->v.float_array,
src->size * src->size *
src->count * sizeof (float));
break;
}
}
}
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:
GE( ctx, glUniform1iv (location, value->count, ptr) );
break;
case 2:
GE( ctx, glUniform2iv (location, value->count, ptr) );
break;
case 3:
GE( ctx, glUniform3iv (location, value->count, ptr) );
break;
case 4:
GE( 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:
GE( ctx, glUniform1fv (location, value->count, ptr) );
break;
case 2:
GE( ctx, glUniform2fv (location, value->count, ptr) );
break;
case 3:
GE( ctx, glUniform3fv (location, value->count, ptr) );
break;
case 4:
GE( 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:
GE( ctx, glUniformMatrix2fv (location, value->count,
FALSE, ptr) );
break;
case 3:
GE( ctx, glUniformMatrix3fv (location, value->count,
FALSE, ptr) );
break;
case 4:
GE( ctx, glUniformMatrix4fv (location, value->count,
FALSE, ptr) );
break;
}
}
break;
}
}