rework to correctly respect _ac_import_range()
[mesa.git] / src / mesa / array_cache / ac_import.c
1 /* $Id: ac_import.c,v 1.5 2001/02/04 00:47:28 keithw Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Author:
27 * Keith Whitwell <keithw@valinux.com>
28 */
29
30 #include "glheader.h"
31 #include "macros.h"
32 #include "mem.h"
33 #include "mmath.h"
34 #include "mtypes.h"
35
36 #include "math/m_translate.h"
37 #include "array_cache/ac_context.h"
38 #include "math/m_translate.h"
39
40 #define STRIDE_ARRAY( array, offset ) \
41 do { \
42 char *tmp = (array).Ptr; \
43 tmp += (offset) * (array).StrideB; \
44 (array).Ptr = tmp; \
45 } while (0)
46
47 /* Set the array pointer back to its source when the cached data is
48 * invalidated:
49 */
50
51 static void reset_texcoord( GLcontext *ctx, GLuint unit )
52 {
53 ACcontext *ac = AC_CONTEXT(ctx);
54
55 if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) {
56 ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
57 STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
58 }
59 else {
60 ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
61
62 if (ctx->Current.Texcoord[unit][4] != 1.0)
63 ac->Raw.TexCoord[unit].Size = 4;
64 else if (ctx->Current.Texcoord[unit][3] != 0.0)
65 ac->Raw.TexCoord[unit].Size = 3;
66 else
67 ac->Raw.TexCoord[unit].Size = 2;
68 }
69
70 ac->IsCached.TexCoord[unit] = GL_FALSE;
71 ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
72 }
73
74 static void reset_vertex( GLcontext *ctx )
75 {
76 ACcontext *ac = AC_CONTEXT(ctx);
77 ASSERT(ctx->Array.Vertex.Enabled);
78 ac->Raw.Vertex = ctx->Array.Vertex;
79 STRIDE_ARRAY(ac->Raw.Vertex, ac->start);
80 ac->IsCached.Vertex = GL_FALSE;
81 ac->NewArrayState &= ~_NEW_ARRAY_VERTEX;
82 }
83
84
85 static void reset_normal( GLcontext *ctx )
86 {
87 ACcontext *ac = AC_CONTEXT(ctx);
88
89 if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) {
90 ac->Raw.Normal = ctx->Array.Normal;
91 STRIDE_ARRAY(ac->Raw.Normal, ac->start);
92 }
93 else {
94 ac->Raw.Normal = ac->Fallback.Normal;
95 }
96
97 ac->IsCached.Normal = GL_FALSE;
98 ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
99 }
100
101
102 static void reset_color( GLcontext *ctx )
103 {
104 ACcontext *ac = AC_CONTEXT(ctx);
105
106
107 if (ctx->Array._Enabled & _NEW_ARRAY_COLOR) {
108 ac->Raw.Color = ctx->Array.Color;
109 STRIDE_ARRAY(ac->Raw.Color, ac->start);
110 }
111 else
112 ac->Raw.Color = ac->Fallback.Color;
113
114 ac->IsCached.Color = GL_FALSE;
115 ac->NewArrayState &= ~_NEW_ARRAY_COLOR;
116 }
117
118
119 static void reset_secondarycolor( GLcontext *ctx )
120 {
121 ACcontext *ac = AC_CONTEXT(ctx);
122
123 if (ctx->Array._Enabled & _NEW_ARRAY_SECONDARYCOLOR) {
124 ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
125 STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
126 }
127 else
128 ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
129
130 ac->IsCached.SecondaryColor = GL_FALSE;
131 ac->NewArrayState &= ~_NEW_ARRAY_SECONDARYCOLOR;
132 }
133
134
135 static void reset_index( GLcontext *ctx )
136 {
137 ACcontext *ac = AC_CONTEXT(ctx);
138
139 if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) {
140 ac->Raw.Index = ctx->Array.Index;
141 STRIDE_ARRAY(ac->Raw.Index, ac->start);
142 }
143 else
144 ac->Raw.Index = ac->Fallback.Index;
145
146 ac->IsCached.Index = GL_FALSE;
147 ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
148 }
149
150 static void reset_fogcoord( GLcontext *ctx )
151 {
152 ACcontext *ac = AC_CONTEXT(ctx);
153
154 if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) {
155 ac->Raw.FogCoord = ctx->Array.FogCoord;
156 STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
157 }
158 else
159 ac->Raw.FogCoord = ac->Fallback.FogCoord;
160
161 ac->IsCached.FogCoord = GL_FALSE;
162 ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
163 }
164
165 static void reset_edgeflag( GLcontext *ctx )
166 {
167 ACcontext *ac = AC_CONTEXT(ctx);
168
169 if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) {
170 ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
171 STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
172 }
173 else
174 ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
175
176 ac->IsCached.EdgeFlag = GL_FALSE;
177 ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
178 }
179
180
181 /* Functions to import array ranges with specified types and strides.
182 */
183 static void import_texcoord( GLcontext *ctx, GLuint unit,
184 GLenum type, GLuint stride )
185 {
186 ACcontext *ac = AC_CONTEXT(ctx);
187 struct gl_client_array *from = &ac->Raw.TexCoord[unit];
188 struct gl_client_array *to = &ac->Cache.TexCoord[unit];
189
190 /* Limited choices at this stage:
191 */
192 ASSERT(type == GL_FLOAT);
193 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
194 ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
195
196 _math_trans_4f( to->Ptr,
197 from->Ptr,
198 from->StrideB,
199 from->Type,
200 from->Size,
201 ac->start,
202 ac->count);
203
204 to->Size = from->Size;
205 to->StrideB = 4 * sizeof(GLfloat);
206 to->Type = GL_FLOAT;
207 ac->IsCached.TexCoord[unit] = GL_TRUE;
208 }
209
210 static void import_vertex( GLcontext *ctx,
211 GLenum type, GLuint stride )
212 {
213 ACcontext *ac = AC_CONTEXT(ctx);
214 struct gl_client_array *from = &ac->Raw.Vertex;
215 struct gl_client_array *to = &ac->Cache.Vertex;
216
217 /* Limited choices at this stage:
218 */
219 ASSERT(type == GL_FLOAT);
220 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
221
222 _math_trans_4f( to->Ptr,
223 from->Ptr,
224 from->StrideB,
225 from->Type,
226 from->Size,
227 0,
228 ac->count - ac->start);
229
230 to->Size = from->Size;
231 to->StrideB = 4 * sizeof(GLfloat);
232 to->Type = GL_FLOAT;
233 ac->IsCached.Vertex = GL_TRUE;
234 }
235
236 static void import_normal( GLcontext *ctx,
237 GLenum type, GLuint stride )
238 {
239 ACcontext *ac = AC_CONTEXT(ctx);
240 struct gl_client_array *from = &ac->Raw.Normal;
241 struct gl_client_array *to = &ac->Cache.Normal;
242
243 /* Limited choices at this stage:
244 */
245 ASSERT(type == GL_FLOAT);
246 ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
247
248 _math_trans_3f( to->Ptr,
249 from->Ptr,
250 from->StrideB,
251 from->Type,
252 0,
253 ac->count - ac->start);
254
255 to->StrideB = 3 * sizeof(GLfloat);
256 to->Type = GL_FLOAT;
257 ac->IsCached.Normal = GL_TRUE;
258 }
259
260 static void import_color( GLcontext *ctx,
261 GLenum type, GLuint stride )
262 {
263 ACcontext *ac = AC_CONTEXT(ctx);
264 struct gl_client_array *from = &ac->Raw.Color;
265 struct gl_client_array *to = &ac->Cache.Color;
266
267 /* Limited choices at this stage:
268 */
269 /* XXX GLchan: is this right for GLchan? */
270 ASSERT(type == CHAN_TYPE);
271 ASSERT(stride == 4 * sizeof(GLchan) || stride == 0);
272
273 #if CHAN_TYPE == GL_UNSIGNED_BYTE
274 _math_trans_4ub( to->Ptr,
275 from->Ptr,
276 from->StrideB,
277 from->Type,
278 from->Size,
279 0,
280 ac->count - ac->start);
281 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
282 _math_trans_4us( to->Ptr,
283 from->Ptr,
284 from->StrideB,
285 from->Type,
286 from->Size,
287 0,
288 ac->count - ac->start);
289 #elif CHAN_TYPE == GL_FLOAT
290 _math_trans_4f( to->Ptr,
291 from->Ptr,
292 from->StrideB,
293 from->Type,
294 from->Size,
295 0,
296 ac->count - ac->start);
297 #endif
298
299 to->Size = from->Size;
300 to->StrideB = 4 * sizeof(GLchan);
301 to->Type = CHAN_TYPE;
302 ac->IsCached.Color = GL_TRUE;
303 }
304
305 static void import_index( GLcontext *ctx,
306 GLenum type, GLuint stride )
307 {
308 ACcontext *ac = AC_CONTEXT(ctx);
309 struct gl_client_array *from = &ac->Raw.Index;
310 struct gl_client_array *to = &ac->Cache.Index;
311
312 /* Limited choices at this stage:
313 */
314 ASSERT(type == GL_UNSIGNED_INT);
315 ASSERT(stride == sizeof(GLuint) || stride == 0);
316
317 _math_trans_1ui( to->Ptr,
318 from->Ptr,
319 from->StrideB,
320 from->Type,
321 0,
322 ac->count - ac->start);
323
324 to->StrideB = sizeof(GLuint);
325 to->Type = GL_UNSIGNED_INT;
326 ac->IsCached.Index = GL_TRUE;
327 }
328
329 static void import_secondarycolor( GLcontext *ctx,
330 GLenum type, GLuint stride )
331 {
332 ACcontext *ac = AC_CONTEXT(ctx);
333 struct gl_client_array *from = &ac->Raw.SecondaryColor;
334 struct gl_client_array *to = &ac->Cache.SecondaryColor;
335
336 /* Limited choices at this stage:
337 */
338 ASSERT(type == CHAN_TYPE);
339 ASSERT(stride == 4 * sizeof(GLchan) || stride == 0);
340
341 #if CHAN_TYPE == GL_UNSIGNED_BYTE
342 _math_trans_4ub( to->Ptr,
343 from->Ptr,
344 from->StrideB,
345 from->Type,
346 from->Size,
347 0,
348 ac->count - ac->start);
349 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
350 _math_trans_4us( to->Ptr,
351 from->Ptr,
352 from->StrideB,
353 from->Type,
354 from->Size,
355 0,
356 ac->count - ac->start);
357 #elif CHAN_TYPE == GL_FLOAT
358 _math_trans_4f( to->Ptr,
359 from->Ptr,
360 from->StrideB,
361 from->Type,
362 from->Size,
363 0,
364 ac->count - ac->start);
365 #endif
366
367 to->StrideB = 4 * sizeof(GLchan);
368 to->Type = CHAN_TYPE;
369 ac->IsCached.SecondaryColor = GL_TRUE;
370 }
371
372 static void import_fogcoord( GLcontext *ctx,
373 GLenum type, GLuint stride )
374 {
375 ACcontext *ac = AC_CONTEXT(ctx);
376 struct gl_client_array *from = &ac->Raw.FogCoord;
377 struct gl_client_array *to = &ac->Cache.FogCoord;
378
379 /* Limited choices at this stage:
380 */
381 ASSERT(type == GL_FLOAT);
382 ASSERT(stride == sizeof(GLfloat) || stride == 0);
383
384 _math_trans_1f( to->Ptr,
385 from->Ptr,
386 from->StrideB,
387 from->Type,
388 0,
389 ac->count - ac->start);
390
391 to->StrideB = sizeof(GLfloat);
392 to->Type = GL_FLOAT;
393 ac->IsCached.FogCoord = GL_TRUE;
394 }
395
396 static void import_edgeflag( GLcontext *ctx,
397 GLenum type, GLuint stride )
398 {
399 ACcontext *ac = AC_CONTEXT(ctx);
400 struct gl_client_array *from = &ac->Raw.EdgeFlag;
401 struct gl_client_array *to = &ac->Cache.EdgeFlag;
402
403 /* Limited choices at this stage:
404 */
405 ASSERT(type == GL_FLOAT);
406 ASSERT(stride == sizeof(GLfloat) || stride == 0);
407
408 _math_trans_1f( to->Ptr,
409 from->Ptr,
410 from->StrideB,
411 from->Type,
412 0,
413 ac->count - ac->start);
414
415 to->StrideB = sizeof(GLfloat);
416 to->Type = GL_FLOAT;
417 ac->IsCached.EdgeFlag = GL_TRUE;
418 }
419
420
421
422 /* Externals to request arrays with specific properties:
423 */
424 struct gl_client_array *_ac_import_texcoord( GLcontext *ctx,
425 GLuint unit,
426 GLenum type,
427 GLuint reqstride,
428 GLuint reqsize,
429 GLboolean reqwriteable,
430 GLboolean *writeable )
431 {
432 ACcontext *ac = AC_CONTEXT(ctx);
433
434 /* Can we keep the existing version?
435 */
436 if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
437 reset_texcoord( ctx, unit );
438
439 /* Is the request impossible?
440 */
441 if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > reqsize)
442 return 0;
443
444 /* Do we need to pull in a copy of the client data:
445 */
446 if (ac->Raw.TexCoord[unit].Type != type ||
447 (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != reqstride) ||
448 reqwriteable)
449 {
450 if (!ac->IsCached.TexCoord[unit])
451 import_texcoord(ctx, unit, type, reqstride );
452 *writeable = GL_TRUE;
453 return &ac->Cache.TexCoord[unit];
454 }
455 else {
456 *writeable = GL_FALSE;
457 return &ac->Raw.TexCoord[unit];
458 }
459 }
460
461 struct gl_client_array *_ac_import_vertex( GLcontext *ctx,
462 GLenum type,
463 GLuint reqstride,
464 GLuint reqsize,
465 GLboolean reqwriteable,
466 GLboolean *writeable )
467 {
468 ACcontext *ac = AC_CONTEXT(ctx);
469
470 /* Can we keep the existing version?
471 */
472 if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
473 reset_vertex( ctx );
474
475 /* Is the request impossible?
476 */
477 if (reqsize != 0 && ac->Raw.Vertex.Size > reqsize)
478 return 0;
479
480 /* Do we need to pull in a copy of the client data:
481 */
482 if (ac->Raw.Vertex.Type != type ||
483 (reqstride != 0 && ac->Raw.Vertex.StrideB != reqstride) ||
484 reqwriteable)
485 {
486 if (!ac->IsCached.Vertex)
487 import_vertex(ctx, type, reqstride );
488 *writeable = GL_TRUE;
489 return &ac->Cache.Vertex;
490 }
491 else {
492 *writeable = GL_FALSE;
493 return &ac->Raw.Vertex;
494 }
495 }
496
497 struct gl_client_array *_ac_import_normal( GLcontext *ctx,
498 GLenum type,
499 GLuint reqstride,
500 GLboolean reqwriteable,
501 GLboolean *writeable )
502 {
503 ACcontext *ac = AC_CONTEXT(ctx);
504
505 /* Can we keep the existing version?
506 */
507 if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
508 reset_normal( ctx );
509
510 /* Do we need to pull in a copy of the client data:
511 */
512 if (ac->Raw.Normal.Type != type ||
513 (reqstride != 0 && ac->Raw.Normal.StrideB != reqstride) ||
514 reqwriteable)
515 {
516 if (!ac->IsCached.Normal)
517 import_normal(ctx, type, reqstride );
518 *writeable = GL_TRUE;
519 return &ac->Cache.Normal;
520 }
521 else {
522 *writeable = GL_FALSE;
523 return &ac->Raw.Normal;
524 }
525 }
526
527 struct gl_client_array *_ac_import_color( GLcontext *ctx,
528 GLenum type,
529 GLuint reqstride,
530 GLuint reqsize,
531 GLboolean reqwriteable,
532 GLboolean *writeable )
533 {
534 ACcontext *ac = AC_CONTEXT(ctx);
535
536 /* Can we keep the existing version?
537 */
538 if (ac->NewArrayState & _NEW_ARRAY_COLOR)
539 reset_color( ctx );
540
541 /* Is the request impossible?
542 */
543 if (reqsize != 0 && ac->Raw.Color.Size > reqsize) {
544 return 0;
545 }
546
547 /* Do we need to pull in a copy of the client data:
548 */
549 if (ac->Raw.Color.Type != type ||
550 (reqstride != 0 && ac->Raw.Color.StrideB != reqstride) ||
551 reqwriteable)
552 {
553 if (!ac->IsCached.Color)
554 import_color(ctx, type, reqstride );
555 *writeable = GL_TRUE;
556 return &ac->Cache.Color;
557 }
558 else {
559 *writeable = GL_FALSE;
560 return &ac->Raw.Color;
561 }
562 }
563
564 struct gl_client_array *_ac_import_index( GLcontext *ctx,
565 GLenum type,
566 GLuint reqstride,
567 GLboolean reqwriteable,
568 GLboolean *writeable )
569 {
570 ACcontext *ac = AC_CONTEXT(ctx);
571
572 /* Can we keep the existing version?
573 */
574 if (ac->NewArrayState & _NEW_ARRAY_INDEX)
575 reset_index( ctx );
576
577
578 /* Do we need to pull in a copy of the client data:
579 */
580 if (ac->Raw.Index.Type != type ||
581 (reqstride != 0 && ac->Raw.Index.StrideB != reqstride) ||
582 reqwriteable)
583 {
584 if (!ac->IsCached.Index)
585 import_index(ctx, type, reqstride );
586 *writeable = GL_TRUE;
587 return &ac->Cache.Index;
588 }
589 else {
590 *writeable = GL_FALSE;
591 return &ac->Raw.Index;
592 }
593 }
594
595 struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx,
596 GLenum type,
597 GLuint reqstride,
598 GLuint reqsize,
599 GLboolean reqwriteable,
600 GLboolean *writeable )
601 {
602 ACcontext *ac = AC_CONTEXT(ctx);
603
604 /* Can we keep the existing version?
605 */
606 if (ac->NewArrayState & _NEW_ARRAY_SECONDARYCOLOR)
607 reset_secondarycolor( ctx );
608
609 /* Is the request impossible?
610 */
611 if (reqsize != 0 && ac->Raw.SecondaryColor.Size > reqsize)
612 return 0;
613
614 /* Do we need to pull in a copy of the client data:
615 */
616 if (ac->Raw.SecondaryColor.Type != type ||
617 (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != reqstride) ||
618 reqwriteable)
619 {
620 if (!ac->IsCached.SecondaryColor)
621 import_secondarycolor(ctx, type, reqstride );
622 *writeable = GL_TRUE;
623 return &ac->Cache.SecondaryColor;
624 }
625 else {
626 *writeable = GL_FALSE;
627 return &ac->Raw.SecondaryColor;
628 }
629 }
630
631 struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx,
632 GLenum type,
633 GLuint reqstride,
634 GLboolean reqwriteable,
635 GLboolean *writeable )
636 {
637 ACcontext *ac = AC_CONTEXT(ctx);
638
639 /* Can we keep the existing version?
640 */
641 if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
642 reset_fogcoord( ctx );
643
644 /* Do we need to pull in a copy of the client data:
645 */
646 if (ac->Raw.FogCoord.Type != type ||
647 (reqstride != 0 && ac->Raw.FogCoord.StrideB != reqstride) ||
648 reqwriteable)
649 {
650 if (!ac->IsCached.FogCoord)
651 import_fogcoord(ctx, type, reqstride );
652 *writeable = GL_TRUE;
653 return &ac->Cache.FogCoord;
654 }
655 else {
656 *writeable = GL_FALSE;
657 return &ac->Raw.FogCoord;
658 }
659 }
660
661
662
663
664 struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx,
665 GLenum type,
666 GLuint reqstride,
667 GLboolean reqwriteable,
668 GLboolean *writeable )
669 {
670 ACcontext *ac = AC_CONTEXT(ctx);
671
672 /* Can we keep the existing version?
673 */
674 if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
675 reset_edgeflag( ctx );
676
677 /* Do we need to pull in a copy of the client data:
678 */
679 if (ac->Raw.EdgeFlag.Type != type ||
680 (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != reqstride) ||
681 reqwriteable)
682 {
683 if (!ac->IsCached.EdgeFlag)
684 import_edgeflag(ctx, type, reqstride );
685 *writeable = GL_TRUE;
686 return &ac->Cache.EdgeFlag;
687 }
688 else {
689 *writeable = GL_FALSE;
690 return &ac->Raw.EdgeFlag;
691 }
692 }
693
694
695
696
697
698 /* Clients must call this function to validate state and set bounds
699 * before importing any data:
700 */
701 void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
702 {
703 ACcontext *ac = AC_CONTEXT(ctx);
704
705 /* Discard cached data which has been invalidated by state changes
706 * since last time. **ALREADY DONE**
707 if (ac->NewState)
708 _ac_update_state( ctx );
709 */
710
711 if (!ctx->Array.LockCount) {
712 /* Not locked, discard cached data. Changes to lock
713 * status are caught via. _ac_invalidate_state().
714 */
715 ac->NewArrayState = _NEW_ARRAY_ALL;
716 ac->start = start;
717 ac->count = count;
718 }
719 else {
720 /* Locked, discard data for any disabled arrays. Require that
721 * the whole locked range always be dealt with, otherwise hard to
722 * maintain cached data in the face of clipping.
723 */
724 ac->NewArrayState |= ~ctx->Array._Enabled;
725 ac->start = ctx->Array.LockFirst;
726 ac->count = ctx->Array.LockCount;
727 ASSERT(ac->start == start); /* hmm? */
728 ASSERT(ac->count == count);
729 }
730 }
731
732
733
734 /* Additional convienence function for importing a the element list
735 * for drawelements, drawrangeelements:
736 */
737 CONST void *
738 _ac_import_elements( GLcontext *ctx,
739 GLenum new_type,
740 GLuint count,
741 GLenum old_type,
742 CONST void *indices )
743 {
744 ACcontext *ac = AC_CONTEXT(ctx);
745
746 if (old_type == new_type)
747 return indices;
748
749 if (ac->elt_size < count * sizeof(GLuint)) {
750 if (ac->Elts) FREE(ac->Elts);
751 while (ac->elt_size < count * sizeof(GLuint))
752 ac->elt_size *= 2;
753 ac->Elts = MALLOC(ac->elt_size);
754 }
755
756 switch (new_type) {
757 case GL_UNSIGNED_BYTE:
758 ASSERT(0);
759 return 0;
760 case GL_UNSIGNED_SHORT:
761 ASSERT(0);
762 return 0;
763 case GL_UNSIGNED_INT: {
764 GLuint *out = (GLuint *)ac->Elts;
765 GLuint i;
766
767 switch (old_type) {
768 case GL_UNSIGNED_BYTE: {
769 CONST GLubyte *in = (CONST GLubyte *)indices;
770 for (i = 0 ; i < count ; i++)
771 out[i] = in[i];
772 break;
773 }
774 case GL_UNSIGNED_SHORT: {
775 CONST GLushort *in = (CONST GLushort *)indices;
776 for (i = 0 ; i < count ; i++)
777 out[i] = in[i];
778 break;
779 }
780 default:
781 ASSERT(0);
782 }
783
784 return (CONST void *)out;
785 }
786 default:
787 ASSERT(0);
788 break;
789 }
790
791 return 0;
792 }
793