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