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