further simplification of thread-related code, misc clean-up
[mesa.git] / src / mesa / main / context.c
1 /* $Id: context.c,v 1.29 1999/12/17 14:52:35 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 }
1634 newCtx->FirstTimeCurrent = GL_FALSE;
1635 }
1636 }
1637
1638
1639
1640 /*
1641 * Return current context handle for the calling thread.
1642 * This isn't the fastest way to get the current context.
1643 * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
1644 */
1645 GLcontext *gl_get_current_context( void )
1646 {
1647 return (GLcontext *) _glapi_get_current_context();
1648 }
1649
1650
1651
1652 /*
1653 * This should be called by device drivers just before they do a
1654 * swapbuffers. Any pending rendering commands will be executed.
1655 */
1656 void
1657 _mesa_swapbuffers(GLcontext *ctx)
1658 {
1659 FLUSH_VB( ctx, "swap buffers" );
1660 }
1661
1662
1663
1664 /*
1665 * Return pointer to this context's current API dispatch table.
1666 * It'll either be the immediate-mode execute dispatcher or the
1667 * display list compile dispatcher.
1668 */
1669 struct _glapi_table *
1670 _mesa_get_dispatch(GLcontext *ctx)
1671 {
1672 return ctx->CurrentDispatch;
1673 }
1674
1675
1676
1677 void
1678 _mesa_ResizeBuffersMESA( void )
1679 {
1680 GLcontext *ctx = gl_get_current_context();
1681
1682 GLuint buf_width, buf_height;
1683
1684 if (MESA_VERBOSE & VERBOSE_API)
1685 fprintf(stderr, "glResizeBuffersMESA\n");
1686
1687 /* ask device driver for size of output buffer */
1688 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1689
1690 /* see if size of device driver's color buffer (window) has changed */
1691 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1692 ctx->DrawBuffer->Height == (GLint) buf_height)
1693 return;
1694
1695 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1696
1697 /* save buffer size */
1698 ctx->DrawBuffer->Width = buf_width;
1699 ctx->DrawBuffer->Height = buf_height;
1700
1701 /* Reallocate other buffers if needed. */
1702 if (ctx->DrawBuffer->UseSoftwareDepthBuffer) {
1703 gl_alloc_depth_buffer( ctx );
1704 }
1705 if (ctx->DrawBuffer->UseSoftwareStencilBuffer) {
1706 gl_alloc_stencil_buffer( ctx );
1707 }
1708 if (ctx->DrawBuffer->UseSoftwareAccumBuffer) {
1709 gl_alloc_accum_buffer( ctx );
1710 }
1711 if (ctx->Visual->SoftwareAlpha) {
1712 gl_alloc_alpha_buffers( ctx );
1713 }
1714 }
1715
1716
1717
1718 /**********************************************************************/
1719 /***** Miscellaneous functions *****/
1720 /**********************************************************************/
1721
1722
1723 /*
1724 * This function is called when the Mesa user has stumbled into a code
1725 * path which may not be implemented fully or correctly.
1726 */
1727 void gl_problem( const GLcontext *ctx, const char *s )
1728 {
1729 fprintf( stderr, "Mesa implementation error: %s\n", s );
1730 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1731 (void) ctx;
1732 }
1733
1734
1735
1736 /*
1737 * This is called to inform the user that he or she has tried to do
1738 * something illogical or if there's likely a bug in their program
1739 * (like enabled depth testing without a depth buffer).
1740 */
1741 void gl_warning( const GLcontext *ctx, const char *s )
1742 {
1743 GLboolean debug;
1744 #ifdef DEBUG
1745 debug = GL_TRUE;
1746 #else
1747 if (getenv("MESA_DEBUG")) {
1748 debug = GL_TRUE;
1749 }
1750 else {
1751 debug = GL_FALSE;
1752 }
1753 #endif
1754 if (debug) {
1755 fprintf( stderr, "Mesa warning: %s\n", s );
1756 }
1757 (void) ctx;
1758 }
1759
1760
1761
1762 void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1763 {
1764 if (ctx->CompileFlag)
1765 gl_save_error( ctx, error, s );
1766
1767 if (ctx->ExecuteFlag)
1768 gl_error( ctx, error, s );
1769 }
1770
1771
1772 /*
1773 * This is Mesa's error handler. Normally, all that's done is the updating
1774 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1775 * environment variable "MESA_DEBUG" is defined then a real error message
1776 * is printed to stderr.
1777 * Input: error - the error value
1778 * s - a diagnostic string
1779 */
1780 void gl_error( GLcontext *ctx, GLenum error, const char *s )
1781 {
1782 GLboolean debug;
1783
1784 #ifdef DEBUG
1785 debug = GL_TRUE;
1786 #else
1787 if (getenv("MESA_DEBUG")) {
1788 debug = GL_TRUE;
1789 }
1790 else {
1791 debug = GL_FALSE;
1792 }
1793 #endif
1794
1795 if (debug) {
1796 char errstr[1000];
1797
1798 switch (error) {
1799 case GL_NO_ERROR:
1800 strcpy( errstr, "GL_NO_ERROR" );
1801 break;
1802 case GL_INVALID_VALUE:
1803 strcpy( errstr, "GL_INVALID_VALUE" );
1804 break;
1805 case GL_INVALID_ENUM:
1806 strcpy( errstr, "GL_INVALID_ENUM" );
1807 break;
1808 case GL_INVALID_OPERATION:
1809 strcpy( errstr, "GL_INVALID_OPERATION" );
1810 break;
1811 case GL_STACK_OVERFLOW:
1812 strcpy( errstr, "GL_STACK_OVERFLOW" );
1813 break;
1814 case GL_STACK_UNDERFLOW:
1815 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1816 break;
1817 case GL_OUT_OF_MEMORY:
1818 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1819 break;
1820 default:
1821 strcpy( errstr, "unknown" );
1822 break;
1823 }
1824 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1825 }
1826
1827 if (ctx->ErrorValue==GL_NO_ERROR) {
1828 ctx->ErrorValue = error;
1829 }
1830
1831 /* Call device driver's error handler, if any. This is used on the Mac. */
1832 if (ctx->Driver.Error) {
1833 (*ctx->Driver.Error)( ctx );
1834 }
1835 }
1836
1837
1838
1839 /**********************************************************************/
1840 /***** State update logic *****/
1841 /**********************************************************************/
1842
1843
1844 /*
1845 * Since the device driver may or may not support pixel logic ops we
1846 * have to make some extensive tests to determine whether or not
1847 * software-implemented logic operations have to be used.
1848 */
1849 static void update_pixel_logic( GLcontext *ctx )
1850 {
1851 if (ctx->Visual->RGBAflag) {
1852 /* RGBA mode blending w/ Logic Op */
1853 if (ctx->Color.ColorLogicOpEnabled) {
1854 if (ctx->Driver.LogicOp
1855 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1856 /* Device driver can do logic, don't have to do it in software */
1857 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1858 }
1859 else {
1860 /* Device driver can't do logic op so we do it in software */
1861 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1862 }
1863 }
1864 else {
1865 /* no logic op */
1866 if (ctx->Driver.LogicOp) {
1867 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1868 }
1869 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1870 }
1871 }
1872 else {
1873 /* CI mode Logic Op */
1874 if (ctx->Color.IndexLogicOpEnabled) {
1875 if (ctx->Driver.LogicOp
1876 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1877 /* Device driver can do logic, don't have to do it in software */
1878 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1879 }
1880 else {
1881 /* Device driver can't do logic op so we do it in software */
1882 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1883 }
1884 }
1885 else {
1886 /* no logic op */
1887 if (ctx->Driver.LogicOp) {
1888 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1889 }
1890 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1891 }
1892 }
1893 }
1894
1895
1896
1897 /*
1898 * Check if software implemented RGBA or Color Index masking is needed.
1899 */
1900 static void update_pixel_masking( GLcontext *ctx )
1901 {
1902 if (ctx->Visual->RGBAflag) {
1903 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1904 if (*colorMask == 0xffffffff) {
1905 /* disable masking */
1906 if (ctx->Driver.ColorMask) {
1907 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1908 }
1909 ctx->Color.SWmasking = GL_FALSE;
1910 }
1911 else {
1912 /* Ask driver to do color masking, if it can't then
1913 * do it in software
1914 */
1915 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1916 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1917 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1918 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1919 if (ctx->Driver.ColorMask
1920 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1921 ctx->Color.SWmasking = GL_FALSE;
1922 }
1923 else {
1924 ctx->Color.SWmasking = GL_TRUE;
1925 }
1926 }
1927 }
1928 else {
1929 if (ctx->Color.IndexMask==0xffffffff) {
1930 /* disable masking */
1931 if (ctx->Driver.IndexMask) {
1932 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1933 }
1934 ctx->Color.SWmasking = GL_FALSE;
1935 }
1936 else {
1937 /* Ask driver to do index masking, if it can't then
1938 * do it in software
1939 */
1940 if (ctx->Driver.IndexMask
1941 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1942 ctx->Color.SWmasking = GL_FALSE;
1943 }
1944 else {
1945 ctx->Color.SWmasking = GL_TRUE;
1946 }
1947 }
1948 }
1949 }
1950
1951
1952 static void update_fog_mode( GLcontext *ctx )
1953 {
1954 int old_mode = ctx->FogMode;
1955
1956 if (ctx->Fog.Enabled) {
1957 if (ctx->Texture.Enabled)
1958 ctx->FogMode = FOG_FRAGMENT;
1959 else if (ctx->Hint.Fog == GL_NICEST)
1960 ctx->FogMode = FOG_FRAGMENT;
1961 else
1962 ctx->FogMode = FOG_VERTEX;
1963
1964 if (ctx->Driver.GetParameteri)
1965 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
1966 ctx->FogMode = FOG_FRAGMENT;
1967 }
1968 else {
1969 ctx->FogMode = FOG_NONE;
1970 }
1971
1972 if (old_mode != ctx->FogMode)
1973 ctx->NewState |= NEW_FOG;
1974 }
1975
1976
1977 /*
1978 * Recompute the value of ctx->RasterMask, etc. according to
1979 * the current context.
1980 */
1981 static void update_rasterflags( GLcontext *ctx )
1982 {
1983 ctx->RasterMask = 0;
1984
1985 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
1986 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
1987 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
1988 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
1989 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
1990 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
1991 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
1992 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
1993
1994 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
1995 && ctx->Color.DrawBuffer != GL_NONE)
1996 ctx->RasterMask |= ALPHABUF_BIT;
1997
1998 if ( ctx->Viewport.X<0
1999 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
2000 || ctx->Viewport.Y<0
2001 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
2002 ctx->RasterMask |= WINCLIP_BIT;
2003 }
2004
2005 /* If we're not drawing to exactly one color buffer set the
2006 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
2007 * buffers or the RGBA or CI mask disables all writes.
2008 */
2009
2010 ctx->TriangleCaps &= ~DD_MULTIDRAW;
2011
2012 if (ctx->Color.MultiDrawBuffer) {
2013 ctx->RasterMask |= MULTI_DRAW_BIT;
2014 ctx->TriangleCaps |= DD_MULTIDRAW;
2015 }
2016 else if (ctx->Color.DrawBuffer==GL_NONE) {
2017 ctx->RasterMask |= MULTI_DRAW_BIT;
2018 ctx->TriangleCaps |= DD_MULTIDRAW;
2019 }
2020 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2021 /* all RGBA channels disabled */
2022 ctx->RasterMask |= MULTI_DRAW_BIT;
2023 ctx->TriangleCaps |= DD_MULTIDRAW;
2024 ctx->Color.DrawDestMask = 0;
2025 }
2026 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2027 /* all color index bits disabled */
2028 ctx->RasterMask |= MULTI_DRAW_BIT;
2029 ctx->TriangleCaps |= DD_MULTIDRAW;
2030 ctx->Color.DrawDestMask = 0;
2031 }
2032 }
2033
2034
2035 void gl_print_state( const char *msg, GLuint state )
2036 {
2037 fprintf(stderr,
2038 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2039 msg,
2040 state,
2041 (state & NEW_LIGHTING) ? "lighting, " : "",
2042 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2043 (state & NEW_TEXTURING) ? "texturing, " : "",
2044 (state & NEW_POLYGON) ? "polygon, " : "",
2045 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2046 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2047 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2048 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2049 (state & NEW_MODELVIEW) ? "modelview, " : "",
2050 (state & NEW_PROJECTION) ? "projection, " : "",
2051 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2052 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2053 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2054 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2055 (state & NEW_FOG) ? "fog, " : "",
2056 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2057 (state & NEW_VIEWPORT) ? "viewport, " : "",
2058 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2059 }
2060
2061 void gl_print_enable_flags( const char *msg, GLuint flags )
2062 {
2063 fprintf(stderr,
2064 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2065 msg,
2066 flags,
2067 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2068 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2069 (flags & ENABLE_LIGHT) ? "light, " : "",
2070 (flags & ENABLE_FOG) ? "fog, " : "",
2071 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2072 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2073 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2074 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2075 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2076 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2077 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2078 }
2079
2080
2081 /*
2082 * If ctx->NewState is non-zero then this function MUST be called before
2083 * rendering any primitive. Basically, function pointers and miscellaneous
2084 * flags are updated to reflect the current state of the state machine.
2085 */
2086 void gl_update_state( GLcontext *ctx )
2087 {
2088 GLuint i;
2089
2090 if (MESA_VERBOSE & VERBOSE_STATE)
2091 gl_print_state("", ctx->NewState);
2092
2093 if (ctx->NewState & NEW_CLIENT_STATE)
2094 gl_update_client_state( ctx );
2095
2096 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2097 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2098 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2099
2100 if (ctx->NewState & NEW_TEXTURE_ENV) {
2101 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2102 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2103 ctx->NewState &= ~NEW_TEXTURE_ENV;
2104 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2105 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2106 }
2107
2108 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2109 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2110
2111 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2112 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2113 {
2114 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2115 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2116
2117 if (ctx->Texture.Unit[i].Enabled &&
2118 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2119 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2120 }
2121 }
2122 }
2123
2124 if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
2125 ctx->Texture.NeedNormals = GL_FALSE;
2126 gl_update_dirty_texobjs(ctx);
2127 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2128 ctx->Texture.ReallyEnabled = 0;
2129
2130 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2131 if (ctx->Texture.Unit[i].Enabled) {
2132 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2133
2134 ctx->Texture.ReallyEnabled |=
2135 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2136
2137 if (ctx->Texture.Unit[i].GenFlags != 0) {
2138 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2139
2140 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2141 {
2142 ctx->Texture.NeedNormals = GL_TRUE;
2143 ctx->Texture.NeedEyeCoords = GL_TRUE;
2144 }
2145
2146 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2147 {
2148 ctx->Texture.NeedEyeCoords = GL_TRUE;
2149 }
2150 }
2151 }
2152 }
2153
2154 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2155 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2156 }
2157
2158 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2159
2160
2161 if (ctx->NewState & NEW_RASTER_OPS) {
2162 update_pixel_logic(ctx);
2163 update_pixel_masking(ctx);
2164 update_fog_mode(ctx);
2165 update_rasterflags(ctx);
2166 if (ctx->Driver.Dither) {
2167 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2168 }
2169
2170 /* Check if incoming colors can be modified during rasterization */
2171 if (ctx->Fog.Enabled ||
2172 ctx->Texture.Enabled ||
2173 ctx->Color.BlendEnabled ||
2174 ctx->Color.SWmasking ||
2175 ctx->Color.SWLogicOpEnabled) {
2176 ctx->MutablePixels = GL_TRUE;
2177 }
2178 else {
2179 ctx->MutablePixels = GL_FALSE;
2180 }
2181
2182 /* update scissor region */
2183
2184 ctx->DrawBuffer->Xmin = 0;
2185 ctx->DrawBuffer->Ymin = 0;
2186 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2187 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
2188 if (ctx->Scissor.Enabled) {
2189 if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2190 ctx->DrawBuffer->Xmin = ctx->Scissor.X;
2191 }
2192 if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2193 ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
2194 }
2195 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2196 ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2197 }
2198 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2199 ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2200 }
2201 }
2202 }
2203
2204 if (ctx->NewState & NEW_LIGHTING) {
2205 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2206 if (ctx->Light.Enabled) {
2207 if (ctx->Light.Model.TwoSide)
2208 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2209 gl_update_lighting(ctx);
2210 }
2211 }
2212 }
2213
2214 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2215
2216 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
2217
2218 if (ctx->NewState & NEW_POLYGON) {
2219 /* Setup CullBits bitmask */
2220 if (ctx->Polygon.CullFlag) {
2221 ctx->backface_sign = 1;
2222 switch(ctx->Polygon.CullFaceMode) {
2223 case GL_BACK:
2224 if(ctx->Polygon.FrontFace==GL_CCW)
2225 ctx->backface_sign = -1;
2226 ctx->Polygon.CullBits = 1;
2227 break;
2228 case GL_FRONT:
2229 if(ctx->Polygon.FrontFace!=GL_CCW)
2230 ctx->backface_sign = -1;
2231 ctx->Polygon.CullBits = 2;
2232 break;
2233 default:
2234 case GL_FRONT_AND_BACK:
2235 ctx->backface_sign = 0;
2236 ctx->Polygon.CullBits = 0;
2237 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
2238 break;
2239 }
2240 }
2241 else {
2242 ctx->Polygon.CullBits = 3;
2243 ctx->backface_sign = 0;
2244 }
2245
2246 /* Any Polygon offsets enabled? */
2247 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2248
2249 if (ctx->Polygon.OffsetPoint ||
2250 ctx->Polygon.OffsetLine ||
2251 ctx->Polygon.OffsetFill)
2252 ctx->TriangleCaps |= DD_TRI_OFFSET;
2253
2254 /* reset Z offsets now */
2255 ctx->PointZoffset = 0.0;
2256 ctx->LineZoffset = 0.0;
2257 ctx->PolygonZoffset = 0.0;
2258 }
2259 }
2260
2261 if (ctx->NewState & ~(NEW_CLIENT_STATE|
2262 NEW_DRIVER_STATE|NEW_USER_CLIP|
2263 NEW_POLYGON))
2264 gl_update_clipmask(ctx);
2265
2266 if (ctx->NewState & (NEW_LIGHTING|
2267 NEW_RASTER_OPS|
2268 NEW_TEXTURING|
2269 NEW_TEXTURE_ENABLE|
2270 NEW_TEXTURE_ENV|
2271 NEW_POLYGON|
2272 NEW_DRVSTATE0|
2273 NEW_DRVSTATE1|
2274 NEW_DRVSTATE2|
2275 NEW_DRVSTATE3|
2276 NEW_USER_CLIP))
2277 {
2278 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2279 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2280
2281 if (MESA_VERBOSE&VERBOSE_CULL)
2282 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2283
2284 ctx->Driver.PointsFunc = NULL;
2285 ctx->Driver.LineFunc = NULL;
2286 ctx->Driver.TriangleFunc = NULL;
2287 ctx->Driver.QuadFunc = NULL;
2288 ctx->Driver.RectFunc = NULL;
2289 ctx->Driver.RenderVBClippedTab = NULL;
2290 ctx->Driver.RenderVBCulledTab = NULL;
2291 ctx->Driver.RenderVBRawTab = NULL;
2292
2293 /*
2294 * Here the driver sets up all the ctx->Driver function pointers to
2295 * it's specific, private functions.
2296 */
2297 ctx->Driver.UpdateState(ctx);
2298
2299 if (MESA_VERBOSE&VERBOSE_CULL)
2300 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2301
2302 /*
2303 * In case the driver didn't hook in an optimized point, line or
2304 * triangle function we'll now select "core/fallback" point, line
2305 * and triangle functions.
2306 */
2307 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2308 gl_set_point_function(ctx);
2309 gl_set_line_function(ctx);
2310 gl_set_triangle_function(ctx);
2311 gl_set_quad_function(ctx);
2312
2313 if ((ctx->IndirectTriangles &
2314 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2315 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2316 ctx->IndirectTriangles &= ~DD_TRI_CULL;
2317 }
2318
2319 if (MESA_VERBOSE&VERBOSE_CULL)
2320 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2321
2322 gl_set_render_vb_function(ctx);
2323 }
2324
2325 /* Should only be calc'd when !need_eye_coords and not culling.
2326 */
2327 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2328 if (ctx->NewState & NEW_MODELVIEW) {
2329 gl_matrix_analyze( &ctx->ModelView );
2330 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2331 }
2332
2333 if (ctx->NewState & NEW_PROJECTION) {
2334 gl_matrix_analyze( &ctx->ProjectionMatrix );
2335 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2336
2337 if (ctx->Transform.AnyClip) {
2338 gl_update_userclip( ctx );
2339 }
2340 }
2341
2342 gl_calculate_model_project_matrix( ctx );
2343 ctx->ModelProjectWinMatrixUptodate = 0;
2344 }
2345
2346 /* Figure out whether we can light in object space or not. If we
2347 * can, find the current positions of the lights in object space
2348 */
2349 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
2350 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2351 (ctx->NewState & (NEW_LIGHTING |
2352 NEW_FOG |
2353 NEW_MODELVIEW |
2354 NEW_PROJECTION |
2355 NEW_TEXTURING |
2356 NEW_RASTER_OPS |
2357 NEW_USER_CLIP)))
2358 {
2359 GLboolean oldcoord, oldnorm;
2360
2361 oldcoord = ctx->NeedEyeCoords;
2362 oldnorm = ctx->NeedEyeNormals;
2363
2364 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2365 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2366 ctx->Point.Attenuated);
2367 ctx->NeedEyeNormals = GL_FALSE;
2368
2369 if (ctx->Light.Enabled) {
2370 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2371 /* Need length for attenuation */
2372 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2373 ctx->NeedEyeCoords = GL_TRUE;
2374 } else if (ctx->Light.NeedVertices) {
2375 /* Need angle for spot calculations */
2376 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2377 ctx->NeedEyeCoords = GL_TRUE;
2378 }
2379 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2380 }
2381 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2382 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2383 if (ctx->Texture.NeedNormals)
2384 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2385 }
2386
2387 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2388
2389 if (ctx->NeedEyeCoords)
2390 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2391
2392 if (ctx->Light.Enabled) {
2393 gl_update_lighting_function(ctx);
2394
2395 if ( (ctx->NewState & NEW_LIGHTING) ||
2396 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2397 !ctx->NeedEyeCoords) ||
2398 oldcoord != ctx->NeedEyeCoords ||
2399 oldnorm != ctx->NeedEyeNormals) {
2400 gl_compute_light_positions(ctx);
2401 }
2402
2403 ctx->rescale_factor = 1.0F;
2404
2405 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2406 MAT_FLAG_GENERAL_SCALE |
2407 MAT_FLAG_GENERAL_3D |
2408 MAT_FLAG_GENERAL) )
2409
2410 {
2411 GLfloat *m = ctx->ModelView.inv;
2412 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2413 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2414 ctx->rescale_factor = 1.0/GL_SQRT(f);
2415 }
2416 }
2417
2418 gl_update_normal_transform( ctx );
2419 }
2420
2421 gl_update_pipelines(ctx);
2422 ctx->NewState = 0;
2423 }