api_arrayelt.c revision 1e3d868ffbec46eecb85b4aaf6990d9ad69e830f
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.1
4 *
5 * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25/* Author:
26 *    Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29#include "glheader.h"
30#include "api_arrayelt.h"
31#include "context.h"
32#include "glapi.h"
33#include "imports.h"
34#include "macros.h"
35#include "mtypes.h"
36
37typedef void (GLAPIENTRY *array_func)( const void * );
38
39typedef struct {
40   const struct gl_client_array *array;
41   array_func func;
42} AEarray;
43
44typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
45
46typedef struct {
47   const struct gl_client_array *array;
48   attrib_func func;
49   GLuint index;
50} AEattrib;
51
52typedef struct {
53   AEarray arrays[32];
54   AEattrib attribs[VERT_ATTRIB_MAX + 1];
55   GLuint NewState;
56} AEcontext;
57
58#define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
59
60/*
61 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
62 * in the range [0, 7].  Luckily these type tokens are sequentially
63 * numbered in gl.h
64 */
65#define TYPE_IDX(t) ((t) & 0xf)
66
67
68static void (GLAPIENTRY *colorfuncs[2][8])( const void * ) = {
69   { (array_func)glColor3bv,
70     (array_func)glColor3ubv,
71     (array_func)glColor3sv,
72     (array_func)glColor3usv,
73     (array_func)glColor3iv,
74     (array_func)glColor3uiv,
75     (array_func)glColor3fv,
76     (array_func)glColor3dv },
77
78   { (array_func)glColor4bv,
79     (array_func)glColor4ubv,
80     (array_func)glColor4sv,
81     (array_func)glColor4usv,
82     (array_func)glColor4iv,
83     (array_func)glColor4uiv,
84     (array_func)glColor4fv,
85     (array_func)glColor4dv }
86};
87
88static void (GLAPIENTRY *vertexfuncs[3][8])( const void * ) = {
89   { 0,
90     0,
91     (array_func)glVertex2sv,
92     0,
93     (array_func)glVertex2iv,
94     0,
95     (array_func)glVertex2fv,
96     (array_func)glVertex2dv },
97
98   { 0,
99     0,
100     (array_func)glVertex3sv,
101     0,
102     (array_func)glVertex3iv,
103     0,
104     (array_func)glVertex3fv,
105     (array_func)glVertex3dv },
106
107   { 0,
108     0,
109     (array_func)glVertex4sv,
110     0,
111     (array_func)glVertex4iv,
112     0,
113     (array_func)glVertex4fv,
114     (array_func)glVertex4dv }
115};
116
117static void (GLAPIENTRY *indexfuncs[8])( const void * ) = {
118   0,
119   (array_func)glIndexubv,
120   (array_func)glIndexsv,
121   0,
122   (array_func)glIndexiv,
123   0,
124   (array_func)glIndexfv,
125   (array_func)glIndexdv
126};
127
128static void (GLAPIENTRY *normalfuncs[8])( const void * ) = {
129   (array_func)glNormal3bv,
130   0,
131   (array_func)glNormal3sv,
132   0,
133   (array_func)glNormal3iv,
134   0,
135   (array_func)glNormal3fv,
136   (array_func)glNormal3dv,
137};
138
139
140/* Wrapper functions in case glSecondaryColor*EXT doesn't exist */
141static void SecondaryColor3bvEXT(const GLbyte *c)
142{
143   _glapi_Dispatch->SecondaryColor3bvEXT(c);
144}
145
146static void SecondaryColor3ubvEXT(const GLubyte *c)
147{
148   _glapi_Dispatch->SecondaryColor3ubvEXT(c);
149}
150
151static void SecondaryColor3svEXT(const GLshort *c)
152{
153   _glapi_Dispatch->SecondaryColor3svEXT(c);
154}
155
156static void SecondaryColor3usvEXT(const GLushort *c)
157{
158   _glapi_Dispatch->SecondaryColor3usvEXT(c);
159}
160
161static void SecondaryColor3ivEXT(const GLint *c)
162{
163   _glapi_Dispatch->SecondaryColor3ivEXT(c);
164}
165
166static void SecondaryColor3uivEXT(const GLuint *c)
167{
168   _glapi_Dispatch->SecondaryColor3uivEXT(c);
169}
170
171static void SecondaryColor3fvEXT(const GLfloat *c)
172{
173   _glapi_Dispatch->SecondaryColor3fvEXT(c);
174}
175
176static void SecondaryColor3dvEXT(const GLdouble *c)
177{
178   _glapi_Dispatch->SecondaryColor3dvEXT(c);
179}
180
181static void (GLAPIENTRY *secondarycolorfuncs[8])( const void * ) = {
182   (array_func) SecondaryColor3bvEXT,
183   (array_func) SecondaryColor3ubvEXT,
184   (array_func) SecondaryColor3svEXT,
185   (array_func) SecondaryColor3usvEXT,
186   (array_func) SecondaryColor3ivEXT,
187   (array_func) SecondaryColor3uivEXT,
188   (array_func) SecondaryColor3fvEXT,
189   (array_func) SecondaryColor3dvEXT,
190};
191
192
193/* Again, wrapper functions in case glSecondaryColor*EXT doesn't exist */
194static void FogCoordfvEXT(const GLfloat *f)
195{
196   _glapi_Dispatch->FogCoordfvEXT(f);
197}
198
199static void FogCoorddvEXT(const GLdouble *f)
200{
201   _glapi_Dispatch->FogCoorddvEXT(f);
202}
203
204static void (GLAPIENTRY *fogcoordfuncs[8])( const void * ) = {
205   0,
206   0,
207   0,
208   0,
209   0,
210   0,
211   (array_func) FogCoordfvEXT,
212   (array_func) FogCoorddvEXT
213};
214
215
216/**********************************************************************/
217
218/* GL_BYTE attributes */
219
220static void VertexAttrib1Nbv(GLuint index, const GLbyte *v)
221{
222   _glapi_Dispatch->VertexAttrib1fNV(index, BYTE_TO_FLOAT(v[0]));
223}
224
225static void VertexAttrib1bv(GLuint index, const GLbyte *v)
226{
227      _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
228}
229
230static void VertexAttrib2Nbv(GLuint index, const GLbyte *v)
231{
232   _glapi_Dispatch->VertexAttrib2fNV(index, BYTE_TO_FLOAT(v[0]),
233                                     BYTE_TO_FLOAT(v[1]));
234}
235
236static void VertexAttrib2bv(GLuint index, const GLbyte *v)
237{
238   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
239}
240
241static void VertexAttrib3Nbv(GLuint index, const GLbyte *v)
242{
243   _glapi_Dispatch->VertexAttrib3fNV(index, BYTE_TO_FLOAT(v[0]),
244                                     BYTE_TO_FLOAT(v[1]),
245                                     BYTE_TO_FLOAT(v[2]));
246}
247
248static void VertexAttrib3bv(GLuint index, const GLbyte *v)
249{
250   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
251}
252
253static void VertexAttrib4Nbv(GLuint index, const GLbyte *v)
254{
255   _glapi_Dispatch->VertexAttrib4fNV(index, BYTE_TO_FLOAT(v[0]),
256                                     BYTE_TO_FLOAT(v[1]),
257                                     BYTE_TO_FLOAT(v[2]),
258                                     BYTE_TO_FLOAT(v[3]));
259}
260
261static void VertexAttrib4bv(GLuint index, const GLbyte *v)
262{
263   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
264}
265
266/* GL_UNSIGNED_BYTE attributes */
267
268static void VertexAttrib1Nubv(GLuint index, const GLubyte *v)
269{
270   _glapi_Dispatch->VertexAttrib1fNV(index, UBYTE_TO_FLOAT(v[0]));
271}
272
273static void VertexAttrib1ubv(GLuint index, const GLubyte *v)
274{
275   _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
276}
277
278static void VertexAttrib2Nubv(GLuint index, const GLubyte *v)
279{
280   _glapi_Dispatch->VertexAttrib2fNV(index, UBYTE_TO_FLOAT(v[0]),
281                                     UBYTE_TO_FLOAT(v[1]));
282}
283
284static void VertexAttrib2ubv(GLuint index, const GLubyte *v)
285{
286   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
287}
288
289static void VertexAttrib3Nubv(GLuint index, const GLubyte *v)
290{
291   _glapi_Dispatch->VertexAttrib3fNV(index, UBYTE_TO_FLOAT(v[0]),
292                                     UBYTE_TO_FLOAT(v[1]),
293                                     UBYTE_TO_FLOAT(v[2]));
294}
295static void VertexAttrib3ubv(GLuint index, const GLubyte *v)
296{
297   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
298}
299
300static void VertexAttrib4Nubv(GLuint index, const GLubyte *v)
301{
302   _glapi_Dispatch->VertexAttrib4fNV(index, UBYTE_TO_FLOAT(v[0]),
303                                     UBYTE_TO_FLOAT(v[1]),
304                                     UBYTE_TO_FLOAT(v[2]),
305                                     UBYTE_TO_FLOAT(v[3]));
306}
307
308static void VertexAttrib4ubv(GLuint index, const GLubyte *v)
309{
310   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
311}
312
313/* GL_SHORT attributes */
314
315static void VertexAttrib1Nsv(GLuint index, const GLshort *v)
316{
317   _glapi_Dispatch->VertexAttrib1fNV(index, SHORT_TO_FLOAT(v[0]));
318}
319
320static void VertexAttrib1sv(GLuint index, const GLshort *v)
321{
322   _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
323}
324
325static void VertexAttrib2Nsv(GLuint index, const GLshort *v)
326{
327   _glapi_Dispatch->VertexAttrib2fNV(index, SHORT_TO_FLOAT(v[0]),
328                                     SHORT_TO_FLOAT(v[1]));
329}
330
331static void VertexAttrib2sv(GLuint index, const GLshort *v)
332{
333   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
334}
335
336static void VertexAttrib3Nsv(GLuint index, const GLshort *v)
337{
338   _glapi_Dispatch->VertexAttrib3fNV(index, SHORT_TO_FLOAT(v[0]),
339                                     SHORT_TO_FLOAT(v[1]),
340                                     SHORT_TO_FLOAT(v[2]));
341}
342
343static void VertexAttrib3sv(GLuint index, const GLshort *v)
344{
345   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
346}
347
348static void VertexAttrib4Nsv(GLuint index, const GLshort *v)
349{
350   _glapi_Dispatch->VertexAttrib4fNV(index, SHORT_TO_FLOAT(v[0]),
351                                     SHORT_TO_FLOAT(v[1]),
352                                     SHORT_TO_FLOAT(v[2]),
353                                     SHORT_TO_FLOAT(v[3]));
354}
355
356static void VertexAttrib4sv(GLuint index, const GLshort *v)
357{
358   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
359}
360
361/* GL_UNSIGNED_SHORT attributes */
362
363static void VertexAttrib1Nusv(GLuint index, const GLushort *v)
364{
365   _glapi_Dispatch->VertexAttrib1fNV(index, USHORT_TO_FLOAT(v[0]));
366}
367
368static void VertexAttrib1usv(GLuint index, const GLushort *v)
369{
370   _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
371}
372
373static void VertexAttrib2Nusv(GLuint index, const GLushort *v)
374{
375   _glapi_Dispatch->VertexAttrib2fNV(index, USHORT_TO_FLOAT(v[0]),
376                                     USHORT_TO_FLOAT(v[1]));
377}
378
379static void VertexAttrib2usv(GLuint index, const GLushort *v)
380{
381   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
382}
383
384static void VertexAttrib3Nusv(GLuint index, const GLushort *v)
385{
386   _glapi_Dispatch->VertexAttrib3fNV(index, USHORT_TO_FLOAT(v[0]),
387                                     USHORT_TO_FLOAT(v[1]),
388                                     USHORT_TO_FLOAT(v[2]));
389}
390
391static void VertexAttrib3usv(GLuint index, const GLushort *v)
392{
393   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
394}
395
396static void VertexAttrib4Nusv(GLuint index, const GLushort *v)
397{
398   _glapi_Dispatch->VertexAttrib4fNV(index, USHORT_TO_FLOAT(v[0]),
399                                     USHORT_TO_FLOAT(v[1]),
400                                     USHORT_TO_FLOAT(v[2]),
401                                     USHORT_TO_FLOAT(v[3]));
402}
403
404static void VertexAttrib4usv(GLuint index, const GLushort *v)
405{
406   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
407}
408
409/* GL_INT attributes */
410
411static void VertexAttrib1Niv(GLuint index, const GLint *v)
412{
413   _glapi_Dispatch->VertexAttrib1fNV(index, INT_TO_FLOAT(v[0]));
414}
415
416static void VertexAttrib1iv(GLuint index, const GLint *v)
417{
418   _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
419}
420
421static void VertexAttrib2Niv(GLuint index, const GLint *v)
422{
423   _glapi_Dispatch->VertexAttrib2fNV(index, INT_TO_FLOAT(v[0]),
424                                     INT_TO_FLOAT(v[1]));
425}
426
427static void VertexAttrib2iv(GLuint index, const GLint *v)
428{
429   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
430}
431
432static void VertexAttrib3Niv(GLuint index, const GLint *v)
433{
434   _glapi_Dispatch->VertexAttrib3fNV(index, INT_TO_FLOAT(v[0]),
435                                     INT_TO_FLOAT(v[1]),
436                                     INT_TO_FLOAT(v[2]));
437}
438
439static void VertexAttrib3iv(GLuint index, const GLint *v)
440{
441   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
442}
443
444static void VertexAttrib4Niv(GLuint index, const GLint *v)
445{
446   _glapi_Dispatch->VertexAttrib4fNV(index, INT_TO_FLOAT(v[0]),
447                                     INT_TO_FLOAT(v[1]),
448                                     INT_TO_FLOAT(v[2]),
449                                     INT_TO_FLOAT(v[3]));
450}
451
452static void VertexAttrib4iv(GLuint index, const GLint *v)
453{
454   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
455}
456
457/* GL_UNSIGNED_INT attributes */
458
459static void VertexAttrib1Nuiv(GLuint index, const GLuint *v)
460{
461   _glapi_Dispatch->VertexAttrib1fNV(index, UINT_TO_FLOAT(v[0]));
462}
463
464static void VertexAttrib1uiv(GLuint index, const GLuint *v)
465{
466   _glapi_Dispatch->VertexAttrib1fNV(index, v[0]);
467}
468
469static void VertexAttrib2Nuiv(GLuint index, const GLuint *v)
470{
471   _glapi_Dispatch->VertexAttrib2fNV(index, UINT_TO_FLOAT(v[0]),
472                                     UINT_TO_FLOAT(v[1]));
473}
474
475static void VertexAttrib2uiv(GLuint index, const GLuint *v)
476{
477   _glapi_Dispatch->VertexAttrib2fNV(index, v[0], v[1]);
478}
479
480static void VertexAttrib3Nuiv(GLuint index, const GLuint *v)
481{
482   _glapi_Dispatch->VertexAttrib3fNV(index, UINT_TO_FLOAT(v[0]),
483                                     UINT_TO_FLOAT(v[1]),
484                                     UINT_TO_FLOAT(v[2]));
485}
486
487static void VertexAttrib3uiv(GLuint index, const GLuint *v)
488{
489   _glapi_Dispatch->VertexAttrib3fNV(index, v[0], v[1], v[2]);
490}
491
492static void VertexAttrib4Nuiv(GLuint index, const GLuint *v)
493{
494   _glapi_Dispatch->VertexAttrib4fNV(index, UINT_TO_FLOAT(v[0]),
495                                     UINT_TO_FLOAT(v[1]),
496                                     UINT_TO_FLOAT(v[2]),
497                                     UINT_TO_FLOAT(v[3]));
498}
499
500static void VertexAttrib4uiv(GLuint index, const GLuint *v)
501{
502   _glapi_Dispatch->VertexAttrib4fNV(index, v[0], v[1], v[2], v[3]);
503}
504
505/* GL_FLOAT attributes */
506
507static void VertexAttrib1fv(GLuint index, const GLfloat *v)
508{
509   _glapi_Dispatch->VertexAttrib1fvNV(index, v);
510}
511
512static void VertexAttrib2fv(GLuint index, const GLfloat *v)
513{
514   _glapi_Dispatch->VertexAttrib2fvNV(index, v);
515}
516
517static void VertexAttrib3fv(GLuint index, const GLfloat *v)
518{
519   _glapi_Dispatch->VertexAttrib3fvNV(index, v);
520}
521
522static void VertexAttrib4fv(GLuint index, const GLfloat *v)
523{
524   _glapi_Dispatch->VertexAttrib4fvNV(index, v);
525}
526
527/* GL_DOUBLE attributes */
528
529static void VertexAttrib1dv(GLuint index, const GLdouble *v)
530{
531   _glapi_Dispatch->VertexAttrib1dvNV(index, v);
532}
533
534static void VertexAttrib2dv(GLuint index, const GLdouble *v)
535{
536   _glapi_Dispatch->VertexAttrib2dvNV(index, v);
537}
538
539static void VertexAttrib3dv(GLuint index, const GLdouble *v)
540{
541   _glapi_Dispatch->VertexAttrib3dvNV(index, v);
542}
543
544static void VertexAttrib4dv(GLuint index, const GLdouble *v)
545{
546   _glapi_Dispatch->VertexAttrib4dvNV(index, v);
547}
548
549
550/*
551 * Array [size][type] of VertexAttrib functions
552 */
553static void (GLAPIENTRY *attribfuncs[2][4][8])( GLuint, const void * ) = {
554   {
555      /* non-normalized */
556      {
557         /* size 1 */
558         (attrib_func) VertexAttrib1bv,
559         (attrib_func) VertexAttrib1ubv,
560         (attrib_func) VertexAttrib1sv,
561         (attrib_func) VertexAttrib1usv,
562         (attrib_func) VertexAttrib1iv,
563         (attrib_func) VertexAttrib1uiv,
564         (attrib_func) VertexAttrib1fv,
565         (attrib_func) VertexAttrib1dv
566      },
567      {
568         /* size 2 */
569         (attrib_func) VertexAttrib2bv,
570         (attrib_func) VertexAttrib2ubv,
571         (attrib_func) VertexAttrib2sv,
572         (attrib_func) VertexAttrib2usv,
573         (attrib_func) VertexAttrib2iv,
574         (attrib_func) VertexAttrib2uiv,
575         (attrib_func) VertexAttrib2fv,
576         (attrib_func) VertexAttrib2dv
577      },
578      {
579         /* size 3 */
580         (attrib_func) VertexAttrib3bv,
581         (attrib_func) VertexAttrib3ubv,
582         (attrib_func) VertexAttrib3sv,
583         (attrib_func) VertexAttrib3usv,
584         (attrib_func) VertexAttrib3iv,
585         (attrib_func) VertexAttrib3uiv,
586         (attrib_func) VertexAttrib3fv,
587         (attrib_func) VertexAttrib3dv
588      },
589      {
590         /* size 4 */
591         (attrib_func) VertexAttrib4bv,
592         (attrib_func) VertexAttrib4ubv,
593         (attrib_func) VertexAttrib4sv,
594         (attrib_func) VertexAttrib4usv,
595         (attrib_func) VertexAttrib4iv,
596         (attrib_func) VertexAttrib4uiv,
597         (attrib_func) VertexAttrib4fv,
598         (attrib_func) VertexAttrib4dv
599      }
600   },
601   {
602      /* normalized (except for float/double) */
603      {
604         /* size 1 */
605         (attrib_func) VertexAttrib1Nbv,
606         (attrib_func) VertexAttrib1Nubv,
607         (attrib_func) VertexAttrib1Nsv,
608         (attrib_func) VertexAttrib1Nusv,
609         (attrib_func) VertexAttrib1Niv,
610         (attrib_func) VertexAttrib1Nuiv,
611         (attrib_func) VertexAttrib1fv,
612         (attrib_func) VertexAttrib1dv
613      },
614      {
615         /* size 2 */
616         (attrib_func) VertexAttrib2Nbv,
617         (attrib_func) VertexAttrib2Nubv,
618         (attrib_func) VertexAttrib2Nsv,
619         (attrib_func) VertexAttrib2Nusv,
620         (attrib_func) VertexAttrib2Niv,
621         (attrib_func) VertexAttrib2Nuiv,
622         (attrib_func) VertexAttrib2fv,
623         (attrib_func) VertexAttrib2dv
624      },
625      {
626         /* size 3 */
627         (attrib_func) VertexAttrib3Nbv,
628         (attrib_func) VertexAttrib3Nubv,
629         (attrib_func) VertexAttrib3Nsv,
630         (attrib_func) VertexAttrib3Nusv,
631         (attrib_func) VertexAttrib3Niv,
632         (attrib_func) VertexAttrib3Nuiv,
633         (attrib_func) VertexAttrib3fv,
634         (attrib_func) VertexAttrib3dv
635      },
636      {
637         /* size 4 */
638         (attrib_func) VertexAttrib4Nbv,
639         (attrib_func) VertexAttrib4Nubv,
640         (attrib_func) VertexAttrib4Nsv,
641         (attrib_func) VertexAttrib4Nusv,
642         (attrib_func) VertexAttrib4Niv,
643         (attrib_func) VertexAttrib4Nuiv,
644         (attrib_func) VertexAttrib4fv,
645         (attrib_func) VertexAttrib4dv
646      }
647   }
648};
649
650/**********************************************************************/
651
652
653GLboolean _ae_create_context( GLcontext *ctx )
654{
655   if (ctx->aelt_context)
656      return GL_TRUE;
657
658   ctx->aelt_context = MALLOC( sizeof(AEcontext) );
659   if (!ctx->aelt_context)
660      return GL_FALSE;
661
662   AE_CONTEXT(ctx)->NewState = ~0;
663   return GL_TRUE;
664}
665
666
667void _ae_destroy_context( GLcontext *ctx )
668{
669   if ( AE_CONTEXT( ctx ) ) {
670      FREE( ctx->aelt_context );
671      ctx->aelt_context = 0;
672   }
673}
674
675
676/**
677 * Make a list of per-vertex functions to call for each glArrayElement call.
678 * These functions access the array data (i.e. glVertex, glColor, glNormal,
679 * etc).
680 * Note: this may be called during display list construction.
681 */
682static void _ae_update_state( GLcontext *ctx )
683{
684   AEcontext *actx = AE_CONTEXT(ctx);
685   AEarray *aa = actx->arrays;
686   AEattrib *at = actx->attribs;
687   GLuint i;
688
689   /* conventional vertex arrays */
690  if (ctx->Array.Index.Enabled) {
691      aa->array = &ctx->Array.Index;
692      aa->func = indexfuncs[TYPE_IDX(aa->array->Type)];
693      aa++;
694   }
695   if (ctx->Array.EdgeFlag.Enabled) {
696      aa->array = &ctx->Array.EdgeFlag;
697      aa->func = (array_func) glEdgeFlagv;
698      aa++;
699   }
700   if (ctx->Array.Normal.Enabled) {
701      aa->array = &ctx->Array.Normal;
702      aa->func = normalfuncs[TYPE_IDX(aa->array->Type)];
703      aa++;
704   }
705   if (ctx->Array.Color.Enabled) {
706      aa->array = &ctx->Array.Color;
707      aa->func = colorfuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
708      aa++;
709   }
710   if (ctx->Array.SecondaryColor.Enabled) {
711      aa->array = &ctx->Array.SecondaryColor;
712      aa->func = secondarycolorfuncs[TYPE_IDX(aa->array->Type)];
713      aa++;
714   }
715   if (ctx->Array.FogCoord.Enabled) {
716      aa->array = &ctx->Array.FogCoord;
717      aa->func = fogcoordfuncs[TYPE_IDX(aa->array->Type)];
718      aa++;
719   }
720   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
721      if (ctx->Array.TexCoord[i].Enabled) {
722         /* NOTE: we use generic glVertexAttrib functions here.
723          * If we ever de-alias conventional/generic vertex attribs this
724          * will have to change.
725          */
726         struct gl_client_array *attribArray = &ctx->Array.TexCoord[i];
727         at->array = attribArray;
728         at->func = attribfuncs[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
729         at->index = i;
730         at++;
731      }
732   }
733
734   /* generic vertex attribute arrays */
735   for (i = 1; i < VERT_ATTRIB_MAX; i++) {  /* skip zero! */
736      if (ctx->Array.VertexAttrib[i].Enabled) {
737         struct gl_client_array *attribArray = &ctx->Array.VertexAttrib[i];
738         at->array = attribArray;
739         /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
740          * function pointer here (for float arrays) since the pointer may
741          * change from one execution of _ae_loopback_array_elt() to
742          * the next.  Doing so caused UT to break.
743          */
744         at->func = attribfuncs[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
745         at->index = i;
746         at++;
747      }
748   }
749
750   /* finally, vertex position */
751   if (ctx->Array.VertexAttrib[0].Enabled) {
752      /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
753       * issued as the last (proviking) attribute).
754       */
755      aa->array = &ctx->Array.VertexAttrib[0];
756      assert(aa->array->Size >= 2); /* XXX fix someday? */
757      aa->func = vertexfuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
758      aa++;
759   }
760   else if (ctx->Array.Vertex.Enabled) {
761      aa->array = &ctx->Array.Vertex;
762      aa->func = vertexfuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
763      aa++;
764   }
765
766   ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
767   ASSERT(aa - actx->arrays < 32);
768   at->func = NULL;  /* terminate the list */
769   aa->func = NULL;  /* terminate the list */
770
771   actx->NewState = 0;
772}
773
774
775/**
776 * Called via glArrayElement() and glDrawArrays().
777 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
778 * for all enabled vertex arrays (for elt-th element).
779 * Note: this may be called during display list construction.
780 */
781void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
782{
783   GET_CURRENT_CONTEXT(ctx);
784   const AEcontext *actx = AE_CONTEXT(ctx);
785   const AEarray *aa;
786   const AEattrib *at;
787
788   if (actx->NewState)
789      _ae_update_state( ctx );
790
791   /* generic attributes */
792   for (at = actx->attribs; at->func; at++) {
793      const GLubyte *src = at->array->BufferObj->Data
794                         + (GLuint) at->array->Ptr
795                         + elt * at->array->StrideB;
796      at->func( at->index, src );
797   }
798
799   /* conventional arrays */
800   for (aa = actx->arrays; aa->func ; aa++) {
801      const GLubyte *src = aa->array->BufferObj->Data
802                         + (GLuint) aa->array->Ptr
803                         + elt * aa->array->StrideB;
804      aa->func( src );
805   }
806}
807
808
809
810void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
811{
812   AE_CONTEXT(ctx)->NewState |= new_state;
813}
814