[cogl/wip/virtual-framebuffer: 21/22] rework enabling of attributes, removing _cogl_enable()
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/virtual-framebuffer: 21/22] rework enabling of attributes, removing _cogl_enable()
- Date: Tue, 29 Nov 2011 12:47:25 +0000 (UTC)
commit 2469065904b76de2519b2709f1211fb0177fcce3
Author: Robert Bragg <robert linux intel com>
Date: Thu Nov 24 18:09:53 2011 +0000
rework enabling of attributes, removing _cogl_enable()
cogl/cogl-attribute-private.h | 23 +-
cogl/cogl-attribute.c | 709 +++++++++++++----------------
cogl/cogl-context-private.h | 27 +-
cogl/cogl-context.c | 37 ++-
cogl/cogl-pipeline-opengl.c | 4 +-
cogl/cogl-pipeline-progend-glsl-private.h | 17 +-
cogl/cogl-pipeline-progend-glsl.c | 162 ++-----
cogl/cogl.c | 66 ---
8 files changed, 435 insertions(+), 610 deletions(-)
---
diff --git a/cogl/cogl-attribute-private.h b/cogl/cogl-attribute-private.h
index 040784e..68ed52d 100644
--- a/cogl/cogl-attribute-private.h
+++ b/cogl/cogl-attribute-private.h
@@ -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);
diff --git a/cogl/cogl-attribute.c b/cogl/cogl-attribute.c
index ad525f6..755cea7 100644
--- a/cogl/cogl-attribute.c
+++ b/cogl/cogl-attribute.c
@@ -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,
- 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)
+static gboolean
+validate_cogl_attribute_name (const char *name,
+ CoglAttributeNameID *name_id,
+ gboolean *normalized,
+ int *texture_unit)
{
name = name + 5; /* skip "cogl_" */
@@ -140,27 +71,9 @@ 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;
- }
+ *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;
- }
+ *name_id = COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY;
else if (strcmp (name, "tex_coord_in") == 0)
*name_id = COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY;
else if (strncmp (name, "tex_coord", strlen ("tex_coord")) == 0)
@@ -178,13 +91,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 +103,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 +155,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 +176,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;
- }
+ attribute->normalized = FALSE;
return _cogl_attribute_object_new (attribute);
+
+error:
+ _cogl_attribute_free (attribute);
+ return NULL;
}
gboolean
@@ -428,87 +370,238 @@ validated:
return status;
}
+typedef struct _ForeachChangedBitState
+{
+ CoglContext *context;
+ const CoglBitmask *new_bits;
+ CoglPipeline *pipeline;
+} ForeachChangedBitState;
+
static gboolean
-toggle_enabled_cb (int bit_num, void *user_data)
+toggle_builtin_attribute_enabled_cb (int bit_num, void *user_data)
{
- const CoglBitmask *new_values = user_data;
- gboolean enabled = _cogl_bitmask_get (new_values, bit_num);
+ ForeachChangedBitState *state = user_data;
+ gboolean enabled = _cogl_bitmask_get (state->new_bits, bit_num);
+ CoglContext *context = state->context;
+ GLenum cap;
- _COGL_GET_CONTEXT (ctx, FALSE);
+ 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 (context, glEnableClientState (cap));
+ else
+ GE (context, glDisableClientState (cap));
+
+ return TRUE;
+}
+
+static gboolean
+toggle_texcood_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;
+
+ GE( context, glClientActiveTexture (GL_TEXTURE0 + bit_num) );
+
+ if (enabled)
+ GE( context, glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
+ else
+ GE( context, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
+
+ return TRUE;
+}
- if (ctx->driver == COGL_DRIVER_GLES2)
+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;
+ int enable_location;
+ int disable_location;
+
+ if (enabled)
{
- if (enabled)
- GE( ctx, glEnableVertexAttribArray (bit_num) );
- else
- GE( ctx, glDisableVertexAttribArray (bit_num) );
+ CoglPipeline *pipeline = state->pipeline;
+ CoglPipeline *prev_pipeline = context->current_pipeline;
+
+ enable_location =
+ _cogl_pipeline_progend_glsl_get_attrib_location (pipeline, bit_num);
+
+ if (G_LIKELY (prev_pipeline))
+ {
+ disable_location =
+ _cogl_pipeline_progend_glsl_get_attrib_location (prev_pipeline,
+ bit_num);
+
+ if (enable_location != disable_location)
+ GE( context, glDisableVertexAttribArray (disable_location) );
+ }
+
+ GE( context, glEnableVertexAttribArray (enable_location) );
}
-#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
else
{
- GE( ctx, glClientActiveTexture (GL_TEXTURE0 + bit_num) );
+ CoglPipeline *prev_pipeline = context->current_pipeline;
- if (enabled)
- GE( ctx, glEnableClientState (GL_TEXTURE_COORD_ARRAY) );
- else
- GE( ctx, glDisableClientState (GL_TEXTURE_COORD_ARRAY) );
+ /* XXX: we only expect ctx->current_pipeline to be NULL the
+ * first time we are flushing a pipeline so we should never need
+ * to be disabling anything in that case.
+ *
+ * If we later change things so ctx->current_pipeline can be
+ * NULL at other times then this code will be affected because
+ * we need a way of mapping a name_index to a GLSL program
+ * attribute location which is currently only possible via the
+ * CoglPipelineProgramState associated with the currently
+ * flushed pipeline. */
+ _COGL_RETURN_VAL_IF_FAIL (prev_pipeline != NULL, TRUE);
+
+ disable_location =
+ _cogl_pipeline_progend_glsl_get_attrib_location (prev_pipeline,
+ bit_num);
+
+ GE( context, glDisableVertexAttribArray (disable_location) );
}
-#endif
return TRUE;
}
static void
-set_enabled_arrays (CoglBitmask *value_cache,
- const CoglBitmask *new_values)
+foreach_changed_bit_and_save (CoglContext *context,
+ CoglBitmask *current_bits,
+ const CoglBitmask *new_bits,
+ CoglBitmaskForeachFunc callback,
+ ForeachChangedBitState *state)
{
- _COGL_GET_CONTEXT (ctx, NO_RETVAL);
-
/* 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_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 */
- _cogl_bitmask_foreach (&ctx->arrays_to_change,
- toggle_enabled_cb,
- (void *) new_values);
+ state->new_bits = new_bits;
+ _cogl_bitmask_foreach (&context->changed_bits_tmp,
+ callback,
+ state);
/* Store the new values */
- _cogl_bitmask_clear_all (value_cache);
- _cogl_bitmask_set_bits (value_cache, new_values);
+ _cogl_bitmask_clear_all (current_bits);
+ _cogl_bitmask_set_bits (current_bits, new_bits);
}
-static CoglHandle
-enable_gl_state (CoglDrawFlags flags,
- CoglAttribute **attributes,
- int n_attributes,
- ValidateLayerState *state)
+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->enabled_custom_attributes,
+ 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 +682,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 +696,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 +775,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 +785,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 +987,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 +1041,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 +1057,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 +1146,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 +1173,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)))
diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
index 9f2e178..f8b9cf0 100644
--- a/cogl/cogl-context-private.h
+++ b/cogl/cogl-context-private.h
@@ -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;
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index f474538..08b527e 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -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);
diff --git a/cogl/cogl-pipeline-opengl.c b/cogl/cogl-pipeline-opengl.c
index 92d75ea..aaf5ea8 100644
--- a/cogl/cogl-pipeline-opengl.c
+++ b/cogl/cogl-pipeline-opengl.c
@@ -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,
diff --git a/cogl/cogl-pipeline-progend-glsl-private.h b/cogl/cogl-pipeline-progend-glsl-private.h
index c100269..a080204 100644
--- a/cogl/cogl-pipeline-progend-glsl-private.h
+++ b/cogl/cogl-pipeline-progend-glsl-private.h
@@ -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 */
diff --git a/cogl/cogl-pipeline-progend-glsl.c b/cogl/cogl-pipeline-progend-glsl.c
index 703cbea..bc96cb8 100644
--- a/cogl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl-pipeline-progend-glsl.c
@@ -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;
-}
-
-int
-_cogl_pipeline_progend_glsl_get_color_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->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;
-}
+/* 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_normal_attribute (CoglPipeline *pipeline)
+_cogl_pipeline_progend_glsl_get_attrib_location (CoglPipeline *pipeline,
+ int name_index)
{
CoglPipelineProgramState *program_state = get_program_state (pipeline);
+ int *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 (program_state->normal_attribute_location == ATTRIBUTE_LOCATION_UNKNOWN)
- GE_RET( program_state->normal_attribute_location,
- ctx, glGetAttribLocation (program_state->program,
- "cogl_normal_in") );
+ if (G_UNLIKELY (program_state->attribute_locations == NULL))
+ program_state->attribute_locations =
+ g_array_new (FALSE, FALSE, sizeof (int));
- 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 (G_UNLIKELY (program_state->attribute_locations->len <= name_index))
{
- 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;
+ 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;
}
- 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 =
- g_array_new (FALSE, FALSE, sizeof (int));
- if (program_state->tex_coord_attribute_locations->len <= unit - 1)
- {
- 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)
- = ATTRIBUTE_LOCATION_UNKNOWN;
- }
+ locations = &g_array_index (program_state->attribute_locations, int, 0);
- locations = &g_array_index (program_state->tex_coord_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);
- }
+ 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);
+ {
+ 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++)
diff --git a/cogl/cogl.c b/cogl/cogl.c
index 46fd45e..cba3de7 100644
--- a/cogl/cogl.c
+++ b/cogl/cogl.c
@@ -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 ();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]