cogl: Use a CoglBitmask to store the list of used texcoord arrays

Instead of directly using a guint32 to store a bitmask for each used
texcoord array, it now stores them in a CoglBitmask. This removes the
limitation of 32 layers (although there are still other places in Cogl
that imply this restriction). To disable texcoord arrays code should
call _cogl_disable_other_texcoord_arrays which takes a bitmask of
texcoord arrays that should not be disabled. There are two extra
bitmasks stored in the CoglContext which are used temporarily for this
function to avoid allocating a new bitmask each time.

http://bugzilla.openedhand.com/show_bug.cgi?id=2132
This commit is contained in:
Neil Roberts 2010-05-24 12:40:11 +01:00
parent 4fb784d111
commit aaf5600b2d
8 changed files with 56 additions and 35 deletions

View File

@ -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);
}

View File

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

View File

@ -26,6 +26,7 @@
#include "cogl.h"
#include "cogl-matrix-stack.h"
#include "cogl-bitmask.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
@ -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

View File

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

View File

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

View File

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

View File

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

View File

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