diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index c8ff3dd51..4f3cb6621 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -97,7 +97,9 @@ cogl_create_context (void) 0, sizeof (CoglMaterialFlushOptions)); _context->current_layers = g_array_new (FALSE, FALSE, sizeof (CoglLayerInfo)); - _context->texcoord_arrays_enabled = 0; + _cogl_bitmask_init (&_context->texcoord_arrays_enabled); + _cogl_bitmask_init (&_context->temp_bitmask); + _cogl_bitmask_init (&_context->texcoord_arrays_to_disable); _context->framebuffer_stack = _cogl_create_framebuffer_stack (); @@ -201,6 +203,10 @@ _cogl_destroy_context () if (_context->atlas_texture) cogl_handle_unref (_context->atlas_texture); + _cogl_bitmask_destroy (&_context->texcoord_arrays_enabled); + _cogl_bitmask_destroy (&_context->temp_bitmask); + _cogl_bitmask_destroy (&_context->texcoord_arrays_to_disable); + g_free (_context); } diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h index b406446a8..9393dd740 100644 --- a/cogl/cogl-context.h +++ b/cogl/cogl-context.h @@ -32,6 +32,7 @@ #include "cogl-material-private.h" #include "cogl-atlas.h" #include "cogl-buffer-private.h" +#include "cogl-bitmask.h" typedef struct { @@ -87,7 +88,12 @@ typedef struct CoglMaterialFlushOptions current_material_flush_options; GArray *current_layers; /* Bitmask of texture coordinates arrays that are enabled */ - unsigned int texcoord_arrays_enabled; + CoglBitmask texcoord_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 texcoord_arrays_to_disable; + CoglBitmask temp_bitmask; /* PBOs */ /* This can be used to check if a pbo is bound */ diff --git a/cogl/cogl-internal.h b/cogl/cogl-internal.h index 50036ab64..c650960b6 100644 --- a/cogl/cogl-internal.h +++ b/cogl/cogl-internal.h @@ -26,6 +26,7 @@ #include "cogl.h" #include "cogl-matrix-stack.h" +#include "cogl-bitmask.h" #ifdef COGL_HAS_XLIB_SUPPORT #include @@ -132,8 +133,10 @@ _cogl_get_max_texture_image_units (void); void _cogl_flush_face_winding (void); +/* Disables the texcoord arrays that don't have a corresponding bit + set in the mask */ void -_cogl_disable_texcoord_arrays (unsigned int mask); +_cogl_disable_other_texcoord_arrays (const CoglBitmask *mask); #ifdef COGL_HAS_XLIB_SUPPORT diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c index ae412b034..078a66f19 100644 --- a/cogl/cogl-journal.c +++ b/cogl/cogl-journal.c @@ -373,7 +373,6 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries ( { CoglJournalFlushState *state = data; int i; - unsigned int layers_mask; _COGL_GET_CONTEXT (ctx, NO_RETVAL); @@ -396,9 +395,9 @@ _cogl_journal_flush_texcoord_vbo_offsets_and_entries ( TEX_STRIDE * 4 * i))); } - layers_mask = ~((~(unsigned int) 0) << batch_start->n_layers); - ctx->texcoord_arrays_enabled |= layers_mask; - _cogl_disable_texcoord_arrays (ctx->texcoord_arrays_enabled & ~layers_mask); + _cogl_bitmask_clear_all (&ctx->temp_bitmask); + _cogl_bitmask_set_range (&ctx->temp_bitmask, batch_start->n_layers, TRUE); + _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); batch_and_call (batch_start, batch_len, diff --git a/cogl/cogl-path.c b/cogl/cogl-path.c index 553189b1f..27787acfd 100644 --- a/cogl/cogl-path.c +++ b/cogl/cogl-path.c @@ -263,7 +263,8 @@ _cogl_add_path_to_stencil_buffer (CoglHandle path_handle, GE (glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT)); /* Disable all client texture coordinate arrays */ - _cogl_disable_texcoord_arrays (ctx->texcoord_arrays_enabled); + _cogl_bitmask_clear_all (&ctx->temp_bitmask); + _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); while (path_start < path->data->path_nodes->len) { diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c index be7bcb4f8..61aeae524 100644 --- a/cogl/cogl-primitives.c +++ b/cogl/cogl-primitives.c @@ -1012,7 +1012,6 @@ cogl_polygon (const CoglTextureVertex *vertices, unsigned int stride; gsize stride_bytes; GLfloat *v; - unsigned int layers_mask; CoglMaterialWrapModeOverrides wrap_mode_overrides; CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL; @@ -1165,9 +1164,9 @@ cogl_polygon (const CoglTextureVertex *vertices, v + 3 + 2 * i)); } - layers_mask = ~((~(unsigned int) 0) << n_layers); - ctx->texcoord_arrays_enabled |= layers_mask; - _cogl_disable_texcoord_arrays (ctx->texcoord_arrays_enabled & ~layers_mask); + _cogl_bitmask_clear_all (&ctx->temp_bitmask); + _cogl_bitmask_set_range (&ctx->temp_bitmask, n_layers, TRUE); + _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); if (use_sliced_polygon_fallback) _cogl_texture_polygon_multiple_primitives (vertices, diff --git a/cogl/cogl-vertex-buffer.c b/cogl/cogl-vertex-buffer.c index c71d39e80..a4cade0c4 100644 --- a/cogl/cogl-vertex-buffer.c +++ b/cogl/cogl-vertex-buffer.c @@ -1518,7 +1518,6 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) GLuint generic_index = 0; #endif unsigned long enable_flags = 0; - unsigned int texcoord_arrays_used = 0; const GList *layers; guint32 fallback_layers = 0; int i; @@ -1534,6 +1533,8 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) memset (&options.wrap_mode_overrides, 0, sizeof (options.wrap_mode_overrides)); + _cogl_bitmask_clear_all (&ctx->temp_bitmask); + for (tmp = buffer->submitted_vbos; tmp != NULL; tmp = tmp->next) { CoglVertexBufferVBO *cogl_vbo = tmp->data; @@ -1596,7 +1597,8 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) gl_type, attribute->stride, pointer)); - texcoord_arrays_used |= (1 << attribute->texture_unit); + _cogl_bitmask_set (&ctx->temp_bitmask, + attribute->texture_unit, TRUE); break; case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: enable_flags |= COGL_ENABLE_VERTEX_ARRAY; @@ -1698,8 +1700,8 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer) } } - _cogl_disable_texcoord_arrays (ctx->texcoord_arrays_enabled & - ~texcoord_arrays_used); + /* Disable any tex coord arrays that we didn't use */ + _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); /* NB: _cogl_framebuffer_flush_state may disrupt various state (such * as the material state) when flushing the clip stack, so should diff --git a/cogl/cogl.c b/cogl/cogl.c index 0d5f438de..eab2d12d9 100644 --- a/cogl/cogl.c +++ b/cogl/cogl.c @@ -763,29 +763,33 @@ cogl_read_pixels (int x, } } -void -_cogl_disable_texcoord_arrays (unsigned int mask) +static void +_cogl_disable_other_texcoord_arrays_cb (int texcoord_array_num, gpointer data) { - int i = 0; + CoglContext *ctx = data; + GE (glClientActiveTexture (GL_TEXTURE0 + texcoord_array_num)); + GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY)); +} + +void +_cogl_disable_other_texcoord_arrays (const CoglBitmask *mask) +{ _COGL_GET_CONTEXT (ctx, NO_RETVAL); + /* Set texcoord_arrays_to_disable to only contain the arrays we want + to disable */ + _cogl_bitmask_clear_all (&ctx->texcoord_arrays_to_disable); + _cogl_bitmask_set_bits (&ctx->texcoord_arrays_to_disable, + &ctx->texcoord_arrays_enabled); + _cogl_bitmask_clear_bits (&ctx->texcoord_arrays_to_disable, mask); + + _cogl_bitmask_foreach (&ctx->texcoord_arrays_to_disable, + _cogl_disable_other_texcoord_arrays_cb, ctx); + /* Update the mask of arrays that are enabled */ - ctx->texcoord_arrays_enabled &= ~mask; - - /* Disable all of the texture coord arrays that have a 1 in the bit - position in mask */ - while (mask) - { - if ((mask & 1)) - { - GE (glClientActiveTexture (GL_TEXTURE0 + i)); - GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY)); - } - - i++; - mask >>= 1; - } + _cogl_bitmask_clear_bits (&ctx->texcoord_arrays_enabled, + &ctx->texcoord_arrays_to_disable); } void @@ -840,7 +844,8 @@ cogl_begin_gl (void) _cogl_flush_face_winding (); /* Disable all client texture coordinate arrays */ - _cogl_disable_texcoord_arrays (ctx->texcoord_arrays_enabled); + _cogl_bitmask_clear_all (&ctx->temp_bitmask); + _cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask); } void