summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/api_arrayelt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/api_arrayelt.c')
-rw-r--r--src/mesa/main/api_arrayelt.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
new file mode 100644
index 00000000000..004977c36c9
--- /dev/null
+++ b/src/mesa/main/api_arrayelt.c
@@ -0,0 +1,284 @@
+#include "glheader.h"
+#include "api_noop.h"
+#include "context.h"
+#include "colormac.h"
+#include "light.h"
+#include "macros.h"
+#include "mmath.h"
+#include "mtypes.h"
+
+
+typedef struct {
+ GLint unit;
+ struct gl_client_array *array;
+ void *func;
+} AAtexarray;
+
+
+typedef struct {
+ struct gl_client_array *array;
+ void *func;
+} AAarray;
+
+typedef struct {
+ AAtexarray texarrays[MAX_TEXTURE_UNITS+1];
+ AAarray arrays[10];
+ GLuint NewState;
+} AAcontext;
+
+
+static void *colorfuncs[2][7] = {
+ { glColor3bv,
+ glColor3ub,
+ glColor3sv,
+ glColor3usv,
+ glColor3iv,
+ glColor3fv,
+ glColor3dv },
+
+ { glColor4bv,
+ glColor4ub,
+ glColor4sv,
+ glColor4usv,
+ glColor4iv,
+ glColor4fv,
+ glColor4dv }
+};
+
+static void *vertexfuncs[3][7] = {
+ { glVertex3bv,
+ glVertex3ub,
+ glVertex3sv,
+ glVertex3usv,
+ glVertex3iv,
+ glVertex3fv,
+ glVertex3dv },
+
+ { glVertex3bv,
+ glVertex3ub,
+ glVertex3sv,
+ glVertex3usv,
+ glVertex3iv,
+ glVertex3fv,
+ glVertex3dv },
+
+ { glVertex4bv,
+ glVertex4ub,
+ glVertex4sv,
+ glVertex4usv,
+ glVertex4iv,
+ glVertex4fv,
+ glVertex4dv }
+};
+
+
+static void *multitexfuncs[4][7] = {
+ { glMultiTexCoord1bv,
+ glMultiTexCoord1ub,
+ glMultiTexCoord1sv,
+ glMultiTexCoord1usv,
+ glMultiTexCoord1iv,
+ glMultiTexCoord1fv,
+ glMultiTexCoord1dv },
+
+ { glMultiTexCoord2bv,
+ glMultiTexCoord2ub,
+ glMultiTexCoord2sv,
+ glMultiTexCoord2usv,
+ glMultiTexCoord2iv,
+ glMultiTexCoord2fv,
+ glMultiTexCoord2dv },
+
+ { glMultiTexCoord3bv,
+ glMultiTexCoord3ub,
+ glMultiTexCoord3sv,
+ glMultiTexCoord3usv,
+ glMultiTexCoord3iv,
+ glMultiTexCoord3fv,
+ glMultiTexCoord3dv },
+
+ { glMultiTexCoord4bv,
+ glMultiTexCoord4ub,
+ glMultiTexCoord4sv,
+ glMultiTexCoord4usv,
+ glMultiTexCoord4iv,
+ glMultiTexCoord4fv,
+ glMultiTexCoord4dv }
+};
+
+static void *indexfuncs[7] = {
+ { glIndexbv,
+ glIndexub,
+ glIndexsv,
+ glIndexusv,
+ glIndexiv,
+ glIndexfv,
+ glIndexdv },
+};
+
+static void *edgeflagfuncs[7] = {
+ { glEdgeFlagbv,
+ glEdgeFlagub,
+ glEdgeFlagsv,
+ glEdgeFlagusv,
+ glEdgeFlagiv,
+ glEdgeFlagfv,
+ glEdgeFlagdv },
+};
+
+static void *normalfuncs[7] = {
+ { glNormal3bv,
+ glNormal3ub,
+ glNormal3sv,
+ glNormal3usv,
+ glNormal3iv,
+ glNormal3fv,
+ glNormal3dv },
+};
+
+static void *fogcoordfuncs[7] = {
+ { glFogCoordbv,
+ glFogCoordub,
+ glFogCoordsv,
+ glFogCoordusv,
+ glFogCoordiv,
+ glFogCoordfv,
+ glFogCoorddv },
+};
+
+static void *secondarycolorfuncs[7] = {
+ { glSecondaryColor3bv,
+ glSecondaryColor3ub,
+ glSecondaryColor3sv,
+ glSecondaryColor3usv,
+ glSecondaryColor3iv,
+ glSecondaryColor3fv,
+ glSecondaryColor3dv },
+};
+
+
+void _aa_create_context( GLcontext *ctx )
+{
+ ctx->aa_context = MALLOC( sizeof(AAcontext) );
+ AA_CONTEXT(ctx)->NewState = ~0;
+}
+
+static void _aa_update_state( GLcontext *ctx )
+{
+ AAcontext *actx = AA_CONTEXT(ctx);
+ AAtexarray *ta = actx->texarrays;
+ AAarray *aa = actx->arrays;
+ int i;
+
+ for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
+ if (ctx->Array.TexCoord[i].Enabled) {
+ ta->unit = i;
+ ta->array = &ctx->Array.TexCoord[i];
+ ta->func = multitexfuncs[ta->array->Size-1][TYPE_IDX(ta->array->Type)];
+ ta++;
+ }
+
+ ta->func = 0;
+
+ if (ctx->Array.Color.Enabled) {
+ aa->array = &ctx->Array.Color;
+ aa->func = colorfuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ if (ctx->Array.Normal.Enabled) {
+ aa->array = &ctx->Array.Normal;
+ aa->func = normalfuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ if (ctx->Array.Index.Enabled) {
+ aa->array = &ctx->Array.Index;
+ aa->func = indexfuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ if (ctx->Array.EdgeFlag.Enabled) {
+ aa->array = &ctx->Array.Edgeflag;
+ aa->func = edgeflagfuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ if (ctx->Array.FogCoord.Enabled) {
+ aa->array = &ctx->Array.Fogcoord;
+ aa->func = fogcoordfuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ if (ctx->Array.SecondaryColor.Enabled) {
+ aa->array = &ctx->Array.SecondaryColor;
+ aa->func = secondarycolorfuncs[TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ /* Must be last
+ */
+ if (ctx->Array.Vertex.Enabled) {
+ aa->array = &ctx->Array.Vertex;
+ aa->func = vertexfuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ aa++;
+ }
+
+ aa->func = 0;
+ actx->NewState = 0;
+}
+
+
+static void _aa_loopback_array_elt( GLint elt )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ AAcontext *actx = AA_CONTEXT(ctx);
+ AAtexarray *ta;
+ AAarray *aa;
+
+ for (ta = actx->texarrays ; ta->func ; ta++) {
+ void (*func)( GLint, const void * ) =
+ (void (*)( GLint, const void * )) ta->func;
+ func( ta->unit, (char *)ta->array->Ptr + elt * ta->array->SizeB );
+ }
+
+ for (aa = actx->arrays ; aa->func ; aa++) {
+ void (*func)( GLint, const void * ) =
+ (void (*)( GLint, const void * )) aa->func;
+ func( (char *)aa->array->Ptr + elt * aa->array->SizeB );
+ }
+}
+
+
+void _aa_exec_array_elt( GLint elt )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ AAcontext *actx = AA_CONTEXT(ctx);
+
+ if (actx->NewState)
+ _aa_update_state( ctx );
+
+ ctx->Exec->ArrayElement = _aa_loopback_array_elt;
+ _aa_loopback_array_elt( elt );
+}
+
+/* This works for save as well:
+ */
+void _aa_save_array_elt( GLint elt )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ AAcontext *actx = AA_CONTEXT(ctx);
+
+ if (actx->NewState)
+ _aa_update_state( ctx );
+
+ ctx->Save->ArrayElement = _aa_loopback_array_elt;
+ _aa_loopback_array_elt( elt );
+}
+
+
+void aa_invalidate_state( GLcontext *ctx, GLuint new_state )
+{
+ if (AA_CONTEXT(ctx))
+ AA_CONTEXT(ctx)->NewState |= new_state;
+}