added mutexes for thread safety
[mesa.git] / src / mesa / main / context.c
1 /* $Id: context.c,v 1.37 2000/01/31 23:11:39 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999-2000 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
27
28 #ifdef PC_HEADER
29 #include "all.h"
30 #else
31 #include "glheader.h"
32 #include "accum.h"
33 #include "alphabuf.h"
34 #include "clip.h"
35 #include "context.h"
36 #include "cva.h"
37 #include "depth.h"
38 #include "dispatch.h"
39 #include "dlist.h"
40 #include "eval.h"
41 #include "enums.h"
42 #include "extensions.h"
43 #include "fog.h"
44 #include "get.h"
45 #include "glapi.h"
46 #include "glapinoop.h"
47 #include "glthread.h"
48 #include "hash.h"
49 #include "light.h"
50 #include "lines.h"
51 #include "dlist.h"
52 #include "macros.h"
53 #include "matrix.h"
54 #include "mem.h"
55 #include "mmath.h"
56 #include "pb.h"
57 #include "pipeline.h"
58 #include "points.h"
59 #include "quads.h"
60 #include "shade.h"
61 #include "simple_list.h"
62 #include "stencil.h"
63 #include "stages.h"
64 #include "triangle.h"
65 #include "translate.h"
66 #include "teximage.h"
67 #include "texobj.h"
68 #include "texstate.h"
69 #include "texture.h"
70 #include "types.h"
71 #include "varray.h"
72 #include "vb.h"
73 #include "vbcull.h"
74 #include "vbfill.h"
75 #include "vbrender.h"
76 #include "vbxform.h"
77 #include "vertices.h"
78 #include "xform.h"
79 #endif
80
81
82
83 /**********************************************************************/
84 /***** Context and Thread management *****/
85 /**********************************************************************/
86
87
88 #if !defined(THREADS)
89
90 struct immediate *_mesa_CurrentInput = NULL;
91
92 #endif
93
94
95
96
97 /**********************************************************************/
98 /***** Profiling functions *****/
99 /**********************************************************************/
100
101 #ifdef PROFILE
102
103 #include <sys/times.h>
104 #include <sys/param.h>
105
106
107 /*
108 * Return system time in seconds.
109 * NOTE: this implementation may not be very portable!
110 */
111 GLdouble gl_time( void )
112 {
113 static GLdouble prev_time = 0.0;
114 static GLdouble time;
115 struct tms tm;
116 clock_t clk;
117
118 clk = times(&tm);
119
120 #ifdef CLK_TCK
121 time = (double)clk / (double)CLK_TCK;
122 #else
123 time = (double)clk / (double)HZ;
124 #endif
125
126 if (time>prev_time) {
127 prev_time = time;
128 return time;
129 }
130 else {
131 return prev_time;
132 }
133 }
134
135 /*
136 * Reset the timing/profiling counters
137 */
138 static void init_timings( GLcontext *ctx )
139 {
140 ctx->BeginEndCount = 0;
141 ctx->BeginEndTime = 0.0;
142 ctx->VertexCount = 0;
143 ctx->VertexTime = 0.0;
144 ctx->PointCount = 0;
145 ctx->PointTime = 0.0;
146 ctx->LineCount = 0;
147 ctx->LineTime = 0.0;
148 ctx->PolygonCount = 0;
149 ctx->PolygonTime = 0.0;
150 ctx->ClearCount = 0;
151 ctx->ClearTime = 0.0;
152 ctx->SwapCount = 0;
153 ctx->SwapTime = 0.0;
154 }
155
156
157 /*
158 * Print the accumulated timing/profiling data.
159 */
160 static void print_timings( GLcontext *ctx )
161 {
162 GLdouble beginendrate;
163 GLdouble vertexrate;
164 GLdouble pointrate;
165 GLdouble linerate;
166 GLdouble polygonrate;
167 GLdouble overhead;
168 GLdouble clearrate;
169 GLdouble swaprate;
170 GLdouble avgvertices;
171
172 if (ctx->BeginEndTime>0.0) {
173 beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
174 }
175 else {
176 beginendrate = 0.0;
177 }
178 if (ctx->VertexTime>0.0) {
179 vertexrate = ctx->VertexCount / ctx->VertexTime;
180 }
181 else {
182 vertexrate = 0.0;
183 }
184 if (ctx->PointTime>0.0) {
185 pointrate = ctx->PointCount / ctx->PointTime;
186 }
187 else {
188 pointrate = 0.0;
189 }
190 if (ctx->LineTime>0.0) {
191 linerate = ctx->LineCount / ctx->LineTime;
192 }
193 else {
194 linerate = 0.0;
195 }
196 if (ctx->PolygonTime>0.0) {
197 polygonrate = ctx->PolygonCount / ctx->PolygonTime;
198 }
199 else {
200 polygonrate = 0.0;
201 }
202 if (ctx->ClearTime>0.0) {
203 clearrate = ctx->ClearCount / ctx->ClearTime;
204 }
205 else {
206 clearrate = 0.0;
207 }
208 if (ctx->SwapTime>0.0) {
209 swaprate = ctx->SwapCount / ctx->SwapTime;
210 }
211 else {
212 swaprate = 0.0;
213 }
214
215 if (ctx->BeginEndCount>0) {
216 avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
217 }
218 else {
219 avgvertices = 0.0;
220 }
221
222 overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
223 - ctx->LineTime - ctx->PolygonTime;
224
225
226 printf(" Count Time (s) Rate (/s) \n");
227 printf("--------------------------------------------------------\n");
228 printf("glBegin/glEnd %7d %8.3f %10.3f\n",
229 ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
230 printf(" vertexes transformed %7d %8.3f %10.3f\n",
231 ctx->VertexCount, ctx->VertexTime, vertexrate );
232 printf(" points rasterized %7d %8.3f %10.3f\n",
233 ctx->PointCount, ctx->PointTime, pointrate );
234 printf(" lines rasterized %7d %8.3f %10.3f\n",
235 ctx->LineCount, ctx->LineTime, linerate );
236 printf(" polygons rasterized %7d %8.3f %10.3f\n",
237 ctx->PolygonCount, ctx->PolygonTime, polygonrate );
238 printf(" overhead %8.3f\n", overhead );
239 printf("glClear %7d %8.3f %10.3f\n",
240 ctx->ClearCount, ctx->ClearTime, clearrate );
241 printf("SwapBuffers %7d %8.3f %10.3f\n",
242 ctx->SwapCount, ctx->SwapTime, swaprate );
243 printf("\n");
244
245 printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
246 }
247 #endif
248
249
250
251
252
253 /**********************************************************************/
254 /***** GL Visual allocation/destruction *****/
255 /**********************************************************************/
256
257
258 /*
259 * Allocate a new GLvisual object.
260 * Input: rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
261 * alphaFlag - alloc software alpha buffers?
262 * dbFlag - double buffering?
263 * stereoFlag - stereo buffer?
264 * depthFits - requested minimum bits per depth buffer value
265 * stencilFits - requested minimum bits per stencil buffer value
266 * accumFits - requested minimum bits per accum buffer component
267 * indexFits - number of bits per pixel if rgbFlag==GL_FALSE
268 * red/green/blue/alphaFits - number of bits per color component
269 * in frame buffer for RGB(A) mode.
270 * Return: pointer to new GLvisual or NULL if requested parameters can't
271 * be met.
272 */
273 GLvisual *gl_create_visual( GLboolean rgbFlag,
274 GLboolean alphaFlag,
275 GLboolean dbFlag,
276 GLboolean stereoFlag,
277 GLint depthBits,
278 GLint stencilBits,
279 GLint accumBits,
280 GLint indexBits,
281 GLint redBits,
282 GLint greenBits,
283 GLint blueBits,
284 GLint alphaBits )
285 {
286 GLvisual *vis;
287
288 if (depthBits > (GLint) (8*sizeof(GLdepth))) {
289 /* can't meet depth buffer requirements */
290 return NULL;
291 }
292 if (stencilBits > (GLint) (8*sizeof(GLstencil))) {
293 /* can't meet stencil buffer requirements */
294 return NULL;
295 }
296 if (accumBits > (GLint) (8*sizeof(GLaccum))) {
297 /* can't meet accum buffer requirements */
298 return NULL;
299 }
300
301 vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
302 if (!vis) {
303 return NULL;
304 }
305
306 vis->RGBAflag = rgbFlag;
307 vis->DBflag = dbFlag;
308 vis->StereoFlag = stereoFlag;
309 vis->RedBits = redBits;
310 vis->GreenBits = greenBits;
311 vis->BlueBits = blueBits;
312 vis->AlphaBits = alphaFlag ? 8*sizeof(GLubyte) : alphaBits;
313
314 vis->IndexBits = indexBits;
315 vis->DepthBits = (depthBits>0) ? 8*sizeof(GLdepth) : 0;
316 vis->AccumBits = (accumBits>0) ? 8*sizeof(GLaccum) : 0;
317 vis->StencilBits = (stencilBits>0) ? 8*sizeof(GLstencil) : 0;
318
319 vis->SoftwareAlpha = alphaFlag;
320
321 return vis;
322 }
323
324
325
326 void gl_destroy_visual( GLvisual *vis )
327 {
328 FREE( vis );
329 }
330
331
332
333 /**********************************************************************/
334 /***** GL Framebuffer allocation/destruction *****/
335 /**********************************************************************/
336
337
338 /*
339 * Create a new framebuffer. A GLframebuffer is a struct which
340 * encapsulates the depth, stencil and accum buffers and related
341 * parameters.
342 * Input: visual - a GLvisual pointer
343 * softwareDepth - create/use a software depth buffer?
344 * softwareStencil - create/use a software stencil buffer?
345 * softwareAccum - create/use a software accum buffer?
346 * softwareAlpha - create/use a software alpha buffer?
347
348 * Return: pointer to new GLframebuffer struct or NULL if error.
349 */
350 GLframebuffer *gl_create_framebuffer( GLvisual *visual,
351 GLboolean softwareDepth,
352 GLboolean softwareStencil,
353 GLboolean softwareAccum,
354 GLboolean softwareAlpha )
355 {
356 GLframebuffer *buffer;
357
358 buffer = CALLOC_STRUCT(gl_frame_buffer);
359 if (!buffer) {
360 return NULL;
361 }
362
363 /* sanity checks */
364 if (softwareDepth ) {
365 assert(visual->DepthBits > 0);
366 }
367 if (softwareStencil) {
368 assert(visual->StencilBits > 0);
369 }
370 if (softwareAccum) {
371 assert(visual->RGBAflag);
372 assert(visual->AccumBits > 0);
373 }
374 if (softwareAlpha) {
375 assert(visual->RGBAflag);
376 assert(visual->AlphaBits > 0);
377 }
378
379 buffer->Visual = visual;
380 buffer->UseSoftwareDepthBuffer = softwareDepth;
381 buffer->UseSoftwareStencilBuffer = softwareStencil;
382 buffer->UseSoftwareAccumBuffer = softwareAccum;
383 buffer->UseSoftwareAlphaBuffers = softwareAlpha;
384
385 return buffer;
386 }
387
388
389
390 /*
391 * Free a framebuffer struct and its buffers.
392 */
393 void gl_destroy_framebuffer( GLframebuffer *buffer )
394 {
395 if (buffer) {
396 if (buffer->Depth) {
397 FREE( buffer->Depth );
398 }
399 if (buffer->Accum) {
400 FREE( buffer->Accum );
401 }
402 if (buffer->Stencil) {
403 FREE( buffer->Stencil );
404 }
405 if (buffer->FrontLeftAlpha) {
406 FREE( buffer->FrontLeftAlpha );
407 }
408 if (buffer->BackLeftAlpha) {
409 FREE( buffer->BackLeftAlpha );
410 }
411 if (buffer->FrontRightAlpha) {
412 FREE( buffer->FrontRightAlpha );
413 }
414 if (buffer->BackRightAlpha) {
415 FREE( buffer->BackRightAlpha );
416 }
417 FREE(buffer);
418 }
419 }
420
421
422
423 /**********************************************************************/
424 /***** Context allocation, initialization, destroying *****/
425 /**********************************************************************/
426
427
428 _glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
429
430
431 /*
432 * This function just calls all the various one-time-init functions in Mesa.
433 */
434 static void one_time_init( void )
435 {
436 static GLboolean alreadyCalled = GL_FALSE;
437 _glthread_LOCK_MUTEX(OneTimeLock);
438 if (!alreadyCalled) {
439 /* do some implementation tests */
440 assert( sizeof(GLbyte) == 1 );
441 assert( sizeof(GLshort) >= 2 );
442 assert( sizeof(GLint) >= 4 );
443 assert( sizeof(GLubyte) == 1 );
444 assert( sizeof(GLushort) >= 2 );
445 assert( sizeof(GLuint) >= 4 );
446
447 gl_init_clip();
448 gl_init_eval();
449 gl_init_fog();
450 gl_init_math();
451 gl_init_lists();
452 gl_init_shade();
453 gl_init_texture();
454 gl_init_transformation();
455 gl_init_translate();
456 gl_init_vbrender();
457 gl_init_vbxform();
458 gl_init_vertices();
459
460 if (getenv("MESA_DEBUG")) {
461 _glapi_noop_enable_warnings(GL_TRUE);
462 }
463 else {
464 _glapi_noop_enable_warnings(GL_FALSE);
465 }
466
467 #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
468 fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
469 #endif
470
471 alreadyCalled = GL_TRUE;
472 }
473 _glthread_UNLOCK_MUTEX(OneTimeLock);
474 }
475
476
477
478 /*
479 * Allocate and initialize a shared context state structure.
480 */
481 static struct gl_shared_state *alloc_shared_state( void )
482 {
483 GLuint d;
484 struct gl_shared_state *ss;
485 GLboolean outOfMemory;
486
487 ss = CALLOC_STRUCT(gl_shared_state);
488 if (!ss)
489 return NULL;
490
491 ss->DisplayList = _mesa_NewHashTable();
492
493 ss->TexObjects = _mesa_NewHashTable();
494
495 /* Default Texture objects */
496 outOfMemory = GL_FALSE;
497 for (d = 1 ; d <= 3 ; d++) {
498 ss->DefaultD[d] = gl_alloc_texture_object(ss, 0, d);
499 if (!ss->DefaultD[d]) {
500 outOfMemory = GL_TRUE;
501 break;
502 }
503 ss->DefaultD[d]->RefCount++; /* don't free if not in use */
504 }
505
506 if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
507 /* Ran out of memory at some point. Free everything and return NULL */
508 if (ss->DisplayList)
509 _mesa_DeleteHashTable(ss->DisplayList);
510 if (ss->TexObjects)
511 _mesa_DeleteHashTable(ss->TexObjects);
512 if (ss->DefaultD[1])
513 gl_free_texture_object(ss, ss->DefaultD[1]);
514 if (ss->DefaultD[2])
515 gl_free_texture_object(ss, ss->DefaultD[2]);
516 if (ss->DefaultD[3])
517 gl_free_texture_object(ss, ss->DefaultD[3]);
518 FREE(ss);
519 return NULL;
520 }
521 else {
522 return ss;
523 }
524 }
525
526
527 /*
528 * Deallocate a shared state context and all children structures.
529 */
530 static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
531 {
532 /* Free display lists */
533 while (1) {
534 GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
535 if (list) {
536 gl_destroy_list(ctx, list);
537 }
538 else {
539 break;
540 }
541 }
542 _mesa_DeleteHashTable(ss->DisplayList);
543
544 /* Free texture objects */
545 while (ss->TexObjectList)
546 {
547 if (ctx->Driver.DeleteTexture)
548 (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
549 /* this function removes from linked list too! */
550 gl_free_texture_object(ss, ss->TexObjectList);
551 }
552 _mesa_DeleteHashTable(ss->TexObjects);
553
554 FREE(ss);
555 }
556
557
558
559 /*
560 * Initialize the nth light. Note that the defaults for light 0 are
561 * different than the other lights.
562 */
563 static void init_light( struct gl_light *l, GLuint n )
564 {
565 make_empty_list( l );
566
567 ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
568 if (n==0) {
569 ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
570 ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
571 }
572 else {
573 ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
574 ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
575 }
576 ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
577 ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
578 l->SpotExponent = 0.0;
579 gl_compute_spot_exp_table( l );
580 l->SpotCutoff = 180.0;
581 l->CosCutoff = 0.0; /* KW: -ve values not admitted */
582 l->ConstantAttenuation = 1.0;
583 l->LinearAttenuation = 0.0;
584 l->QuadraticAttenuation = 0.0;
585 l->Enabled = GL_FALSE;
586 }
587
588
589
590 static void init_lightmodel( struct gl_lightmodel *lm )
591 {
592 ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
593 lm->LocalViewer = GL_FALSE;
594 lm->TwoSide = GL_FALSE;
595 lm->ColorControl = GL_SINGLE_COLOR;
596 }
597
598
599 static void init_material( struct gl_material *m )
600 {
601 ASSIGN_4V( m->Ambient, 0.2, 0.2, 0.2, 1.0 );
602 ASSIGN_4V( m->Diffuse, 0.8, 0.8, 0.8, 1.0 );
603 ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 );
604 ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 );
605 m->Shininess = 0.0;
606 m->AmbientIndex = 0;
607 m->DiffuseIndex = 1;
608 m->SpecularIndex = 1;
609 }
610
611
612
613 static void init_texture_unit( GLcontext *ctx, GLuint unit )
614 {
615 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
616
617 texUnit->EnvMode = GL_MODULATE;
618 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
619 texUnit->TexGenEnabled = 0;
620 texUnit->GenModeS = GL_EYE_LINEAR;
621 texUnit->GenModeT = GL_EYE_LINEAR;
622 texUnit->GenModeR = GL_EYE_LINEAR;
623 texUnit->GenModeQ = GL_EYE_LINEAR;
624 /* Yes, these plane coefficients are correct! */
625 ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
626 ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
627 ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
628 ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
629 ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
630 ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
631 ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
632 ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
633
634 texUnit->CurrentD[1] = ctx->Shared->DefaultD[1];
635 texUnit->CurrentD[2] = ctx->Shared->DefaultD[2];
636 texUnit->CurrentD[3] = ctx->Shared->DefaultD[3];
637 }
638
639
640 static void init_fallback_arrays( GLcontext *ctx )
641 {
642 struct gl_client_array *cl;
643 GLuint i;
644
645 cl = &ctx->Fallback.Normal;
646 cl->Size = 3;
647 cl->Type = GL_FLOAT;
648 cl->Stride = 0;
649 cl->StrideB = 0;
650 cl->Ptr = (void *) ctx->Current.Normal;
651 cl->Enabled = 1;
652
653 cl = &ctx->Fallback.Color;
654 cl->Size = 4;
655 cl->Type = GL_UNSIGNED_BYTE;
656 cl->Stride = 0;
657 cl->StrideB = 0;
658 cl->Ptr = (void *) ctx->Current.ByteColor;
659 cl->Enabled = 1;
660
661 cl = &ctx->Fallback.Index;
662 cl->Size = 1;
663 cl->Type = GL_UNSIGNED_INT;
664 cl->Stride = 0;
665 cl->StrideB = 0;
666 cl->Ptr = (void *) &ctx->Current.Index;
667 cl->Enabled = 1;
668
669 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
670 cl = &ctx->Fallback.TexCoord[i];
671 cl->Size = 4;
672 cl->Type = GL_FLOAT;
673 cl->Stride = 0;
674 cl->StrideB = 0;
675 cl->Ptr = (void *) ctx->Current.Texcoord[i];
676 cl->Enabled = 1;
677 }
678
679 cl = &ctx->Fallback.EdgeFlag;
680 cl->Size = 1;
681 cl->Type = GL_UNSIGNED_BYTE;
682 cl->Stride = 0;
683 cl->StrideB = 0;
684 cl->Ptr = (void *) &ctx->Current.EdgeFlag;
685 cl->Enabled = 1;
686 }
687
688
689 /* Initialize a 1-D evaluator map */
690 static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
691 {
692 map->Order = 1;
693 map->u1 = 0.0;
694 map->u2 = 1.0;
695 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
696 if (map->Points) {
697 GLint i;
698 for (i=0;i<n;i++)
699 map->Points[i] = initial[i];
700 }
701 }
702
703
704 /* Initialize a 2-D evaluator map */
705 static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
706 {
707 map->Uorder = 1;
708 map->Vorder = 1;
709 map->u1 = 0.0;
710 map->u2 = 1.0;
711 map->v1 = 0.0;
712 map->v2 = 1.0;
713 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
714 if (map->Points) {
715 GLint i;
716 for (i=0;i<n;i++)
717 map->Points[i] = initial[i];
718 }
719 }
720
721
722 static void init_color_table( struct gl_color_table *p )
723 {
724 p->Table[0] = 255;
725 p->Table[1] = 255;
726 p->Table[2] = 255;
727 p->Table[3] = 255;
728 p->Size = 1;
729 p->IntFormat = GL_RGBA;
730 p->Format = GL_RGBA;
731 }
732
733
734 /*
735 * Initialize the attribute groups in a GLcontext.
736 */
737 static void init_attrib_groups( GLcontext *ctx )
738 {
739 GLuint i, j;
740
741 assert(ctx);
742
743 /* Constants, may be overriden by device driver */
744 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
745 ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
746 ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
747 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
748
749 /* Modelview matrix */
750 gl_matrix_ctr( &ctx->ModelView );
751 gl_matrix_alloc_inv( &ctx->ModelView );
752
753 ctx->ModelViewStackDepth = 0;
754 for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
755 gl_matrix_ctr( &ctx->ModelViewStack[i] );
756 gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
757 }
758
759 /* Projection matrix - need inv for user clipping in clip space*/
760 gl_matrix_ctr( &ctx->ProjectionMatrix );
761 gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
762
763 gl_matrix_ctr( &ctx->ModelProjectMatrix );
764 gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
765 ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
766
767 ctx->ProjectionStackDepth = 0;
768 ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
769 ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
770
771 for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
772 gl_matrix_ctr( &ctx->ProjectionStack[i] );
773 gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
774 }
775
776 /* Texture matrix */
777 for (i=0; i<MAX_TEXTURE_UNITS; i++) {
778 gl_matrix_ctr( &ctx->TextureMatrix[i] );
779 ctx->TextureStackDepth[i] = 0;
780 for (j = 0 ; j < MAX_TEXTURE_STACK_DEPTH ; j++) {
781 ctx->TextureStack[i][j].inv = 0;
782 }
783 }
784
785 /* Accumulate buffer group */
786 ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
787
788 /* Color buffer group */
789 ctx->Color.IndexMask = 0xffffffff;
790 ctx->Color.ColorMask[0] = 0xff;
791 ctx->Color.ColorMask[1] = 0xff;
792 ctx->Color.ColorMask[2] = 0xff;
793 ctx->Color.ColorMask[3] = 0xff;
794 ctx->Color.SWmasking = GL_FALSE;
795 ctx->Color.ClearIndex = 0;
796 ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
797 ctx->Color.DrawBuffer = GL_FRONT;
798 ctx->Color.AlphaEnabled = GL_FALSE;
799 ctx->Color.AlphaFunc = GL_ALWAYS;
800 ctx->Color.AlphaRef = 0;
801 ctx->Color.BlendEnabled = GL_FALSE;
802 ctx->Color.BlendSrcRGB = GL_ONE;
803 ctx->Color.BlendDstRGB = GL_ZERO;
804 ctx->Color.BlendSrcA = GL_ONE;
805 ctx->Color.BlendDstA = GL_ZERO;
806 ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
807 ctx->Color.BlendFunc = NULL; /* this pointer set only when needed */
808 ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
809 ctx->Color.IndexLogicOpEnabled = GL_FALSE;
810 ctx->Color.ColorLogicOpEnabled = GL_FALSE;
811 ctx->Color.SWLogicOpEnabled = GL_FALSE;
812 ctx->Color.LogicOp = GL_COPY;
813 ctx->Color.DitherFlag = GL_TRUE;
814 ctx->Color.MultiDrawBuffer = GL_FALSE;
815
816 /* Current group */
817 ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
818 ctx->Current.Index = 1;
819 for (i=0; i<MAX_TEXTURE_UNITS; i++)
820 ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
821 ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
822 ctx->Current.RasterDistance = 0.0;
823 ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
824 ctx->Current.RasterIndex = 1;
825 for (i=0; i<MAX_TEXTURE_UNITS; i++)
826 ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
827 ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
828 ctx->Current.RasterPosValid = GL_TRUE;
829 ctx->Current.EdgeFlag = GL_TRUE;
830 ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
831 ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
832
833 ctx->Current.Flag = (VERT_NORM|VERT_INDEX|VERT_RGBA|VERT_EDGE|
834 VERT_TEX0_1|VERT_TEX1_1|VERT_MATERIAL);
835
836 init_fallback_arrays( ctx );
837
838 /* Depth buffer group */
839 ctx->Depth.Test = GL_FALSE;
840 ctx->Depth.Clear = 1.0;
841 ctx->Depth.Func = GL_LESS;
842 ctx->Depth.Mask = GL_TRUE;
843
844 /* Evaluators group */
845 ctx->Eval.Map1Color4 = GL_FALSE;
846 ctx->Eval.Map1Index = GL_FALSE;
847 ctx->Eval.Map1Normal = GL_FALSE;
848 ctx->Eval.Map1TextureCoord1 = GL_FALSE;
849 ctx->Eval.Map1TextureCoord2 = GL_FALSE;
850 ctx->Eval.Map1TextureCoord3 = GL_FALSE;
851 ctx->Eval.Map1TextureCoord4 = GL_FALSE;
852 ctx->Eval.Map1Vertex3 = GL_FALSE;
853 ctx->Eval.Map1Vertex4 = GL_FALSE;
854 ctx->Eval.Map2Color4 = GL_FALSE;
855 ctx->Eval.Map2Index = GL_FALSE;
856 ctx->Eval.Map2Normal = GL_FALSE;
857 ctx->Eval.Map2TextureCoord1 = GL_FALSE;
858 ctx->Eval.Map2TextureCoord2 = GL_FALSE;
859 ctx->Eval.Map2TextureCoord3 = GL_FALSE;
860 ctx->Eval.Map2TextureCoord4 = GL_FALSE;
861 ctx->Eval.Map2Vertex3 = GL_FALSE;
862 ctx->Eval.Map2Vertex4 = GL_FALSE;
863 ctx->Eval.AutoNormal = GL_FALSE;
864 ctx->Eval.MapGrid1un = 1;
865 ctx->Eval.MapGrid1u1 = 0.0;
866 ctx->Eval.MapGrid1u2 = 1.0;
867 ctx->Eval.MapGrid2un = 1;
868 ctx->Eval.MapGrid2vn = 1;
869 ctx->Eval.MapGrid2u1 = 0.0;
870 ctx->Eval.MapGrid2u2 = 1.0;
871 ctx->Eval.MapGrid2v1 = 0.0;
872 ctx->Eval.MapGrid2v2 = 1.0;
873
874 /* Evaluator data */
875 {
876 static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
877 static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
878 static GLfloat index[1] = { 1.0 };
879 static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
880 static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
881
882 init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
883 init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
884 init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
885 init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
886 init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
887 init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
888 init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
889 init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
890 init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
891
892 init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
893 init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
894 init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
895 init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
896 init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
897 init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
898 init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
899 init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
900 init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
901 }
902
903 /* Fog group */
904 ctx->Fog.Enabled = GL_FALSE;
905 ctx->Fog.Mode = GL_EXP;
906 ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
907 ctx->Fog.Index = 0.0;
908 ctx->Fog.Density = 1.0;
909 ctx->Fog.Start = 0.0;
910 ctx->Fog.End = 1.0;
911
912 /* Hint group */
913 ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
914 ctx->Hint.PointSmooth = GL_DONT_CARE;
915 ctx->Hint.LineSmooth = GL_DONT_CARE;
916 ctx->Hint.PolygonSmooth = GL_DONT_CARE;
917 ctx->Hint.Fog = GL_DONT_CARE;
918
919 ctx->Hint.AllowDrawWin = GL_TRUE;
920 ctx->Hint.AllowDrawSpn = GL_TRUE;
921 ctx->Hint.AllowDrawMem = GL_TRUE;
922 ctx->Hint.StrictLighting = GL_TRUE;
923
924 /* Pipeline */
925 gl_pipeline_init( ctx );
926 gl_cva_init( ctx );
927
928 /* Extensions */
929 gl_extensions_ctr( ctx );
930
931 ctx->AllowVertexCull = CLIP_CULLED_BIT;
932
933 /* Lighting group */
934 for (i=0;i<MAX_LIGHTS;i++) {
935 init_light( &ctx->Light.Light[i], i );
936 }
937 make_empty_list( &ctx->Light.EnabledList );
938
939 init_lightmodel( &ctx->Light.Model );
940 init_material( &ctx->Light.Material[0] );
941 init_material( &ctx->Light.Material[1] );
942 ctx->Light.ShadeModel = GL_SMOOTH;
943 ctx->Light.Enabled = GL_FALSE;
944 ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
945 ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
946 ctx->Light.ColorMaterialBitmask
947 = gl_material_bitmask( ctx,
948 GL_FRONT_AND_BACK,
949 GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
950
951 ctx->Light.ColorMaterialEnabled = GL_FALSE;
952
953 /* Lighting miscellaneous */
954 ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
955 make_empty_list( ctx->ShineTabList );
956 for (i = 0 ; i < 10 ; i++) {
957 struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
958 s->shininess = -1;
959 s->refcount = 0;
960 insert_at_tail( ctx->ShineTabList, s );
961 }
962 for (i = 0 ; i < 4 ; i++) {
963 ctx->ShineTable[i] = ctx->ShineTabList->prev;
964 ctx->ShineTable[i]->refcount++;
965 }
966
967
968 /* Line group */
969 ctx->Line.SmoothFlag = GL_FALSE;
970 ctx->Line.StippleFlag = GL_FALSE;
971 ctx->Line.Width = 1.0;
972 ctx->Line.StipplePattern = 0xffff;
973 ctx->Line.StippleFactor = 1;
974
975 /* Display List group */
976 ctx->List.ListBase = 0;
977
978 /* Pixel group */
979 ctx->Pixel.RedBias = 0.0;
980 ctx->Pixel.RedScale = 1.0;
981 ctx->Pixel.GreenBias = 0.0;
982 ctx->Pixel.GreenScale = 1.0;
983 ctx->Pixel.BlueBias = 0.0;
984 ctx->Pixel.BlueScale = 1.0;
985 ctx->Pixel.AlphaBias = 0.0;
986 ctx->Pixel.AlphaScale = 1.0;
987 ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
988 ctx->Pixel.DepthBias = 0.0;
989 ctx->Pixel.DepthScale = 1.0;
990 ctx->Pixel.IndexOffset = 0;
991 ctx->Pixel.IndexShift = 0;
992 ctx->Pixel.ZoomX = 1.0;
993 ctx->Pixel.ZoomY = 1.0;
994 ctx->Pixel.MapColorFlag = GL_FALSE;
995 ctx->Pixel.MapStencilFlag = GL_FALSE;
996 ctx->Pixel.MapStoSsize = 1;
997 ctx->Pixel.MapItoIsize = 1;
998 ctx->Pixel.MapItoRsize = 1;
999 ctx->Pixel.MapItoGsize = 1;
1000 ctx->Pixel.MapItoBsize = 1;
1001 ctx->Pixel.MapItoAsize = 1;
1002 ctx->Pixel.MapRtoRsize = 1;
1003 ctx->Pixel.MapGtoGsize = 1;
1004 ctx->Pixel.MapBtoBsize = 1;
1005 ctx->Pixel.MapAtoAsize = 1;
1006 ctx->Pixel.MapStoS[0] = 0;
1007 ctx->Pixel.MapItoI[0] = 0;
1008 ctx->Pixel.MapItoR[0] = 0.0;
1009 ctx->Pixel.MapItoG[0] = 0.0;
1010 ctx->Pixel.MapItoB[0] = 0.0;
1011 ctx->Pixel.MapItoA[0] = 0.0;
1012 ctx->Pixel.MapItoR8[0] = 0;
1013 ctx->Pixel.MapItoG8[0] = 0;
1014 ctx->Pixel.MapItoB8[0] = 0;
1015 ctx->Pixel.MapItoA8[0] = 0;
1016 ctx->Pixel.MapRtoR[0] = 0.0;
1017 ctx->Pixel.MapGtoG[0] = 0.0;
1018 ctx->Pixel.MapBtoB[0] = 0.0;
1019 ctx->Pixel.MapAtoA[0] = 0.0;
1020
1021 /* Point group */
1022 ctx->Point.SmoothFlag = GL_FALSE;
1023 ctx->Point.Size = 1.0;
1024 ctx->Point.Params[0] = 1.0;
1025 ctx->Point.Params[1] = 0.0;
1026 ctx->Point.Params[2] = 0.0;
1027 ctx->Point.Attenuated = GL_FALSE;
1028 ctx->Point.MinSize = 0.0;
1029 ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
1030 ctx->Point.Threshold = 1.0;
1031
1032 /* Polygon group */
1033 ctx->Polygon.CullFlag = GL_FALSE;
1034 ctx->Polygon.CullFaceMode = GL_BACK;
1035 ctx->Polygon.FrontFace = GL_CCW;
1036 ctx->Polygon.FrontBit = 0;
1037 ctx->Polygon.FrontMode = GL_FILL;
1038 ctx->Polygon.BackMode = GL_FILL;
1039 ctx->Polygon.Unfilled = GL_FALSE;
1040 ctx->Polygon.SmoothFlag = GL_FALSE;
1041 ctx->Polygon.StippleFlag = GL_FALSE;
1042 ctx->Polygon.OffsetFactor = 0.0F;
1043 ctx->Polygon.OffsetUnits = 0.0F;
1044 ctx->Polygon.OffsetPoint = GL_FALSE;
1045 ctx->Polygon.OffsetLine = GL_FALSE;
1046 ctx->Polygon.OffsetFill = GL_FALSE;
1047
1048 /* Polygon Stipple group */
1049 MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
1050
1051 /* Scissor group */
1052 ctx->Scissor.Enabled = GL_FALSE;
1053 ctx->Scissor.X = 0;
1054 ctx->Scissor.Y = 0;
1055 ctx->Scissor.Width = 0;
1056 ctx->Scissor.Height = 0;
1057
1058 /* Stencil group */
1059 ctx->Stencil.Enabled = GL_FALSE;
1060 ctx->Stencil.Function = GL_ALWAYS;
1061 ctx->Stencil.FailFunc = GL_KEEP;
1062 ctx->Stencil.ZPassFunc = GL_KEEP;
1063 ctx->Stencil.ZFailFunc = GL_KEEP;
1064 ctx->Stencil.Ref = 0;
1065 ctx->Stencil.ValueMask = STENCIL_MAX;
1066 ctx->Stencil.Clear = 0;
1067 ctx->Stencil.WriteMask = STENCIL_MAX;
1068
1069 /* Texture group */
1070 ctx->Texture.CurrentUnit = 0; /* multitexture */
1071 ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
1072 ctx->Texture.Enabled = 0;
1073 for (i=0; i<MAX_TEXTURE_UNITS; i++)
1074 init_texture_unit( ctx, i );
1075 init_color_table(&ctx->Texture.Palette);
1076
1077 /* Transformation group */
1078 ctx->Transform.MatrixMode = GL_MODELVIEW;
1079 ctx->Transform.Normalize = GL_FALSE;
1080 ctx->Transform.RescaleNormals = GL_FALSE;
1081 for (i=0;i<MAX_CLIP_PLANES;i++) {
1082 ctx->Transform.ClipEnabled[i] = GL_FALSE;
1083 ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
1084 }
1085 ctx->Transform.AnyClip = GL_FALSE;
1086
1087 /* Viewport group */
1088 ctx->Viewport.X = 0;
1089 ctx->Viewport.Y = 0;
1090 ctx->Viewport.Width = 0;
1091 ctx->Viewport.Height = 0;
1092 ctx->Viewport.Near = 0.0;
1093 ctx->Viewport.Far = 1.0;
1094 gl_matrix_ctr(&ctx->Viewport.WindowMap);
1095
1096 #define Sz 10
1097 #define Tz 14
1098 ctx->Viewport.WindowMap.m[Sz] = 0.5 * DEPTH_SCALE;
1099 ctx->Viewport.WindowMap.m[Tz] = 0.5 * DEPTH_SCALE;
1100 #undef Sz
1101 #undef Tz
1102
1103 ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
1104 ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
1105
1106 /* Vertex arrays */
1107 ctx->Array.Vertex.Size = 4;
1108 ctx->Array.Vertex.Type = GL_FLOAT;
1109 ctx->Array.Vertex.Stride = 0;
1110 ctx->Array.Vertex.StrideB = 0;
1111 ctx->Array.Vertex.Ptr = NULL;
1112 ctx->Array.Vertex.Enabled = GL_FALSE;
1113 ctx->Array.Normal.Type = GL_FLOAT;
1114 ctx->Array.Normal.Stride = 0;
1115 ctx->Array.Normal.StrideB = 0;
1116 ctx->Array.Normal.Ptr = NULL;
1117 ctx->Array.Normal.Enabled = GL_FALSE;
1118 ctx->Array.Color.Size = 4;
1119 ctx->Array.Color.Type = GL_FLOAT;
1120 ctx->Array.Color.Stride = 0;
1121 ctx->Array.Color.StrideB = 0;
1122 ctx->Array.Color.Ptr = NULL;
1123 ctx->Array.Color.Enabled = GL_FALSE;
1124 ctx->Array.Index.Type = GL_FLOAT;
1125 ctx->Array.Index.Stride = 0;
1126 ctx->Array.Index.StrideB = 0;
1127 ctx->Array.Index.Ptr = NULL;
1128 ctx->Array.Index.Enabled = GL_FALSE;
1129 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1130 ctx->Array.TexCoord[i].Size = 4;
1131 ctx->Array.TexCoord[i].Type = GL_FLOAT;
1132 ctx->Array.TexCoord[i].Stride = 0;
1133 ctx->Array.TexCoord[i].StrideB = 0;
1134 ctx->Array.TexCoord[i].Ptr = NULL;
1135 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
1136 }
1137 ctx->Array.TexCoordInterleaveFactor = 1;
1138 ctx->Array.EdgeFlag.Stride = 0;
1139 ctx->Array.EdgeFlag.StrideB = 0;
1140 ctx->Array.EdgeFlag.Ptr = NULL;
1141 ctx->Array.EdgeFlag.Enabled = GL_FALSE;
1142 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1143
1144 /* Pixel transfer */
1145 ctx->Pack.Alignment = 4;
1146 ctx->Pack.RowLength = 0;
1147 ctx->Pack.ImageHeight = 0;
1148 ctx->Pack.SkipPixels = 0;
1149 ctx->Pack.SkipRows = 0;
1150 ctx->Pack.SkipImages = 0;
1151 ctx->Pack.SwapBytes = GL_FALSE;
1152 ctx->Pack.LsbFirst = GL_FALSE;
1153 ctx->Unpack.Alignment = 4;
1154 ctx->Unpack.RowLength = 0;
1155 ctx->Unpack.ImageHeight = 0;
1156 ctx->Unpack.SkipPixels = 0;
1157 ctx->Unpack.SkipRows = 0;
1158 ctx->Unpack.SkipImages = 0;
1159 ctx->Unpack.SwapBytes = GL_FALSE;
1160 ctx->Unpack.LsbFirst = GL_FALSE;
1161
1162 /* Feedback */
1163 ctx->Feedback.Type = GL_2D; /* TODO: verify */
1164 ctx->Feedback.Buffer = NULL;
1165 ctx->Feedback.BufferSize = 0;
1166 ctx->Feedback.Count = 0;
1167
1168 /* Selection/picking */
1169 ctx->Select.Buffer = NULL;
1170 ctx->Select.BufferSize = 0;
1171 ctx->Select.BufferCount = 0;
1172 ctx->Select.Hits = 0;
1173 ctx->Select.NameStackDepth = 0;
1174
1175 /* Optimized Accum buffer */
1176 ctx->IntegerAccumMode = GL_TRUE;
1177 ctx->IntegerAccumScaler = 0.0;
1178
1179 /* Renderer and client attribute stacks */
1180 ctx->AttribStackDepth = 0;
1181 ctx->ClientAttribStackDepth = 0;
1182
1183 /* Miscellaneous */
1184 ctx->NewState = NEW_ALL;
1185 ctx->RenderMode = GL_RENDER;
1186 ctx->StippleCounter = 0;
1187 ctx->NeedNormals = GL_FALSE;
1188 ctx->DoViewportMapping = GL_TRUE;
1189
1190 ctx->NeedEyeCoords = GL_FALSE;
1191 ctx->NeedEyeNormals = GL_FALSE;
1192 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
1193
1194 /* Display list */
1195 ctx->CallDepth = 0;
1196 ctx->ExecuteFlag = GL_TRUE;
1197 ctx->CompileFlag = GL_FALSE;
1198 ctx->CurrentListPtr = NULL;
1199 ctx->CurrentBlock = NULL;
1200 ctx->CurrentListNum = 0;
1201 ctx->CurrentPos = 0;
1202
1203 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1204
1205 ctx->CatchSignals = GL_TRUE;
1206
1207 /* For debug/development only */
1208 ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
1209 ctx->FirstTimeCurrent = GL_TRUE;
1210
1211 /* Dither disable */
1212 ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
1213 if (ctx->NoDither) {
1214 if (getenv("MESA_DEBUG")) {
1215 fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
1216 }
1217 ctx->Color.DitherFlag = GL_FALSE;
1218 }
1219 }
1220
1221
1222
1223
1224 /*
1225 * Allocate the proxy textures. If we run out of memory part way through
1226 * the allocations clean up and return GL_FALSE.
1227 * Return: GL_TRUE=success, GL_FALSE=failure
1228 */
1229 static GLboolean alloc_proxy_textures( GLcontext *ctx )
1230 {
1231 GLboolean out_of_memory;
1232 GLint i;
1233
1234 ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
1235 if (!ctx->Texture.Proxy1D) {
1236 return GL_FALSE;
1237 }
1238
1239 ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
1240 if (!ctx->Texture.Proxy2D) {
1241 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1242 return GL_FALSE;
1243 }
1244
1245 ctx->Texture.Proxy3D = gl_alloc_texture_object(NULL, 0, 3);
1246 if (!ctx->Texture.Proxy3D) {
1247 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1248 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1249 return GL_FALSE;
1250 }
1251
1252 out_of_memory = GL_FALSE;
1253 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1254 ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
1255 ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
1256 ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
1257 if (!ctx->Texture.Proxy1D->Image[i]
1258 || !ctx->Texture.Proxy2D->Image[i]
1259 || !ctx->Texture.Proxy3D->Image[i]) {
1260 out_of_memory = GL_TRUE;
1261 }
1262 }
1263 if (out_of_memory) {
1264 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1265 if (ctx->Texture.Proxy1D->Image[i]) {
1266 gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
1267 }
1268 if (ctx->Texture.Proxy2D->Image[i]) {
1269 gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
1270 }
1271 if (ctx->Texture.Proxy3D->Image[i]) {
1272 gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
1273 }
1274 }
1275 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1276 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1277 gl_free_texture_object(NULL, ctx->Texture.Proxy3D);
1278 return GL_FALSE;
1279 }
1280 else {
1281 return GL_TRUE;
1282 }
1283 }
1284
1285
1286
1287 /*
1288 * Initialize a GLcontext struct.
1289 */
1290 GLboolean gl_initialize_context_data( GLcontext *ctx,
1291 GLvisual *visual,
1292 GLcontext *share_list,
1293 void *driver_ctx,
1294 GLboolean direct )
1295 {
1296 (void) direct; /* not used */
1297
1298 /* misc one-time initializations */
1299 one_time_init();
1300
1301 ctx->DriverCtx = driver_ctx;
1302 ctx->Visual = visual;
1303 ctx->DrawBuffer = NULL;
1304 ctx->ReadBuffer = NULL;
1305
1306 ctx->VB = gl_vb_create_for_immediate( ctx );
1307 if (!ctx->VB) {
1308 FREE( ctx );
1309 return GL_FALSE;
1310 }
1311 ctx->input = ctx->VB->IM;
1312
1313 ctx->PB = gl_alloc_pb();
1314 if (!ctx->PB) {
1315 FREE( ctx->VB );
1316 FREE( ctx );
1317 return GL_FALSE;
1318 }
1319
1320 if (share_list) {
1321 /* share the group of display lists of another context */
1322 ctx->Shared = share_list->Shared;
1323 }
1324 else {
1325 /* allocate new group of display lists */
1326 ctx->Shared = alloc_shared_state();
1327 if (!ctx->Shared) {
1328 FREE(ctx->VB);
1329 FREE(ctx->PB);
1330 FREE(ctx);
1331 return GL_FALSE;
1332 }
1333 }
1334 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1335 ctx->Shared->RefCount++;
1336 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1337
1338 init_attrib_groups( ctx );
1339
1340 gl_reset_vb( ctx->VB );
1341 gl_reset_input( ctx );
1342
1343 if (visual->DBflag) {
1344 ctx->Color.DrawBuffer = GL_BACK;
1345 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1346 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1347 ctx->Pixel.ReadBuffer = GL_BACK;
1348 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1349 }
1350 else {
1351 ctx->Color.DrawBuffer = GL_FRONT;
1352 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1353 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1354 ctx->Pixel.ReadBuffer = GL_FRONT;
1355 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1356 }
1357
1358 #ifdef PROFILE
1359 init_timings( ctx );
1360 #endif
1361
1362 if (!alloc_proxy_textures(ctx)) {
1363 free_shared_state(ctx, ctx->Shared);
1364 FREE(ctx->VB);
1365 FREE(ctx->PB);
1366 FREE(ctx);
1367 return GL_FALSE;
1368 }
1369
1370 /* setup API dispatch tables */
1371 _mesa_init_exec_table( &ctx->Exec );
1372 _mesa_init_dlist_table( &ctx->Save );
1373 ctx->CurrentDispatch = &ctx->Exec;
1374
1375 return GL_TRUE;
1376 }
1377
1378
1379
1380 /*
1381 * Allocate and initialize a GLcontext structure.
1382 * Input: visual - a GLvisual pointer
1383 * sharelist - another context to share display lists with or NULL
1384 * driver_ctx - pointer to device driver's context state struct
1385 * Return: pointer to a new gl_context struct or NULL if error.
1386 */
1387 GLcontext *gl_create_context( GLvisual *visual,
1388 GLcontext *share_list,
1389 void *driver_ctx,
1390 GLboolean direct )
1391 {
1392 GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
1393 if (!ctx) {
1394 return NULL;
1395 }
1396
1397 if (gl_initialize_context_data(ctx, visual, share_list,
1398 driver_ctx, direct)) {
1399 return ctx;
1400 }
1401 else {
1402 FREE(ctx);
1403 return NULL;
1404 }
1405 }
1406
1407
1408
1409 /*
1410 * Free the data associated with the given context.
1411 * But don't free() the GLcontext struct itself!
1412 */
1413 void gl_free_context_data( GLcontext *ctx )
1414 {
1415 GLuint i;
1416 struct gl_shine_tab *s, *tmps;
1417
1418 /* if we're destroying the current context, unbind it first */
1419 if (ctx == gl_get_current_context()) {
1420 gl_make_current(NULL, NULL);
1421 }
1422
1423 #ifdef PROFILE
1424 if (getenv("MESA_PROFILE")) {
1425 print_timings( ctx );
1426 }
1427 #endif
1428
1429 gl_matrix_dtr( &ctx->ModelView );
1430 for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
1431 gl_matrix_dtr( &ctx->ModelViewStack[i] );
1432 }
1433 gl_matrix_dtr( &ctx->ProjectionMatrix );
1434 for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
1435 gl_matrix_dtr( &ctx->ProjectionStack[i] );
1436 }
1437
1438 FREE( ctx->PB );
1439
1440 if(ctx->input != ctx->VB->IM)
1441 gl_immediate_free( ctx->input );
1442
1443 gl_vb_free( ctx->VB );
1444
1445 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1446 ctx->Shared->RefCount--;
1447 assert(ctx->Shared->RefCount >= 0);
1448 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1449 if (ctx->Shared->RefCount == 0) {
1450 /* free shared state */
1451 free_shared_state( ctx, ctx->Shared );
1452 }
1453
1454 foreach_s( s, tmps, ctx->ShineTabList ) {
1455 FREE( s );
1456 }
1457 FREE( ctx->ShineTabList );
1458
1459 /* Free proxy texture objects */
1460 gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1461 gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1462 gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1463
1464 /* Free evaluator data */
1465 if (ctx->EvalMap.Map1Vertex3.Points)
1466 FREE( ctx->EvalMap.Map1Vertex3.Points );
1467 if (ctx->EvalMap.Map1Vertex4.Points)
1468 FREE( ctx->EvalMap.Map1Vertex4.Points );
1469 if (ctx->EvalMap.Map1Index.Points)
1470 FREE( ctx->EvalMap.Map1Index.Points );
1471 if (ctx->EvalMap.Map1Color4.Points)
1472 FREE( ctx->EvalMap.Map1Color4.Points );
1473 if (ctx->EvalMap.Map1Normal.Points)
1474 FREE( ctx->EvalMap.Map1Normal.Points );
1475 if (ctx->EvalMap.Map1Texture1.Points)
1476 FREE( ctx->EvalMap.Map1Texture1.Points );
1477 if (ctx->EvalMap.Map1Texture2.Points)
1478 FREE( ctx->EvalMap.Map1Texture2.Points );
1479 if (ctx->EvalMap.Map1Texture3.Points)
1480 FREE( ctx->EvalMap.Map1Texture3.Points );
1481 if (ctx->EvalMap.Map1Texture4.Points)
1482 FREE( ctx->EvalMap.Map1Texture4.Points );
1483
1484 if (ctx->EvalMap.Map2Vertex3.Points)
1485 FREE( ctx->EvalMap.Map2Vertex3.Points );
1486 if (ctx->EvalMap.Map2Vertex4.Points)
1487 FREE( ctx->EvalMap.Map2Vertex4.Points );
1488 if (ctx->EvalMap.Map2Index.Points)
1489 FREE( ctx->EvalMap.Map2Index.Points );
1490 if (ctx->EvalMap.Map2Color4.Points)
1491 FREE( ctx->EvalMap.Map2Color4.Points );
1492 if (ctx->EvalMap.Map2Normal.Points)
1493 FREE( ctx->EvalMap.Map2Normal.Points );
1494 if (ctx->EvalMap.Map2Texture1.Points)
1495 FREE( ctx->EvalMap.Map2Texture1.Points );
1496 if (ctx->EvalMap.Map2Texture2.Points)
1497 FREE( ctx->EvalMap.Map2Texture2.Points );
1498 if (ctx->EvalMap.Map2Texture3.Points)
1499 FREE( ctx->EvalMap.Map2Texture3.Points );
1500 if (ctx->EvalMap.Map2Texture4.Points)
1501 FREE( ctx->EvalMap.Map2Texture4.Points );
1502
1503 /* Free cache of immediate buffers. */
1504 while (ctx->nr_im_queued-- > 0) {
1505 struct immediate * next = ctx->freed_im_queue->next;
1506 FREE( ctx->freed_im_queue );
1507 ctx->freed_im_queue = next;
1508 }
1509 gl_extensions_dtr(ctx);
1510 }
1511
1512
1513
1514 /*
1515 * Destroy a GLcontext structure.
1516 */
1517 void gl_destroy_context( GLcontext *ctx )
1518 {
1519 if (ctx) {
1520 gl_free_context_data(ctx);
1521 FREE( (void *) ctx );
1522 }
1523 }
1524
1525
1526
1527 /*
1528 * Called by the driver after both the context and driver are fully
1529 * initialized. Currently just reads the config file.
1530 */
1531 void gl_context_initialize( GLcontext *ctx )
1532 {
1533 gl_read_config_file( ctx );
1534 }
1535
1536
1537
1538 /*
1539 * Copy attribute groups from one context to another.
1540 * Input: src - source context
1541 * dst - destination context
1542 * mask - bitwise OR of GL_*_BIT flags
1543 */
1544 void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1545 {
1546 if (mask & GL_ACCUM_BUFFER_BIT) {
1547 MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1548 }
1549 if (mask & GL_COLOR_BUFFER_BIT) {
1550 MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1551 }
1552 if (mask & GL_CURRENT_BIT) {
1553 MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1554 }
1555 if (mask & GL_DEPTH_BUFFER_BIT) {
1556 MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1557 }
1558 if (mask & GL_ENABLE_BIT) {
1559 /* no op */
1560 }
1561 if (mask & GL_EVAL_BIT) {
1562 MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1563 }
1564 if (mask & GL_FOG_BIT) {
1565 MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1566 }
1567 if (mask & GL_HINT_BIT) {
1568 MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1569 }
1570 if (mask & GL_LIGHTING_BIT) {
1571 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1572 /* gl_reinit_light_attrib( &dst->Light ); */
1573 }
1574 if (mask & GL_LINE_BIT) {
1575 MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1576 }
1577 if (mask & GL_LIST_BIT) {
1578 MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1579 }
1580 if (mask & GL_PIXEL_MODE_BIT) {
1581 MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1582 }
1583 if (mask & GL_POINT_BIT) {
1584 MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1585 }
1586 if (mask & GL_POLYGON_BIT) {
1587 MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1588 }
1589 if (mask & GL_POLYGON_STIPPLE_BIT) {
1590 /* Use loop instead of MEMCPY due to problem with Portland Group's
1591 * C compiler. Reported by John Stone.
1592 */
1593 int i;
1594 for (i=0;i<32;i++) {
1595 dst->PolygonStipple[i] = src->PolygonStipple[i];
1596 }
1597 }
1598 if (mask & GL_SCISSOR_BIT) {
1599 MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1600 }
1601 if (mask & GL_STENCIL_BUFFER_BIT) {
1602 MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1603 }
1604 if (mask & GL_TEXTURE_BIT) {
1605 MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1606 }
1607 if (mask & GL_TRANSFORM_BIT) {
1608 MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1609 }
1610 if (mask & GL_VIEWPORT_BIT) {
1611 MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1612 }
1613 }
1614
1615
1616 /*
1617 * Set the current context, binding the given frame buffer to the context.
1618 */
1619 void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1620 {
1621 gl_make_current2( newCtx, buffer, buffer );
1622 }
1623
1624
1625 /*
1626 * Bind the given context to the given draw-buffer and read-buffer
1627 * and make it the current context for this thread.
1628 */
1629 void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1630 GLframebuffer *readBuffer )
1631 {
1632 #if 0
1633 GLcontext *oldCtx = gl_get_context();
1634
1635 /* Flush the old context
1636 */
1637 if (oldCtx) {
1638 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
1639
1640 /* unbind frame buffers from context */
1641 if (oldCtx->DrawBuffer) {
1642 oldCtx->DrawBuffer = NULL;
1643 }
1644 if (oldCtx->ReadBuffer) {
1645 oldCtx->ReadBuffer = NULL;
1646 }
1647 }
1648 #endif
1649
1650 /* We call this function periodically (just here for now) in
1651 * order to detect when multithreading has begun.
1652 */
1653 _glapi_check_multithread();
1654
1655 _glapi_set_context((void *) newCtx);
1656 ASSERT(gl_get_current_context() == newCtx);
1657 if (newCtx) {
1658 SET_IMMEDIATE(newCtx, newCtx->input);
1659 _glapi_set_dispatch(newCtx->CurrentDispatch);
1660 }
1661 else {
1662 _glapi_set_dispatch(NULL); /* none current */
1663 }
1664
1665 if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1666
1667 if (newCtx && drawBuffer && readBuffer) {
1668 /* TODO: check if newCtx and buffer's visual match??? */
1669 newCtx->DrawBuffer = drawBuffer;
1670 newCtx->ReadBuffer = readBuffer;
1671 newCtx->NewState = NEW_ALL; /* just to be safe */
1672 gl_update_state( newCtx );
1673 }
1674
1675 /* We can use this to help debug user's problems. Tell the to set
1676 * the MESA_INFO env variable before running their app. Then the
1677 * first time each context is made current we'll print some useful
1678 * information.
1679 */
1680 if (newCtx && newCtx->FirstTimeCurrent) {
1681 if (getenv("MESA_INFO")) {
1682 fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
1683 fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
1684 fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
1685 fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
1686 #if defined(THREADS)
1687 fprintf(stderr, "Mesa thread-safe: YES\n");
1688 #else
1689 fprintf(stderr, "Mesa thread-safe: NO\n");
1690 #endif
1691 #if defined(USE_X86_ASM)
1692 fprintf(stderr, "Mesa x86-optimized: YES\n");
1693 #else
1694 fprintf(stderr, "Mesa x86-optimized: NO\n");
1695 #endif
1696 }
1697 newCtx->FirstTimeCurrent = GL_FALSE;
1698 }
1699 }
1700
1701
1702
1703 /*
1704 * Return current context handle for the calling thread.
1705 * This isn't the fastest way to get the current context.
1706 * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
1707 */
1708 GLcontext *gl_get_current_context( void )
1709 {
1710 return (GLcontext *) _glapi_get_context();
1711 }
1712
1713
1714
1715 /*
1716 * This should be called by device drivers just before they do a
1717 * swapbuffers. Any pending rendering commands will be executed.
1718 */
1719 void
1720 _mesa_swapbuffers(GLcontext *ctx)
1721 {
1722 FLUSH_VB( ctx, "swap buffers" );
1723 }
1724
1725
1726
1727 /*
1728 * Return pointer to this context's current API dispatch table.
1729 * It'll either be the immediate-mode execute dispatcher or the
1730 * display list compile dispatcher.
1731 */
1732 struct _glapi_table *
1733 _mesa_get_dispatch(GLcontext *ctx)
1734 {
1735 return ctx->CurrentDispatch;
1736 }
1737
1738
1739
1740 void
1741 _mesa_ResizeBuffersMESA( void )
1742 {
1743 GLcontext *ctx = gl_get_current_context();
1744
1745 GLuint buf_width, buf_height;
1746
1747 if (MESA_VERBOSE & VERBOSE_API)
1748 fprintf(stderr, "glResizeBuffersMESA\n");
1749
1750 /* ask device driver for size of output buffer */
1751 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1752
1753 /* see if size of device driver's color buffer (window) has changed */
1754 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1755 ctx->DrawBuffer->Height == (GLint) buf_height)
1756 return;
1757
1758 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1759
1760 /* save buffer size */
1761 ctx->DrawBuffer->Width = buf_width;
1762 ctx->DrawBuffer->Height = buf_height;
1763
1764 /* Reallocate other buffers if needed. */
1765 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1766 gl_alloc_depth_buffer( ctx );
1767 }
1768 if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
1769 gl_alloc_stencil_buffer( ctx );
1770 }
1771 if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
1772 gl_alloc_accum_buffer( ctx );
1773 }
1774 if (ctx->Visual->SoftwareAlpha) {
1775 gl_alloc_alpha_buffers( ctx );
1776 }
1777 }
1778
1779
1780
1781 /**********************************************************************/
1782 /***** Miscellaneous functions *****/
1783 /**********************************************************************/
1784
1785
1786 /*
1787 * This function is called when the Mesa user has stumbled into a code
1788 * path which may not be implemented fully or correctly.
1789 */
1790 void gl_problem( const GLcontext *ctx, const char *s )
1791 {
1792 fprintf( stderr, "Mesa implementation error: %s\n", s );
1793 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1794 (void) ctx;
1795 }
1796
1797
1798
1799 /*
1800 * This is called to inform the user that he or she has tried to do
1801 * something illogical or if there's likely a bug in their program
1802 * (like enabled depth testing without a depth buffer).
1803 */
1804 void gl_warning( const GLcontext *ctx, const char *s )
1805 {
1806 GLboolean debug;
1807 #ifdef DEBUG
1808 debug = GL_TRUE;
1809 #else
1810 if (getenv("MESA_DEBUG")) {
1811 debug = GL_TRUE;
1812 }
1813 else {
1814 debug = GL_FALSE;
1815 }
1816 #endif
1817 if (debug) {
1818 fprintf( stderr, "Mesa warning: %s\n", s );
1819 }
1820 (void) ctx;
1821 }
1822
1823
1824
1825 void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1826 {
1827 if (ctx->CompileFlag)
1828 gl_save_error( ctx, error, s );
1829
1830 if (ctx->ExecuteFlag)
1831 gl_error( ctx, error, s );
1832 }
1833
1834
1835 /*
1836 * This is Mesa's error handler. Normally, all that's done is the updating
1837 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1838 * environment variable "MESA_DEBUG" is defined then a real error message
1839 * is printed to stderr.
1840 * Input: error - the error value
1841 * s - a diagnostic string
1842 */
1843 void gl_error( GLcontext *ctx, GLenum error, const char *s )
1844 {
1845 GLboolean debug;
1846
1847 #ifdef DEBUG
1848 debug = GL_TRUE;
1849 #else
1850 if (getenv("MESA_DEBUG")) {
1851 debug = GL_TRUE;
1852 }
1853 else {
1854 debug = GL_FALSE;
1855 }
1856 #endif
1857
1858 if (debug) {
1859 char errstr[1000];
1860
1861 switch (error) {
1862 case GL_NO_ERROR:
1863 strcpy( errstr, "GL_NO_ERROR" );
1864 break;
1865 case GL_INVALID_VALUE:
1866 strcpy( errstr, "GL_INVALID_VALUE" );
1867 break;
1868 case GL_INVALID_ENUM:
1869 strcpy( errstr, "GL_INVALID_ENUM" );
1870 break;
1871 case GL_INVALID_OPERATION:
1872 strcpy( errstr, "GL_INVALID_OPERATION" );
1873 break;
1874 case GL_STACK_OVERFLOW:
1875 strcpy( errstr, "GL_STACK_OVERFLOW" );
1876 break;
1877 case GL_STACK_UNDERFLOW:
1878 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1879 break;
1880 case GL_OUT_OF_MEMORY:
1881 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1882 break;
1883 default:
1884 strcpy( errstr, "unknown" );
1885 break;
1886 }
1887 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1888 }
1889
1890 if (ctx->ErrorValue==GL_NO_ERROR) {
1891 ctx->ErrorValue = error;
1892 }
1893
1894 /* Call device driver's error handler, if any. This is used on the Mac. */
1895 if (ctx->Driver.Error) {
1896 (*ctx->Driver.Error)( ctx );
1897 }
1898 }
1899
1900
1901
1902 /**********************************************************************/
1903 /***** State update logic *****/
1904 /**********************************************************************/
1905
1906
1907 /*
1908 * Since the device driver may or may not support pixel logic ops we
1909 * have to make some extensive tests to determine whether or not
1910 * software-implemented logic operations have to be used.
1911 */
1912 static void update_pixel_logic( GLcontext *ctx )
1913 {
1914 if (ctx->Visual->RGBAflag) {
1915 /* RGBA mode blending w/ Logic Op */
1916 if (ctx->Color.ColorLogicOpEnabled) {
1917 if (ctx->Driver.LogicOp
1918 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1919 /* Device driver can do logic, don't have to do it in software */
1920 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1921 }
1922 else {
1923 /* Device driver can't do logic op so we do it in software */
1924 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1925 }
1926 }
1927 else {
1928 /* no logic op */
1929 if (ctx->Driver.LogicOp) {
1930 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1931 }
1932 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1933 }
1934 }
1935 else {
1936 /* CI mode Logic Op */
1937 if (ctx->Color.IndexLogicOpEnabled) {
1938 if (ctx->Driver.LogicOp
1939 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1940 /* Device driver can do logic, don't have to do it in software */
1941 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1942 }
1943 else {
1944 /* Device driver can't do logic op so we do it in software */
1945 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1946 }
1947 }
1948 else {
1949 /* no logic op */
1950 if (ctx->Driver.LogicOp) {
1951 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1952 }
1953 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1954 }
1955 }
1956 }
1957
1958
1959
1960 /*
1961 * Check if software implemented RGBA or Color Index masking is needed.
1962 */
1963 static void update_pixel_masking( GLcontext *ctx )
1964 {
1965 if (ctx->Visual->RGBAflag) {
1966 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1967 if (*colorMask == 0xffffffff) {
1968 /* disable masking */
1969 if (ctx->Driver.ColorMask) {
1970 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1971 }
1972 ctx->Color.SWmasking = GL_FALSE;
1973 }
1974 else {
1975 /* Ask driver to do color masking, if it can't then
1976 * do it in software
1977 */
1978 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1979 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1980 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1981 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1982 if (ctx->Driver.ColorMask
1983 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1984 ctx->Color.SWmasking = GL_FALSE;
1985 }
1986 else {
1987 ctx->Color.SWmasking = GL_TRUE;
1988 }
1989 }
1990 }
1991 else {
1992 if (ctx->Color.IndexMask==0xffffffff) {
1993 /* disable masking */
1994 if (ctx->Driver.IndexMask) {
1995 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1996 }
1997 ctx->Color.SWmasking = GL_FALSE;
1998 }
1999 else {
2000 /* Ask driver to do index masking, if it can't then
2001 * do it in software
2002 */
2003 if (ctx->Driver.IndexMask
2004 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
2005 ctx->Color.SWmasking = GL_FALSE;
2006 }
2007 else {
2008 ctx->Color.SWmasking = GL_TRUE;
2009 }
2010 }
2011 }
2012 }
2013
2014
2015 static void update_fog_mode( GLcontext *ctx )
2016 {
2017 int old_mode = ctx->FogMode;
2018
2019 if (ctx->Fog.Enabled) {
2020 if (ctx->Texture.Enabled)
2021 ctx->FogMode = FOG_FRAGMENT;
2022 else if (ctx->Hint.Fog == GL_NICEST)
2023 ctx->FogMode = FOG_FRAGMENT;
2024 else
2025 ctx->FogMode = FOG_VERTEX;
2026
2027 if (ctx->Driver.GetParameteri)
2028 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
2029 ctx->FogMode = FOG_FRAGMENT;
2030 }
2031 else {
2032 ctx->FogMode = FOG_NONE;
2033 }
2034
2035 if (old_mode != ctx->FogMode)
2036 ctx->NewState |= NEW_FOG;
2037 }
2038
2039
2040 /*
2041 * Recompute the value of ctx->RasterMask, etc. according to
2042 * the current context.
2043 */
2044 static void update_rasterflags( GLcontext *ctx )
2045 {
2046 ctx->RasterMask = 0;
2047
2048 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
2049 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
2050 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
2051 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
2052 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
2053 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
2054 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
2055 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
2056
2057 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
2058 && ctx->Color.DrawBuffer != GL_NONE)
2059 ctx->RasterMask |= ALPHABUF_BIT;
2060
2061 if ( ctx->Viewport.X<0
2062 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
2063 || ctx->Viewport.Y<0
2064 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
2065 ctx->RasterMask |= WINCLIP_BIT;
2066 }
2067
2068 /* If we're not drawing to exactly one color buffer set the
2069 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
2070 * buffers or the RGBA or CI mask disables all writes.
2071 */
2072
2073 ctx->TriangleCaps &= ~DD_MULTIDRAW;
2074
2075 if (ctx->Color.MultiDrawBuffer) {
2076 ctx->RasterMask |= MULTI_DRAW_BIT;
2077 ctx->TriangleCaps |= DD_MULTIDRAW;
2078 }
2079 else if (ctx->Color.DrawBuffer==GL_NONE) {
2080 ctx->RasterMask |= MULTI_DRAW_BIT;
2081 ctx->TriangleCaps |= DD_MULTIDRAW;
2082 }
2083 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2084 /* all RGBA channels disabled */
2085 ctx->RasterMask |= MULTI_DRAW_BIT;
2086 ctx->TriangleCaps |= DD_MULTIDRAW;
2087 ctx->Color.DrawDestMask = 0;
2088 }
2089 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2090 /* all color index bits disabled */
2091 ctx->RasterMask |= MULTI_DRAW_BIT;
2092 ctx->TriangleCaps |= DD_MULTIDRAW;
2093 ctx->Color.DrawDestMask = 0;
2094 }
2095 }
2096
2097
2098 void gl_print_state( const char *msg, GLuint state )
2099 {
2100 fprintf(stderr,
2101 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2102 msg,
2103 state,
2104 (state & NEW_LIGHTING) ? "lighting, " : "",
2105 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2106 (state & NEW_TEXTURING) ? "texturing, " : "",
2107 (state & NEW_POLYGON) ? "polygon, " : "",
2108 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2109 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2110 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2111 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2112 (state & NEW_MODELVIEW) ? "modelview, " : "",
2113 (state & NEW_PROJECTION) ? "projection, " : "",
2114 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2115 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2116 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2117 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2118 (state & NEW_FOG) ? "fog, " : "",
2119 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2120 (state & NEW_VIEWPORT) ? "viewport, " : "",
2121 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2122 }
2123
2124 void gl_print_enable_flags( const char *msg, GLuint flags )
2125 {
2126 fprintf(stderr,
2127 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2128 msg,
2129 flags,
2130 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2131 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2132 (flags & ENABLE_LIGHT) ? "light, " : "",
2133 (flags & ENABLE_FOG) ? "fog, " : "",
2134 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2135 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2136 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2137 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2138 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2139 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2140 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2141 }
2142
2143
2144 /*
2145 * If ctx->NewState is non-zero then this function MUST be called before
2146 * rendering any primitive. Basically, function pointers and miscellaneous
2147 * flags are updated to reflect the current state of the state machine.
2148 */
2149 void gl_update_state( GLcontext *ctx )
2150 {
2151 GLuint i;
2152
2153 if (MESA_VERBOSE & VERBOSE_STATE)
2154 gl_print_state("", ctx->NewState);
2155
2156 if (ctx->NewState & NEW_CLIENT_STATE)
2157 gl_update_client_state( ctx );
2158
2159 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2160 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2161 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2162
2163 if (ctx->NewState & NEW_TEXTURE_ENV) {
2164 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2165 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2166 ctx->NewState &= ~NEW_TEXTURE_ENV;
2167 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2168 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2169 }
2170
2171 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2172 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2173
2174 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2175 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2176 {
2177 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2178 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2179
2180 if (ctx->Texture.Unit[i].Enabled &&
2181 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2182 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2183 }
2184 }
2185 }
2186
2187 if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
2188 ctx->Texture.NeedNormals = GL_FALSE;
2189 gl_update_dirty_texobjs(ctx);
2190 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2191 ctx->Texture.ReallyEnabled = 0;
2192
2193 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2194 if (ctx->Texture.Unit[i].Enabled) {
2195 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2196
2197 ctx->Texture.ReallyEnabled |=
2198 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2199
2200 if (ctx->Texture.Unit[i].GenFlags != 0) {
2201 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2202
2203 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2204 {
2205 ctx->Texture.NeedNormals = GL_TRUE;
2206 ctx->Texture.NeedEyeCoords = GL_TRUE;
2207 }
2208
2209 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2210 {
2211 ctx->Texture.NeedEyeCoords = GL_TRUE;
2212 }
2213 }
2214 }
2215 }
2216
2217 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2218 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2219 }
2220
2221 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2222
2223
2224 if (ctx->NewState & NEW_RASTER_OPS) {
2225 update_pixel_logic(ctx);
2226 update_pixel_masking(ctx);
2227 update_fog_mode(ctx);
2228 update_rasterflags(ctx);
2229 if (ctx->Driver.Dither) {
2230 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2231 }
2232
2233 /* Check if incoming colors can be modified during rasterization */
2234 if (ctx->Fog.Enabled ||
2235 ctx->Texture.Enabled ||
2236 ctx->Color.BlendEnabled ||
2237 ctx->Color.SWmasking ||
2238 ctx->Color.SWLogicOpEnabled) {
2239 ctx->MutablePixels = GL_TRUE;
2240 }
2241 else {
2242 ctx->MutablePixels = GL_FALSE;
2243 }
2244
2245 /* update scissor region */
2246
2247 ctx->DrawBuffer->Xmin = 0;
2248 ctx->DrawBuffer->Ymin = 0;
2249 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2250 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
2251 if (ctx->Scissor.Enabled) {
2252 if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2253 ctx->DrawBuffer->Xmin = ctx->Scissor.X;
2254 }
2255 if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2256 ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
2257 }
2258 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2259 ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2260 }
2261 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2262 ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2263 }
2264 }
2265 }
2266
2267 if (ctx->NewState & NEW_LIGHTING) {
2268 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2269 if (ctx->Light.Enabled) {
2270 if (ctx->Light.Model.TwoSide)
2271 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2272 gl_update_lighting(ctx);
2273 }
2274 }
2275 }
2276
2277 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2278
2279 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
2280
2281 if (ctx->NewState & NEW_POLYGON) {
2282 /* Setup CullBits bitmask */
2283 if (ctx->Polygon.CullFlag) {
2284 ctx->backface_sign = 1;
2285 switch(ctx->Polygon.CullFaceMode) {
2286 case GL_BACK:
2287 if(ctx->Polygon.FrontFace==GL_CCW)
2288 ctx->backface_sign = -1;
2289 ctx->Polygon.CullBits = 1;
2290 break;
2291 case GL_FRONT:
2292 if(ctx->Polygon.FrontFace!=GL_CCW)
2293 ctx->backface_sign = -1;
2294 ctx->Polygon.CullBits = 2;
2295 break;
2296 default:
2297 case GL_FRONT_AND_BACK:
2298 ctx->backface_sign = 0;
2299 ctx->Polygon.CullBits = 0;
2300 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
2301 break;
2302 }
2303 }
2304 else {
2305 ctx->Polygon.CullBits = 3;
2306 ctx->backface_sign = 0;
2307 }
2308
2309 /* Any Polygon offsets enabled? */
2310 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2311
2312 if (ctx->Polygon.OffsetPoint ||
2313 ctx->Polygon.OffsetLine ||
2314 ctx->Polygon.OffsetFill)
2315 ctx->TriangleCaps |= DD_TRI_OFFSET;
2316
2317 /* reset Z offsets now */
2318 ctx->PointZoffset = 0.0;
2319 ctx->LineZoffset = 0.0;
2320 ctx->PolygonZoffset = 0.0;
2321 }
2322 }
2323
2324 if (ctx->NewState & ~(NEW_CLIENT_STATE|
2325 NEW_DRIVER_STATE|NEW_USER_CLIP|
2326 NEW_POLYGON))
2327 gl_update_clipmask(ctx);
2328
2329 if (ctx->NewState & (NEW_LIGHTING|
2330 NEW_RASTER_OPS|
2331 NEW_TEXTURING|
2332 NEW_TEXTURE_ENABLE|
2333 NEW_TEXTURE_ENV|
2334 NEW_POLYGON|
2335 NEW_DRVSTATE0|
2336 NEW_DRVSTATE1|
2337 NEW_DRVSTATE2|
2338 NEW_DRVSTATE3|
2339 NEW_USER_CLIP))
2340 {
2341 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2342 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2343
2344 if (MESA_VERBOSE&VERBOSE_CULL)
2345 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2346
2347 ctx->Driver.PointsFunc = NULL;
2348 ctx->Driver.LineFunc = NULL;
2349 ctx->Driver.TriangleFunc = NULL;
2350 ctx->Driver.QuadFunc = NULL;
2351 ctx->Driver.RectFunc = NULL;
2352 ctx->Driver.RenderVBClippedTab = NULL;
2353 ctx->Driver.RenderVBCulledTab = NULL;
2354 ctx->Driver.RenderVBRawTab = NULL;
2355
2356 /*
2357 * Here the driver sets up all the ctx->Driver function pointers to
2358 * it's specific, private functions.
2359 */
2360 ctx->Driver.UpdateState(ctx);
2361
2362 if (MESA_VERBOSE&VERBOSE_CULL)
2363 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2364
2365 /*
2366 * In case the driver didn't hook in an optimized point, line or
2367 * triangle function we'll now select "core/fallback" point, line
2368 * and triangle functions.
2369 */
2370 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2371 gl_set_point_function(ctx);
2372 gl_set_line_function(ctx);
2373 gl_set_triangle_function(ctx);
2374 gl_set_quad_function(ctx);
2375
2376 if ((ctx->IndirectTriangles &
2377 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2378 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2379 ctx->IndirectTriangles &= ~DD_TRI_CULL;
2380 }
2381
2382 if (MESA_VERBOSE&VERBOSE_CULL)
2383 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2384
2385 gl_set_render_vb_function(ctx);
2386 }
2387
2388 /* Should only be calc'd when !need_eye_coords and not culling.
2389 */
2390 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2391 if (ctx->NewState & NEW_MODELVIEW) {
2392 gl_matrix_analyze( &ctx->ModelView );
2393 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2394 }
2395
2396 if (ctx->NewState & NEW_PROJECTION) {
2397 gl_matrix_analyze( &ctx->ProjectionMatrix );
2398 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2399
2400 if (ctx->Transform.AnyClip) {
2401 gl_update_userclip( ctx );
2402 }
2403 }
2404
2405 gl_calculate_model_project_matrix( ctx );
2406 ctx->ModelProjectWinMatrixUptodate = 0;
2407 }
2408
2409 /* Figure out whether we can light in object space or not. If we
2410 * can, find the current positions of the lights in object space
2411 */
2412 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
2413 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2414 (ctx->NewState & (NEW_LIGHTING |
2415 NEW_FOG |
2416 NEW_MODELVIEW |
2417 NEW_PROJECTION |
2418 NEW_TEXTURING |
2419 NEW_RASTER_OPS |
2420 NEW_USER_CLIP)))
2421 {
2422 GLboolean oldcoord, oldnorm;
2423
2424 oldcoord = ctx->NeedEyeCoords;
2425 oldnorm = ctx->NeedEyeNormals;
2426
2427 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2428 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2429 ctx->Point.Attenuated);
2430 ctx->NeedEyeNormals = GL_FALSE;
2431
2432 if (ctx->Light.Enabled) {
2433 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2434 /* Need length for attenuation */
2435 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2436 ctx->NeedEyeCoords = GL_TRUE;
2437 } else if (ctx->Light.NeedVertices) {
2438 /* Need angle for spot calculations */
2439 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2440 ctx->NeedEyeCoords = GL_TRUE;
2441 }
2442 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2443 }
2444 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2445 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2446 if (ctx->Texture.NeedNormals)
2447 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2448 }
2449
2450 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2451
2452 if (ctx->NeedEyeCoords)
2453 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2454
2455 if (ctx->Light.Enabled) {
2456 gl_update_lighting_function(ctx);
2457
2458 if ( (ctx->NewState & NEW_LIGHTING) ||
2459 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2460 !ctx->NeedEyeCoords) ||
2461 oldcoord != ctx->NeedEyeCoords ||
2462 oldnorm != ctx->NeedEyeNormals) {
2463 gl_compute_light_positions(ctx);
2464 }
2465
2466 ctx->rescale_factor = 1.0F;
2467
2468 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2469 MAT_FLAG_GENERAL_SCALE |
2470 MAT_FLAG_GENERAL_3D |
2471 MAT_FLAG_GENERAL) )
2472
2473 {
2474 GLfloat *m = ctx->ModelView.inv;
2475 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2476 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2477 ctx->rescale_factor = 1.0/GL_SQRT(f);
2478 }
2479 }
2480
2481 gl_update_normal_transform( ctx );
2482 }
2483
2484 gl_update_pipelines(ctx);
2485 ctx->NewState = 0;
2486 }