rework enabling of attributes, removing _cogl_enable()

This removes the limited caching of enabled attributes done by
_cogl_enable() and replaces it with a more generalized set of bitmasks
associated with the context that allow us to efficiently compare the set
of attribute locations that are currently enabled vs the new locations
that need enabling so we only have to inform OpenGL of the changes in
which locations are enabled/disabled.

This also adds a per-context hash table for mapping attribute names to
global name-state structs which includes a unique name-index for any
name as well as pre-validated information about builtin "cogl_"
attribute names including whether the attribute is normalized and what
texture unit a texture attribute corresponds too.

The name-state hash table means that cogl_attribute_new() now only needs
to validate names the first time they are seen.

CoglAttributes now reference a name-state structure instead of just the
attribute name, so now we can efficiently get the name-index for any
attribute and we can use that to index into a per-glsl-program cache
that maps name indices to real GL attribute locations so when we get
asked to draw a set of attributes we can very quickly determine what GL
attributes need to be setup and enabled. If we don't have a cached
location though we can still quickly access the string name so we can
query OpenGL.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-11-24 18:09:53 +00:00
parent 2112af0bc5
commit 7283e0a49c
8 changed files with 422 additions and 616 deletions

View File

@ -40,19 +40,26 @@ typedef enum
COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY
} CoglAttributeNameID;
typedef struct _CoglAttributeNameState
{
char *name;
CoglAttributeNameID name_id;
int name_index;
gboolean normalized_default;
int texture_unit;
} CoglAttributeNameState;
struct _CoglAttribute
{
CoglObject _parent;
CoglAttributeBuffer *attribute_buffer;
const char *name;
CoglAttributeNameID name_id;
const CoglAttributeNameState *name_state;
gsize stride;
gsize offset;
int n_components;
CoglAttributeType type;
gboolean normalized;
unsigned int texture_unit;
int immutable_ref;
};
@ -71,6 +78,16 @@ typedef enum
COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3
} CoglDrawFlags;
/* During CoglContext initialization we register the "cogl_color_in"
* attribute name so it gets a global name_index of 0. We need to know
* the name_index for "cogl_color_in" in
* _cogl_pipeline_flush_gl_state() */
#define COGL_ATTRIBUTE_COLOR_NAME_INDEX 0
CoglAttributeNameState *
_cogl_attribute_register_attribute_name (CoglContext *context,
const char *name);
CoglAttribute *
_cogl_attribute_immutable_ref (CoglAttribute *attribute);

View File

@ -59,80 +59,11 @@ static void _cogl_attribute_free (CoglAttribute *attribute);
COGL_OBJECT_DEFINE (Attribute, attribute);
#if 0
gboolean
validate_gl_attribute (const char *name,
int n_components,
static gboolean
validate_cogl_attribute_name (const char *name,
CoglAttributeNameID *name_id,
gboolean *normalized,
unsigned int *texture_unit)
{
name = name + 3; /* skip past "gl_" */
*normalized = FALSE;
*texture_unit = 0;
if (strcmp (name, "Vertex") == 0)
{
if (G_UNLIKELY (n_components == 1))
{
g_critical ("glVertexPointer doesn't allow 1 component vertex "
"positions so we currently only support \"gl_Vertex\" "
"attributes where n_components == 2, 3 or 4");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY;
}
else if (strcmp (name, "Color") == 0)
{
if (G_UNLIKELY (n_components != 3 && n_components != 4))
{
g_critical ("glColorPointer expects 3 or 4 component colors so we "
"currently only support \"gl_Color\" attributes where "
"n_components == 3 or 4");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY;
*normalized = TRUE;
}
else if (strncmp (name, "MultiTexCoord", strlen ("MultiTexCoord")) == 0)
{
if (sscanf (gl_attribute, "MultiTexCoord%u", texture_unit) != 1)
{
g_warning ("gl_MultiTexCoord attributes should include a\n"
"texture unit number, E.g. gl_MultiTexCoord0\n");
unit = 0;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY;
}
else if (strncmp (name, "Normal") == 0)
{
if (G_UNLIKELY (n_components != 3))
{
g_critical ("glNormalPointer expects 3 component normals so we "
"currently only support \"gl_Normal\" attributes where "
"n_components == 3");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY;
*normalized = TRUE;
}
else
{
g_warning ("Unknown gl_* attribute name gl_%s\n", name);
return FALSE;
}
return TRUE;
}
#endif
gboolean
validate_cogl_attribute (const char *name,
int n_components,
CoglAttributeNameID *name_id,
gboolean *normalized,
unsigned int *texture_unit)
int *texture_unit)
{
name = name + 5; /* skip "cogl_" */
@ -140,26 +71,11 @@ validate_cogl_attribute (const char *name,
*texture_unit = 0;
if (strcmp (name, "position_in") == 0)
{
if (G_UNLIKELY (n_components == 1))
{
g_critical ("glVertexPointer doesn't allow 1 component vertex "
"positions so we currently only support \"cogl_vertex\" "
"attributes where n_components == 2, 3 or 4");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY;
}
else if (strcmp (name, "color_in") == 0)
{
if (G_UNLIKELY (n_components != 3 && n_components != 4))
{
g_critical ("glColorPointer expects 3 or 4 component colors so we "
"currently only support \"cogl_color\" attributes where "
"n_components == 3 or 4");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY;
*normalized = TRUE;
}
else if (strcmp (name, "tex_coord_in") == 0)
*name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY;
@ -178,13 +94,6 @@ validate_cogl_attribute (const char *name,
}
else if (strcmp (name, "normal_in") == 0)
{
if (G_UNLIKELY (n_components != 3))
{
g_critical ("glNormalPointer expects 3 component normals so we "
"currently only support \"cogl_normal\" attributes "
"where n_components == 3");
return FALSE;
}
*name_id = COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY;
*normalized = TRUE;
}
@ -197,6 +106,49 @@ validate_cogl_attribute (const char *name,
return TRUE;
}
CoglAttributeNameState *
_cogl_attribute_register_attribute_name (CoglContext *context,
const char *name)
{
CoglAttributeNameState *name_state = g_new (CoglAttributeNameState, 1);
int name_index = context->n_attribute_names++;
name_state->name = g_strdup (name);
name_state->name_index = name_index;
if (strncmp (name, "cogl_", 5) == 0)
{
if (!validate_cogl_attribute_name (name,
&name_state->name_id,
&name_state->normalized_default,
&name_state->texture_unit))
goto error;
}
else
{
name_state->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY;
name_state->normalized_default = FALSE;
name_state->texture_unit = 0;
}
g_hash_table_insert (context->attribute_name_states_hash,
name_state->name, name_state);
if (G_UNLIKELY (context->attribute_name_index_map == NULL))
context->attribute_name_index_map =
g_array_new (FALSE, FALSE, sizeof (void *));
g_array_set_size (context->attribute_name_index_map, name_index + 1);
g_array_index (context->attribute_name_index_map,
CoglAttributeNameState *, name_index) = name_state;
return name_state;
error:
g_free (name_state);
return NULL;
}
CoglAttribute *
cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
const char *name,
@ -206,8 +158,20 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
CoglAttributeType type)
{
CoglAttribute *attribute = g_slice_new (CoglAttribute);
gboolean status;
/* FIXME: retrieve the context from the buffer */
_COGL_GET_CONTEXT (ctx, NULL);
attribute->name_state =
g_hash_table_lookup (ctx->attribute_name_states_hash, name);
if (!attribute->name_state)
{
CoglAttributeNameState *name_state =
_cogl_attribute_register_attribute_name (ctx, name);
if (!name_state)
goto error;
attribute->name_state = name_state;
}
attribute->attribute_buffer = cogl_object_ref (attribute_buffer);
attribute->stride = stride;
attribute->offset = offset;
@ -215,71 +179,52 @@ cogl_attribute_new (CoglAttributeBuffer *attribute_buffer,
attribute->type = type;
attribute->immutable_ref = 0;
if (strncmp (name, "cogl_", 5) == 0)
if (attribute->name_state->name_id != COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY)
{
const char *common_tex_coord_names[8] = {
"cogl_tex_coord0_in",
"cogl_tex_coord1_in",
"cogl_tex_coord2_in",
"cogl_tex_coord3_in",
"cogl_tex_coord4_in",
"cogl_tex_coord5_in",
"cogl_tex_coord6_in",
"cogl_tex_coord7_in"
};
status = validate_cogl_attribute (name,
n_components,
&attribute->name_id,
&attribute->normalized,
&attribute->texture_unit);
/* Avoid even the cost of g_intern_string() for the very common case
* attribute names...*/
switch (attribute->name_id)
switch (attribute->name_state->name_id)
{
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
attribute->name = "cogl_position_in";
if (G_UNLIKELY (n_components == 1))
{
g_critical ("glVertexPointer doesn't allow 1 component vertex "
"positions so we currently only support \"cogl_vertex\" "
"attributes where n_components == 2, 3 or 4");
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
attribute->name = "cogl_color_in";
if (G_UNLIKELY (n_components != 3 && n_components != 4))
{
g_critical ("glColorPointer expects 3 or 4 component colors so we "
"currently only support \"cogl_color\" attributes where "
"n_components == 3 or 4");
return FALSE;
}
break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
if (attribute->texture_unit < 8)
attribute->name = common_tex_coord_names[attribute->texture_unit];
else
attribute->name = g_intern_string (name);
break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
attribute->name = "cogl_normal_in";
if (G_UNLIKELY (n_components != 3))
{
g_critical ("glNormalPointer expects 3 component normals so we "
"currently only support \"cogl_normal\" attributes "
"where n_components == 3");
return FALSE;
}
break;
default:
g_warn_if_reached ();
}
attribute->normalized = attribute->name_state->normalized_default;
}
#if 0
else if (strncmp (name, "gl_", 3) == 0)
status = validate_gl_attribute (attribute->name,
n_components,
&attribute->name_id,
&attribute->normalized,
&attribute->texture_unit);
#endif
else
{
attribute->name = g_intern_string (name);
attribute->name_id = COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY;
attribute->normalized = FALSE;
attribute->texture_unit = 0;
status = TRUE;
}
if (!status)
{
_cogl_attribute_free (attribute);
return NULL;
}
return _cogl_attribute_object_new (attribute);
error:
_cogl_attribute_free (attribute);
return NULL;
}
gboolean
@ -428,87 +373,216 @@ validated:
return status;
}
static gboolean
toggle_enabled_cb (int bit_num, void *user_data)
typedef struct _ForeachChangedBitState
{
const CoglBitmask *new_values = user_data;
gboolean enabled = _cogl_bitmask_get (new_values, bit_num);
CoglContext *context;
const CoglBitmask *new_bits;
CoglPipeline *pipeline;
} ForeachChangedBitState;
_COGL_GET_CONTEXT (ctx, FALSE);
static gboolean
toggle_builtin_attribute_enabled_cb (int bit_num, void *user_data)
{
ForeachChangedBitState *state = user_data;
CoglContext *context = state->context;
_COGL_RETURN_VAL_IF_FAIL (context->driver == COGL_DRIVER_GL ||
context->driver == COGL_DRIVER_GLES1,
FALSE);
if (ctx->driver == COGL_DRIVER_GLES2)
{
if (enabled)
GE( ctx, glEnableVertexAttribArray (bit_num) );
else
GE( ctx, glDisableVertexAttribArray (bit_num) );
}
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
else
{
GE( ctx, glClientActiveTexture (GL_TEXTURE0 + bit_num) );
gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num);
GLenum cap;
switch (bit_num)
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
cap = GL_COLOR_ARRAY;
break;
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
cap = GL_VERTEX_ARRAY;
break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
cap = GL_NORMAL_ARRAY;
break;
}
if (enabled)
GE( ctx, glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
GE (context, glEnableClientState (cap));
else
GE( ctx, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
GE (context, glDisableClientState (cap));
}
#endif
return TRUE;
}
static void
set_enabled_arrays (CoglBitmask *value_cache,
const CoglBitmask *new_values)
static gboolean
toggle_texcood_attribute_enabled_cb (int bit_num, void *user_data)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
ForeachChangedBitState *state = user_data;
CoglContext *context = state->context;
/* Get the list of bits that are different */
_cogl_bitmask_clear_all (&ctx->arrays_to_change);
_cogl_bitmask_set_bits (&ctx->arrays_to_change, value_cache);
_cogl_bitmask_xor_bits (&ctx->arrays_to_change, new_values);
_COGL_RETURN_VAL_IF_FAIL (context->driver == COGL_DRIVER_GL ||
context->driver == COGL_DRIVER_GLES1,
FALSE);
/* Iterate over each bit to change */
_cogl_bitmask_foreach (&ctx->arrays_to_change,
toggle_enabled_cb,
(void *) new_values);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
{
gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num);
/* Store the new values */
_cogl_bitmask_clear_all (value_cache);
_cogl_bitmask_set_bits (value_cache, new_values);
GE( context, glClientActiveTexture (GL_TEXTURE0 + bit_num) );
if (enabled)
GE( context, glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
else
GE( context, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
}
#endif
return TRUE;
}
static CoglHandle
enable_gl_state (CoglDrawFlags flags,
static gboolean
toggle_custom_attribute_enabled_cb (int bit_num, void *user_data)
{
ForeachChangedBitState *state = user_data;
gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num);
CoglContext *context = state->context;
if (enabled)
GE( context, glEnableVertexAttribArray (bit_num) );
else
GE( context, glDisableVertexAttribArray (bit_num) );
return TRUE;
}
static void
foreach_changed_bit_and_save (CoglContext *context,
CoglBitmask *current_bits,
const CoglBitmask *new_bits,
CoglBitmaskForeachFunc callback,
ForeachChangedBitState *state)
{
/* Get the list of bits that are different */
_cogl_bitmask_clear_all (&context->changed_bits_tmp);
_cogl_bitmask_set_bits (&context->changed_bits_tmp, current_bits);
_cogl_bitmask_xor_bits (&context->changed_bits_tmp, new_bits);
/* Iterate over each bit to change */
state->new_bits = new_bits;
_cogl_bitmask_foreach (&context->changed_bits_tmp,
callback,
state);
/* Store the new values */
_cogl_bitmask_clear_all (current_bits);
_cogl_bitmask_set_bits (current_bits, new_bits);
}
static void
setup_generic_attribute (CoglContext *context,
CoglPipeline *pipeline,
CoglAttribute *attribute,
guint8 *base)
{
int name_index = attribute->name_state->name_index;
int attrib_location =
_cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index);
if (attrib_location != -1)
{
GE( context, glVertexAttribPointer (attrib_location,
attribute->n_components,
attribute->type,
attribute->normalized,
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&context->enable_custom_attributes_tmp,
attrib_location, TRUE);
}
}
static void
apply_attribute_enable_updates (CoglContext *context,
CoglPipeline *pipeline)
{
ForeachChangedBitState changed_bits_state;
changed_bits_state.context = context;
changed_bits_state.new_bits = &context->enable_builtin_attributes_tmp;
changed_bits_state.pipeline = pipeline;
foreach_changed_bit_and_save (context,
&context->enabled_builtin_attributes,
&context->enable_builtin_attributes_tmp,
toggle_builtin_attribute_enabled_cb,
&changed_bits_state);
changed_bits_state.new_bits = &context->enable_texcoord_attributes_tmp;
foreach_changed_bit_and_save (context,
&context->enabled_texcoord_attributes,
&context->enable_texcoord_attributes_tmp,
toggle_texcood_attribute_enabled_cb,
&changed_bits_state);
changed_bits_state.new_bits = &context->enable_custom_attributes_tmp;
foreach_changed_bit_and_save (context,
&context->enabled_custom_attributes,
&context->enable_custom_attributes_tmp,
toggle_custom_attribute_enabled_cb,
&changed_bits_state);
}
static CoglPipeline *
flush_state (CoglDrawFlags flags,
CoglAttribute **attributes,
int n_attributes,
ValidateLayerState *state)
{
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
int i;
GLuint generic_index = 0;
unsigned long enable_flags = 0;
gboolean skip_gl_color = FALSE;
CoglPipeline *source;
CoglPipeline *source = cogl_get_source ();
CoglPipeline *copy = NULL;
int n_tex_coord_attribs = 0;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
_cogl_journal_flush (framebuffer->journal, framebuffer);
state->unit = 0;
state->options.flags = 0;
state->fallback_layers = 0;
if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION))
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
_cogl_get_read_framebuffer (),
COGL_FRAMEBUFFER_STATE_ALL);
/* In cogl_read_pixels we have a fast-path when reading a single
* pixel and the scene is just comprised of simple rectangles still
* in the journal. For this optimization to work we need to track
* when the framebuffer really does get drawn to. */
_cogl_framebuffer_dirty (framebuffer);
source = cogl_get_source ();
/* Iterate the attributes to work out whether blending needs to be
enabled and how many texture coords there are. We need to do this
before flushing the pipeline. */
for (i = 0; i < n_attributes; i++)
switch (attributes[i]->name_id)
switch (attributes[i]->name_state->name_id)
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 &&
@ -589,11 +663,13 @@ enable_gl_state (CoglDrawFlags flags,
_cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs);
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp);
/* Bind the attribute pointers. We need to do this after the
pipeline is flushed because on GLES2 that is the only point when
we can determine the attribute locations */
* pipeline is flushed because when using GLSL that is the only
* point when we can determine the attribute locations */
for (i = 0; i < n_attributes; i++)
{
@ -601,156 +677,77 @@ enable_gl_state (CoglDrawFlags flags,
CoglAttributeBuffer *attribute_buffer;
CoglBuffer *buffer;
guint8 *base;
#ifdef HAVE_COGL_GLES2
int attrib_location;
#endif
attribute_buffer = cogl_attribute_get_buffer (attribute);
buffer = COGL_BUFFER (attribute_buffer);
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_ATTRIBUTE_BUFFER);
switch (attribute->name_id)
switch (attribute->name_state->name_id)
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
attrib_location =
_cogl_pipeline_progend_glsl_get_color_attribute (source);
if (attrib_location != -1)
{
GE( ctx,
glVertexAttribPointer (attrib_location,
attribute->n_components,
attribute->type,
TRUE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
}
setup_generic_attribute (ctx, source, attribute, base);
else
#endif
{
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
/* GE (ctx, glEnableClientState (GL_COLOR_ARRAY)); */
_cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY, TRUE);
GE (ctx, glColorPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
}
break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
attrib_location =
_cogl_pipeline_progend_glsl_get_normal_attribute (source);
if (attrib_location != -1)
{
GE( ctx,
glVertexAttribPointer (attrib_location,
attribute->n_components,
attribute->type,
TRUE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
}
setup_generic_attribute (ctx, source, attribute, base);
#endif
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->driver != COGL_DRIVER_GLES2)
{
/* FIXME: go through cogl cache to enable normal array */
GE (ctx, glEnableClientState (GL_NORMAL_ARRAY));
_cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY, TRUE);
GE (ctx, glNormalPointer (attribute->type,
attribute->stride,
base + attribute->offset));
}
#endif
break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
attrib_location =
_cogl_pipeline_progend_glsl_get_tex_coord_attribute
(source, attribute->texture_unit);
if (attrib_location != -1)
{
GE( ctx,
glVertexAttribPointer (attrib_location,
attribute->n_components,
attribute->type,
FALSE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
}
setup_generic_attribute (ctx, source, attribute, base);
else
#endif
{
GE (ctx, glClientActiveTexture (GL_TEXTURE0 +
attribute->texture_unit));
_cogl_bitmask_set (&ctx->enable_texcoord_attributes_tmp,
attribute->name_state->texture_unit, TRUE);
GE (ctx,
glClientActiveTexture (GL_TEXTURE0 +
attribute->name_state->texture_unit));
GE (ctx, glTexCoordPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
_cogl_bitmask_set (&ctx->temp_bitmask,
attribute->texture_unit, TRUE);
}
break;
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
attrib_location =
_cogl_pipeline_progend_glsl_get_position_attribute (source);
if (attrib_location != -1)
{
GE( ctx,
glVertexAttribPointer (attrib_location,
attribute->n_components,
attribute->type,
FALSE, /* normalize */
attribute->stride,
base + attribute->offset) );
_cogl_bitmask_set (&ctx->temp_bitmask, attrib_location, TRUE);
}
}
setup_generic_attribute (ctx, source, attribute, base);
else
#endif
{
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
/* GE (ctx, glEnableClientState (GL_VERTEX_ARRAY)); */
_cogl_bitmask_set (&ctx->enable_builtin_attributes_tmp,
COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY, TRUE);
GE (ctx, glVertexPointer (attribute->n_components,
attribute->type,
attribute->stride,
base + attribute->offset));
}
break;
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
if (ctx->driver != COGL_DRIVER_GLES1)
{
/* FIXME: go through cogl cache to enable generic array. */
/* FIXME: this is going to end up just using the builtins
on GLES 2 */
GE (ctx, glEnableVertexAttribArray (generic_index++));
GE (ctx, glVertexAttribPointer (generic_index,
attribute->n_components,
attribute->type,
attribute->normalized,
attribute->stride,
base + attribute->offset));
}
setup_generic_attribute (ctx, source, attribute, base);
break;
default:
g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
@ -759,10 +756,7 @@ enable_gl_state (CoglDrawFlags flags,
_cogl_buffer_unbind (buffer);
}
/* Flush the state of the attribute arrays */
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
_cogl_enable (enable_flags);
apply_attribute_enable_updates (ctx, source);
return source;
}
@ -772,60 +766,14 @@ _cogl_attribute_disable_cached_arrays (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
set_enabled_arrays (&ctx->arrays_enabled, &ctx->temp_bitmask);
}
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_custom_attributes_tmp);
/* FIXME: we shouldn't be disabling state after drawing we should
* just disable the things not needed after enabling state. */
static void
disable_gl_state (CoglAttribute **attributes,
int n_attributes,
CoglPipeline *source)
{
GLuint generic_index = 0;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (G_UNLIKELY (source != cogl_get_source ()))
cogl_object_unref (source);
for (i = 0; i < n_attributes; i++)
{
CoglAttribute *attribute = attributes[i];
switch (attribute->name_id)
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
/* GE (ctx, glDisableClientState (GL_COLOR_ARRAY)); */
break;
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
/* FIXME: go through cogl cache to enable normal array */
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GL)
if (ctx->driver != COGL_DRIVER_GLES2)
GE (ctx, glDisableClientState (GL_NORMAL_ARRAY));
#endif
break;
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
/* The enabled state of the texture coord arrays is
cached in ctx->enabled_texcoord_arrays so we don't
need to do anything here. The array will be disabled
by the next drawing primitive if it is not
required */
break;
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
/* GE (ctx, glDisableClientState (GL_VERTEX_ARRAY)); */
break;
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
if (ctx->driver != COGL_DRIVER_GLES1)
/* FIXME: go through cogl cache to enable generic array */
GE (ctx, glDisableVertexAttribArray (generic_index++));
break;
default:
g_warning ("Unrecognised attribute type 0x%08x", attribute->type);
}
}
/* XXX: we can pass a NULL source pipeline here because we know a
* source pipeline only needs to be referenced when enabling
* attributes. */
apply_attribute_enable_updates (ctx, NULL);
}
#ifdef COGL_ENABLE_DEBUG
@ -1020,7 +968,8 @@ draw_wireframe (CoglVerticesMode mode,
for (i = 0; i < n_attributes; i++)
{
if (strcmp (attributes[i]->name, "cogl_position_in") == 0)
if (attributes[i]->name_state->name_id ==
COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY)
{
position = attributes[i];
break;
@ -1073,37 +1022,6 @@ draw_wireframe (CoglVerticesMode mode,
}
#endif
static void
flush_state (CoglDrawFlags flags,
ValidateLayerState *state)
{
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
{
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
_cogl_journal_flush (framebuffer->journal, framebuffer);
}
state->unit = 0;
state->options.flags = 0;
state->fallback_layers = 0;
if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION))
cogl_pipeline_foreach_layer (cogl_get_source (),
validate_layer_cb,
state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. We need to do this
* before setting up the array pointers because setting up the clip
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
_cogl_get_read_framebuffer (),
COGL_FRAMEBUFFER_STATE_ALL);
}
/* This can be called directly by the CoglJournal to draw attributes
* skipping the implicit journal flush, the framebuffer flush and
* pipeline validation. */
@ -1120,15 +1038,12 @@ _cogl_draw_attributes (CoglVerticesMode mode,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
flush_state (flags, &state);
source = enable_gl_state (flags, attributes, n_attributes, &state);
source = flush_state (flags, attributes, n_attributes, &state);
GE (ctx, glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
/* FIXME: we shouldn't be disabling state after drawing we should
* just disable the things not needed after enabling state. */
disable_gl_state (attributes, n_attributes, source);
if (G_UNLIKELY (source != cogl_get_source ()))
cogl_object_unref (source);
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
@ -1212,9 +1127,7 @@ _cogl_draw_indexed_attributes (CoglVerticesMode mode,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
flush_state (flags, &state);
source = enable_gl_state (flags, attributes, n_attributes, &state);
source = flush_state (flags, attributes, n_attributes, &state);
buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
@ -1241,9 +1154,8 @@ _cogl_draw_indexed_attributes (CoglVerticesMode mode,
_cogl_buffer_unbind (buffer);
/* FIXME: we shouldn't be disabling state after drawing we should
* just disable the things not needed after enabling state. */
disable_gl_state (attributes, n_attributes, source);
if (G_UNLIKELY (source != cogl_get_source ()))
cogl_object_unref (source);
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))

View File

@ -72,8 +72,21 @@ struct _CoglContext
CoglHandle default_layer_n;
CoglHandle dummy_layer_dependant;
/* Enable cache */
unsigned long enable_flags;
GHashTable *attribute_name_states_hash;
GArray *attribute_name_index_map;
int n_attribute_names;
CoglBitmask enabled_builtin_attributes;
CoglBitmask enabled_texcoord_attributes;
CoglBitmask enabled_custom_attributes;
/* These are temporary bitmasks that are used when disabling
* builtin,texcoord and custom attribute arrays. They are here just
* to avoid allocating new ones each time */
CoglBitmask enable_builtin_attributes_tmp;
CoglBitmask enable_texcoord_attributes_tmp;
CoglBitmask enable_custom_attributes_tmp;
CoglBitmask changed_bits_tmp;
gboolean legacy_backface_culling_enabled;
@ -129,16 +142,6 @@ struct _CoglContext
gboolean current_pipeline_skip_gl_color;
unsigned long current_pipeline_age;
/* Bitmask of attributes enabled. On GLES2 these are the vertex
attribute numbers and on regular GL these are only used for the
texture coordinate arrays */
CoglBitmask arrays_enabled;
/* These are temporary bitmasks that are used when disabling
texcoord arrays. They are here just to avoid allocating new ones
each time */
CoglBitmask arrays_to_change;
CoglBitmask temp_bitmask;
gboolean gl_blend_enable_cache;
gboolean depth_test_enabled_cache;

View File

@ -43,6 +43,7 @@
#include "cogl-framebuffer-private.h"
#include "cogl-onscreen-private.h"
#include "cogl2-path.h"
#include "cogl-attribute-private.h"
#include <string.h>
@ -129,7 +130,6 @@ cogl_context_new (CoglDisplay *display,
{
CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
unsigned long enable_flags = 0;
const CoglWinsysVtable *winsys;
int i;
@ -221,6 +221,16 @@ cogl_context_new (CoglDisplay *display,
g_assert_not_reached ();
}
context->attribute_name_states_hash =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
context->attribute_name_index_map = NULL;
context->n_attribute_names = 0;
/* The "cogl_color_in" attribute needs a deterministic name_index
* so we make sure it's the first attribute name we register */
_cogl_attribute_register_attribute_name (context, "cogl_color_in");
context->uniform_names =
g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
@ -234,7 +244,6 @@ cogl_context_new (CoglDisplay *display,
_cogl_pipeline_init_state_hash_functions ();
_cogl_pipeline_init_layer_state_hash_functions ();
context->enable_flags = 0;
context->current_clip_stack_valid = FALSE;
context->current_clip_stack = NULL;
@ -284,9 +293,13 @@ cogl_context_new (CoglDisplay *display,
context->current_pipeline_changes_since_flush = 0;
context->current_pipeline_skip_gl_color = FALSE;
_cogl_bitmask_init (&context->arrays_enabled);
_cogl_bitmask_init (&context->temp_bitmask);
_cogl_bitmask_init (&context->arrays_to_change);
_cogl_bitmask_init (&context->enabled_builtin_attributes);
_cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
_cogl_bitmask_init (&context->enabled_texcoord_attributes);
_cogl_bitmask_init (&context->enable_texcoord_attributes_tmp);
_cogl_bitmask_init (&context->enabled_custom_attributes);
_cogl_bitmask_init (&context->enable_custom_attributes_tmp);
_cogl_bitmask_init (&context->changed_bits_tmp);
context->max_texture_units = -1;
context->max_activateable_texture_units = -1;
@ -385,7 +398,6 @@ cogl_context_new (CoglDisplay *display,
cogl_push_source (context->opaque_color_pipeline);
_cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
_cogl_enable (enable_flags);
context->atlases = NULL;
g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));
@ -468,9 +480,13 @@ _cogl_context_free (CoglContext *context)
g_slist_free (context->atlases);
g_hook_list_clear (&context->atlas_reorganize_callbacks);
_cogl_bitmask_destroy (&context->arrays_enabled);
_cogl_bitmask_destroy (&context->temp_bitmask);
_cogl_bitmask_destroy (&context->arrays_to_change);
_cogl_bitmask_destroy (&context->enabled_builtin_attributes);
_cogl_bitmask_destroy (&context->enable_builtin_attributes_tmp);
_cogl_bitmask_destroy (&context->enabled_texcoord_attributes);
_cogl_bitmask_destroy (&context->enable_texcoord_attributes_tmp);
_cogl_bitmask_destroy (&context->enabled_custom_attributes);
_cogl_bitmask_destroy (&context->enable_custom_attributes_tmp);
_cogl_bitmask_destroy (&context->changed_bits_tmp);
g_slist_free (context->texture_types);
g_slist_free (context->buffer_types);
@ -490,6 +506,9 @@ _cogl_context_free (CoglContext *context)
g_ptr_array_free (context->uniform_names, TRUE);
g_hash_table_destroy (context->uniform_name_hash);
g_hash_table_destroy (context->attribute_name_states_hash);
g_array_free (context->attribute_name_index_map, TRUE);
g_byte_array_free (context->buffer_map_fallback_array, TRUE);
cogl_object_unref (context->display);

View File

@ -1372,8 +1372,10 @@ done:
int attribute;
CoglPipeline *authority =
_cogl_pipeline_get_authority (pipeline, COGL_PIPELINE_STATE_COLOR);
int name_index = COGL_ATTRIBUTE_COLOR_NAME_INDEX;
attribute = _cogl_pipeline_progend_glsl_get_color_attribute (pipeline);
attribute =
_cogl_pipeline_progend_glsl_get_attrib_location (pipeline, name_index);
if (attribute != -1)
GE (ctx,
glVertexAttrib4f (attribute,

View File

@ -33,22 +33,9 @@
extern const CoglPipelineProgend _cogl_pipeline_glsl_progend;
#ifdef HAVE_COGL_GLES2
int
_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline);
int
_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline);
int
_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline);
int
_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline,
int unit);
#endif /* HAVE_COGL_GLES2 */
_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline,
int name_index);
#endif /* __COGL_PIPELINE_PROGEND_GLSL_PRIVATE_H */

View File

@ -47,6 +47,7 @@
#include "cogl-pipeline-vertend-glsl-private.h"
#include "cogl-pipeline-cache.h"
#include "cogl-pipeline-state-private.h"
#include "cogl-attribute-private.h"
#ifdef HAVE_COGL_GLES2
@ -116,18 +117,6 @@ typedef struct
unsigned long dirty_builtin_uniforms;
GLint builtin_uniform_locations[G_N_ELEMENTS (builtin_uniforms)];
/* Under GLES2 we can't use the builtin functions to set attribute
pointers such as the vertex position. Instead the vertex
attribute code needs to query the attribute numbers from the
progend backend */
int position_attribute_location;
int color_attribute_location;
int normal_attribute_location;
int tex_coord0_attribute_location;
/* We only allocate this array if more than one tex coord attribute
is requested because most pipelines will only use one layer */
GArray *tex_coord_attribute_locations;
GLint modelview_uniform;
GLint projection_uniform;
GLint mvp_uniform;
@ -148,6 +137,9 @@ typedef struct
uniform is actually set */
GArray *uniform_locations;
/* Array of attribute locations. */
GArray *attribute_locations;
UnitState *unit_state;
} CoglPipelineProgramState;
@ -161,8 +153,6 @@ get_program_state (CoglPipeline *pipeline)
#define UNIFORM_LOCATION_UNKNOWN -2
#ifdef HAVE_COGL_GLES2
#define ATTRIBUTE_LOCATION_UNKNOWN -2
/* Under GLES2 the vertex attribute API needs to query the attribute
@ -172,125 +162,66 @@ get_program_state (CoglPipeline *pipeline)
cache. This should always be called after the pipeline is flushed
so they can assert that the gl program is valid */
int
_cogl_pipeline_progend_glsl_get_position_attribute (CoglPipeline *pipeline)
{
CoglPipelineProgramState *program_state = get_program_state (pipeline);
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (program_state->position_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
GE_RET( program_state->position_attribute_location,
ctx, glGetAttribLocation (program_state->program,
"cogl_position_in") );
return program_state->position_attribute_location;
}
/* All attributes names get internally mapped to a global set of
* sequential indices when they are setup which we need to need to
* then be able to map to a GL attribute location once we have
* a linked GLSL program */
int
_cogl_pipeline_progend_glsl_get_color_attribute (CoglPipeline *pipeline)
_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline,
int name_index)
{
CoglPipelineProgramState *program_state = get_program_state (pipeline);
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (program_state->color_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
GE_RET( program_state->color_attribute_location,
ctx, glGetAttribLocation (program_state->program,
"cogl_color_in") );
return program_state->color_attribute_location;
}
int
_cogl_pipeline_progend_glsl_get_normal_attribute (CoglPipeline *pipeline)
{
CoglPipelineProgramState *program_state = get_program_state (pipeline);
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (program_state->normal_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
GE_RET( program_state->normal_attribute_location,
ctx, glGetAttribLocation (program_state->program,
"cogl_normal_in") );
return program_state->normal_attribute_location;
}
int
_cogl_pipeline_progend_glsl_get_tex_coord_attribute (CoglPipeline *pipeline,
int unit)
{
CoglPipelineProgramState *program_state = get_program_state (pipeline);
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (unit == 0)
{
if (program_state->tex_coord0_attribute_location ==
ATTRIBUTE_LOCATION_UNKNOWN)
GE_RET( program_state->tex_coord0_attribute_location,
ctx, glGetAttribLocation (program_state->program,
"cogl_tex_coord0_in") );
return program_state->tex_coord0_attribute_location;
}
else
{
char *name = g_strdup_printf ("cogl_tex_coord%i_in", unit);
int *locations;
if (program_state->tex_coord_attribute_locations == NULL)
program_state->tex_coord_attribute_locations =
_COGL_GET_CONTEXT (ctx, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state != NULL, -1);
_COGL_RETURN_VAL_IF_FAIL (program_state->program != 0, -1);
if (G_UNLIKELY (program_state->attribute_locations == NULL))
program_state->attribute_locations =
g_array_new (FALSE, FALSE, sizeof (int));
if (program_state->tex_coord_attribute_locations->len <= unit - 1)
if (G_UNLIKELY (program_state->attribute_locations->len <= name_index))
{
int i = program_state->tex_coord_attribute_locations->len;
g_array_set_size (program_state->tex_coord_attribute_locations, unit);
for (; i < unit; i++)
g_array_index (program_state->tex_coord_attribute_locations, int, i)
int i = program_state->attribute_locations->len;
g_array_set_size (program_state->attribute_locations, name_index + 1);
for (; i < program_state->attribute_locations->len; i++)
g_array_index (program_state->attribute_locations, int, i)
= ATTRIBUTE_LOCATION_UNKNOWN;
}
locations = &g_array_index (program_state->tex_coord_attribute_locations,
int, 0);
locations = &g_array_index (program_state->attribute_locations, int, 0);
if (locations[unit - 1] == ATTRIBUTE_LOCATION_UNKNOWN)
GE_RET( locations[unit - 1],
ctx, glGetAttribLocation (program_state->program, name) );
if (locations[name_index] == ATTRIBUTE_LOCATION_UNKNOWN)
{
CoglAttributeNameState *name_state =
g_array_index (ctx->attribute_name_index_map,
CoglAttributeNameState *, name_index);
g_free (name);
_COGL_RETURN_VAL_IF_FAIL (name_state != NULL, 0);
return locations[unit - 1];
GE_RET( locations[name_index],
ctx, glGetAttribLocation (program_state->program,
name_state->name) );
}
return locations[name_index];
}
static void
clear_attribute_cache (CoglPipelineProgramState *program_state)
{
program_state->position_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
program_state->color_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
program_state->normal_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
program_state->tex_coord0_attribute_location = ATTRIBUTE_LOCATION_UNKNOWN;
if (program_state->tex_coord_attribute_locations)
if (program_state->attribute_locations)
{
g_array_free (program_state->tex_coord_attribute_locations, TRUE);
program_state->tex_coord_attribute_locations = NULL;
g_array_free (program_state->attribute_locations, TRUE);
program_state->attribute_locations = NULL;
}
}
#ifdef HAVE_COGL_GLES2
static void
clear_flushed_matrix_stacks (CoglPipelineProgramState *program_state)
{
@ -320,8 +251,8 @@ program_state_new (int n_layers)
program_state->n_tex_coord_attribs = 0;
program_state->unit_state = g_new (UnitState, n_layers);
program_state->uniform_locations = NULL;
program_state->attribute_locations = NULL;
#ifdef HAVE_COGL_GLES2
program_state->tex_coord_attribute_locations = NULL;
program_state->flushed_modelview_stack = NULL;
program_state->flushed_modelview_is_identity = FALSE;
program_state->flushed_projection_stack = NULL;
@ -347,12 +278,11 @@ destroy_program_state (void *user_data,
if (--program_state->ref_count == 0)
{
clear_attribute_cache (program_state);
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
{
clear_attribute_cache (program_state);
clear_flushed_matrix_stacks (program_state);
}
#endif
if (program_state->program)
@ -858,9 +788,12 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
state.program_state = program_state;
if (program_changed)
{
cogl_pipeline_foreach_layer (pipeline,
get_uniform_cb,
&state);
clear_attribute_cache (program_state);
}
state.unit = 0;
state.update_all = (program_changed ||
@ -877,7 +810,6 @@ _cogl_pipeline_progend_glsl_end (CoglPipeline *pipeline,
{
int i;
clear_attribute_cache (program_state);
clear_flushed_matrix_stacks (program_state);
for (i = 0; i < G_N_ELEMENTS (builtin_uniforms); i++)

View File

@ -141,69 +141,6 @@ cogl_clear (const CoglColor *color, unsigned long buffers)
cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color);
}
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
static gboolean
toggle_client_flag (CoglContext *ctx,
unsigned long new_flags,
unsigned long flag,
GLenum gl_flag)
{
_COGL_RETURN_VAL_IF_FAIL (ctx->driver != COGL_DRIVER_GLES2, FALSE);
/* Toggles and caches a single client-side enable flag
* on or off by comparing to current state
*/
if (new_flags & flag)
{
if (!(ctx->enable_flags & flag))
{
GE( ctx, glEnableClientState (gl_flag) );
ctx->enable_flags |= flag;
return TRUE;
}
}
else if (ctx->enable_flags & flag)
{
GE( ctx, glDisableClientState (gl_flag) );
ctx->enable_flags &= ~flag;
}
return FALSE;
}
#endif
void
_cogl_enable (unsigned long flags)
{
/* This function essentially caches glEnable state() in the
* hope of lessening number GL traffic.
*/
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
if (ctx->driver != COGL_DRIVER_GLES2)
{
toggle_client_flag (ctx, flags,
COGL_ENABLE_VERTEX_ARRAY,
GL_VERTEX_ARRAY);
toggle_client_flag (ctx, flags,
COGL_ENABLE_COLOR_ARRAY,
GL_COLOR_ARRAY);
}
#endif
}
unsigned long
_cogl_get_enable (void)
{
_COGL_GET_CONTEXT (ctx, 0);
return ctx->enable_flags;
}
/* XXX: This API has been deprecated */
void
cogl_set_depth_test_enabled (gboolean setting)
@ -645,7 +582,6 @@ cogl_read_pixels (int x,
void
cogl_begin_gl (void)
{
unsigned long enable_flags = 0;
CoglPipeline *pipeline;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -697,8 +633,6 @@ cogl_begin_gl (void)
FALSE,
cogl_pipeline_get_n_layers (pipeline));
_cogl_enable (enable_flags);
/* Disable any cached vertex arrays */
_cogl_attribute_disable_cached_arrays ();
}