+
+
+/**
+ * Call glMaterialfv for the attributes specified by bitmask, using the
+ * material colors in src.
+ */
+static void
+emit_material( const struct gl_material *src, GLuint bitmask )
+{
+ if (bitmask & FRONT_EMISSION_BIT)
+ glMaterialfv( GL_FRONT, GL_EMISSION, src[0].Emission );
+
+ if (bitmask & BACK_EMISSION_BIT)
+ glMaterialfv( GL_BACK, GL_EMISSION, src[1].Emission );
+
+ if (bitmask & FRONT_AMBIENT_BIT)
+ glMaterialfv( GL_FRONT, GL_AMBIENT, src[0].Ambient );
+
+ if (bitmask & BACK_AMBIENT_BIT)
+ glMaterialfv( GL_BACK, GL_AMBIENT, src[1].Ambient );
+
+ if (bitmask & FRONT_DIFFUSE_BIT)
+ glMaterialfv( GL_FRONT, GL_DIFFUSE, src[0].Diffuse );
+
+ if (bitmask & BACK_DIFFUSE_BIT)
+ glMaterialfv( GL_BACK, GL_DIFFUSE, src[1].Diffuse );
+
+ if (bitmask & FRONT_SPECULAR_BIT)
+ glMaterialfv( GL_FRONT, GL_SPECULAR, src[0].Specular );
+
+ if (bitmask & BACK_SPECULAR_BIT)
+ glMaterialfv( GL_BACK, GL_SPECULAR, src[1].Specular );
+
+ if (bitmask & FRONT_SHININESS_BIT)
+ glMaterialfv( GL_FRONT, GL_SHININESS, &src[0].Shininess );
+
+ if (bitmask & BACK_SHININESS_BIT)
+ glMaterialfv( GL_BACK, GL_SHININESS, &src[1].Shininess );
+
+ if (bitmask & FRONT_INDEXES_BIT) {
+ GLfloat ind[3];
+ ind[0] = src[0].AmbientIndex;
+ ind[1] = src[0].DiffuseIndex;
+ ind[2] = src[0].SpecularIndex;
+ glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, ind );
+ }
+
+ if (bitmask & BACK_INDEXES_BIT) {
+ GLfloat ind[3];
+ ind[0] = src[1].AmbientIndex;
+ ind[1] = src[1].DiffuseIndex;
+ ind[2] = src[1].SpecularIndex;
+ glMaterialfv( GL_BACK, GL_COLOR_INDEXES, ind );
+ }
+}
+
+
+/* Low-performance helper function to allow driver-supplied tnl
+ * modules to process tnl display lists. This is primarily supplied
+ * to avoid fallbacks if CallList is invoked inside a Begin/End pair.
+ * For higher performance, drivers should fallback to tnl (if outside
+ * begin/end), or (for tnl hardware) implement their own display list
+ * mechanism.
+ */
+static void
+loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM )
+{
+ const GLuint *flags = IM->Flag;
+ const GLuint orflag = IM->OrFlag;
+ void (GLAPIENTRY *vertex)( const GLfloat * );
+ void (GLAPIENTRY *texcoordfv[MAX_TEXTURE_COORD_UNITS])( GLenum, const GLfloat * );
+ GLuint i, j, p, length, prim = 0, maxtex = 0;
+
+ if (orflag & VERT_BITS_OBJ_234)
+ vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex4fv;
+ else
+ vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex3fv;
+
+ if (orflag & VERT_BITS_TEX_ANY) {
+ for (j = 0 ; j < ctx->Const.MaxTextureUnits ; j++) {
+ if (orflag & VERT_BIT_TEX(j)) {
+ maxtex = j+1;
+ if ((IM->TexSize & TEX_SIZE_4(j)) == TEX_SIZE_4(j))
+ texcoordfv[j] = glMultiTexCoord4fvARB;
+ else if (IM->TexSize & TEX_SIZE_3(j))
+ texcoordfv[j] = glMultiTexCoord3fvARB;
+ else
+ texcoordfv[j] = glMultiTexCoord2fvARB;
+ }
+ }
+ }
+
+ for (p = IM->Start ; !(prim & PRIM_LAST) ; p += length)
+ {
+ prim = IM->Primitive[p];
+ length= IM->PrimitiveLength[p];
+ ASSERT(length || (prim & PRIM_LAST));
+ ASSERT((prim & PRIM_MODE_MASK) <= GL_POLYGON+1);
+
+ if (prim & PRIM_BEGIN) {
+ glBegin(prim & PRIM_MODE_MASK);
+ }
+
+ for ( i = p ; i <= p+length ; i++) {
+ if (flags[i] & VERT_BITS_TEX_ANY) {
+ GLuint k;
+ for (k = 0 ; k < maxtex ; k++) {
+ if (flags[i] & VERT_BIT_TEX(k)) {
+ texcoordfv[k]( GL_TEXTURE0_ARB + k,
+ IM->Attrib[VERT_ATTRIB_TEX0 + k][i] );
+ }
+ }
+ }
+
+ /* XXX Maybe we should jump through _glapi->Dispatch all the time?? */
+ if (flags[i] & VERT_BIT_NORMAL)
+ glNormal3fv(IM->Attrib[VERT_ATTRIB_NORMAL][i]);
+
+ if (flags[i] & VERT_BIT_COLOR0)
+ glColor4fv( IM->Attrib[VERT_ATTRIB_COLOR0][i] );
+
+ if (flags[i] & VERT_BIT_COLOR1)
+ _glapi_Dispatch->SecondaryColor3fvEXT( IM->Attrib[VERT_ATTRIB_COLOR1][i] );
+
+ if (flags[i] & VERT_BIT_FOG)
+ _glapi_Dispatch->FogCoordfEXT( IM->Attrib[VERT_ATTRIB_FOG][i][0] );
+
+ if (flags[i] & VERT_BIT_INDEX)
+ glIndexi( IM->Index[i] );
+
+ if (flags[i] & VERT_BIT_EDGEFLAG)
+ glEdgeFlag( IM->EdgeFlag[i] );
+
+ if (flags[i] & VERT_BIT_MATERIAL)
+ emit_material( IM->Material[i], IM->MaterialMask[i] );
+
+ if (flags[i]&VERT_BITS_OBJ_234)
+ vertex( IM->Attrib[VERT_ATTRIB_POS][i] );
+ else if (flags[i] & VERT_BIT_EVAL_C1)
+ glEvalCoord1f( IM->Attrib[VERT_ATTRIB_POS][i][0] );
+ else if (flags[i] & VERT_BIT_EVAL_P1)
+ glEvalPoint1( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0] );
+ else if (flags[i] & VERT_BIT_EVAL_C2)
+ glEvalCoord2f( IM->Attrib[VERT_ATTRIB_POS][i][0],
+ IM->Attrib[VERT_ATTRIB_POS][i][1] );
+ else if (flags[i] & VERT_BIT_EVAL_P2)
+ glEvalPoint2( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0],
+ (GLint) IM->Attrib[VERT_ATTRIB_POS][i][1] );
+ }
+
+ if (prim & PRIM_END) {
+ glEnd();
+ }
+ }
+}