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