added support for separate read/draw buffers per context
[mesa.git] / src / mesa / main / context.c
1 /* $Id: context.c,v 1.23 1999/11/24 18:48:31 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_color_table( struct gl_color_table *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_color_table(&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->DrawBuffer = NULL;
1208 ctx->ReadBuffer = NULL;
1209
1210 ctx->VB = gl_vb_create_for_immediate( ctx );
1211 if (!ctx->VB) {
1212 FREE( ctx );
1213 return NULL;
1214 }
1215 ctx->input = ctx->VB->IM;
1216
1217 ctx->PB = gl_alloc_pb();
1218 if (!ctx->PB) {
1219 FREE( ctx->VB );
1220 FREE( ctx );
1221 return NULL;
1222 }
1223
1224 if (share_list) {
1225 /* share the group of display lists of another context */
1226 ctx->Shared = share_list->Shared;
1227 }
1228 else {
1229 /* allocate new group of display lists */
1230 ctx->Shared = alloc_shared_state();
1231 if (!ctx->Shared) {
1232 FREE(ctx->VB);
1233 FREE(ctx->PB);
1234 FREE(ctx);
1235 return NULL;
1236 }
1237 }
1238 ctx->Shared->RefCount++;
1239
1240 initialize_context( ctx );
1241 gl_reset_vb( ctx->VB );
1242 gl_reset_input( ctx );
1243
1244
1245 ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
1246 make_empty_list( ctx->ShineTabList );
1247
1248 for (i = 0 ; i < 10 ; i++) {
1249 struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
1250 s->shininess = -1;
1251 s->refcount = 0;
1252 insert_at_tail( ctx->ShineTabList, s );
1253 }
1254
1255 for (i = 0 ; i < 4 ; i++) {
1256 ctx->ShineTable[i] = ctx->ShineTabList->prev;
1257 ctx->ShineTable[i]->refcount++;
1258 }
1259
1260 if (visual->DBflag) {
1261 ctx->Color.DrawBuffer = GL_BACK;
1262 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1263 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1264 ctx->Pixel.ReadBuffer = GL_BACK;
1265 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1266 }
1267 else {
1268 ctx->Color.DrawBuffer = GL_FRONT;
1269 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1270 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1271 ctx->Pixel.ReadBuffer = GL_FRONT;
1272 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1273 }
1274
1275
1276 /* Fill in some driver defaults now.
1277 */
1278 ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
1279 ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
1280 ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
1281
1282 #ifdef PROFILE
1283 init_timings( ctx );
1284 #endif
1285
1286 if (!alloc_proxy_textures(ctx)) {
1287 free_shared_state(ctx, ctx->Shared);
1288 FREE(ctx->VB);
1289 FREE(ctx->PB);
1290 FREE(ctx);
1291 return NULL;
1292 }
1293
1294 /* setup API dispatch tables */
1295 _mesa_init_exec_table( &ctx->Exec );
1296 _mesa_init_dlist_table( &ctx->Save );
1297 ctx->CurrentDispatch = &ctx->Exec;
1298
1299 return ctx;
1300 }
1301
1302 /* Just reads the config files...
1303 */
1304 void gl_context_initialize( GLcontext *ctx )
1305 {
1306 gl_read_config_file( ctx );
1307 }
1308
1309
1310
1311
1312 /*
1313 * Destroy a gl_context structure.
1314 */
1315 void gl_destroy_context( GLcontext *ctx )
1316 {
1317 if (ctx) {
1318
1319 GLuint i;
1320 struct gl_shine_tab *s, *tmps;
1321
1322 #ifdef PROFILE
1323 if (getenv("MESA_PROFILE")) {
1324 print_timings( ctx );
1325 }
1326 #endif
1327
1328 gl_matrix_dtr( &ctx->ModelView );
1329 for (i = 0 ; i < MAX_MODELVIEW_STACK_DEPTH ; i++) {
1330 gl_matrix_dtr( &ctx->ModelViewStack[i] );
1331 }
1332 gl_matrix_dtr( &ctx->ProjectionMatrix );
1333 for (i = 0 ; i < MAX_PROJECTION_STACK_DEPTH ; i++) {
1334 gl_matrix_dtr( &ctx->ProjectionStack[i] );
1335 }
1336
1337 FREE( ctx->PB );
1338
1339 if(ctx->input != ctx->VB->IM)
1340 gl_immediate_free( ctx->input );
1341
1342 gl_vb_free( ctx->VB );
1343
1344 ctx->Shared->RefCount--;
1345 assert(ctx->Shared->RefCount>=0);
1346 if (ctx->Shared->RefCount==0) {
1347 /* free shared state */
1348 free_shared_state( ctx, ctx->Shared );
1349 }
1350
1351 foreach_s( s, tmps, ctx->ShineTabList ) {
1352 FREE( s );
1353 }
1354 FREE( ctx->ShineTabList );
1355
1356 /* Free proxy texture objects */
1357 gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1358 gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1359 gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1360
1361 /* Free evaluator data */
1362 if (ctx->EvalMap.Map1Vertex3.Points)
1363 FREE( ctx->EvalMap.Map1Vertex3.Points );
1364 if (ctx->EvalMap.Map1Vertex4.Points)
1365 FREE( ctx->EvalMap.Map1Vertex4.Points );
1366 if (ctx->EvalMap.Map1Index.Points)
1367 FREE( ctx->EvalMap.Map1Index.Points );
1368 if (ctx->EvalMap.Map1Color4.Points)
1369 FREE( ctx->EvalMap.Map1Color4.Points );
1370 if (ctx->EvalMap.Map1Normal.Points)
1371 FREE( ctx->EvalMap.Map1Normal.Points );
1372 if (ctx->EvalMap.Map1Texture1.Points)
1373 FREE( ctx->EvalMap.Map1Texture1.Points );
1374 if (ctx->EvalMap.Map1Texture2.Points)
1375 FREE( ctx->EvalMap.Map1Texture2.Points );
1376 if (ctx->EvalMap.Map1Texture3.Points)
1377 FREE( ctx->EvalMap.Map1Texture3.Points );
1378 if (ctx->EvalMap.Map1Texture4.Points)
1379 FREE( ctx->EvalMap.Map1Texture4.Points );
1380
1381 if (ctx->EvalMap.Map2Vertex3.Points)
1382 FREE( ctx->EvalMap.Map2Vertex3.Points );
1383 if (ctx->EvalMap.Map2Vertex4.Points)
1384 FREE( ctx->EvalMap.Map2Vertex4.Points );
1385 if (ctx->EvalMap.Map2Index.Points)
1386 FREE( ctx->EvalMap.Map2Index.Points );
1387 if (ctx->EvalMap.Map2Color4.Points)
1388 FREE( ctx->EvalMap.Map2Color4.Points );
1389 if (ctx->EvalMap.Map2Normal.Points)
1390 FREE( ctx->EvalMap.Map2Normal.Points );
1391 if (ctx->EvalMap.Map2Texture1.Points)
1392 FREE( ctx->EvalMap.Map2Texture1.Points );
1393 if (ctx->EvalMap.Map2Texture2.Points)
1394 FREE( ctx->EvalMap.Map2Texture2.Points );
1395 if (ctx->EvalMap.Map2Texture3.Points)
1396 FREE( ctx->EvalMap.Map2Texture3.Points );
1397 if (ctx->EvalMap.Map2Texture4.Points)
1398 FREE( ctx->EvalMap.Map2Texture4.Points );
1399
1400 /* Free cache of immediate buffers. */
1401 while (ctx->nr_im_queued-- > 0) {
1402 struct immediate * next = ctx->freed_im_queue->next;
1403 FREE( ctx->freed_im_queue );
1404 ctx->freed_im_queue = next;
1405 }
1406 gl_extensions_dtr(ctx);
1407
1408 FREE( (void *) ctx );
1409
1410 #ifndef THREADS
1411 if (ctx == _mesa_current_context) {
1412 _mesa_current_context = NULL;
1413 CURRENT_INPUT = NULL;
1414 }
1415 #endif
1416
1417 }
1418 }
1419
1420
1421
1422 /*
1423 * Create a new framebuffer. A GLframebuffer is a struct which
1424 * encapsulates the depth, stencil and accum buffers and related
1425 * parameters.
1426 * Input: visual - a GLvisual pointer
1427 * Return: pointer to new GLframebuffer struct or NULL if error.
1428 */
1429 GLframebuffer *gl_create_framebuffer( GLvisual *visual )
1430 {
1431 GLframebuffer *buffer;
1432
1433 buffer = (GLframebuffer *) CALLOC( sizeof(GLframebuffer) );
1434 if (!buffer) {
1435 return NULL;
1436 }
1437
1438 buffer->Visual = visual;
1439
1440 return buffer;
1441 }
1442
1443
1444
1445 /*
1446 * Free a framebuffer struct and its buffers.
1447 */
1448 void gl_destroy_framebuffer( GLframebuffer *buffer )
1449 {
1450 if (buffer) {
1451 if (buffer->Depth) {
1452 FREE( buffer->Depth );
1453 }
1454 if (buffer->Accum) {
1455 FREE( buffer->Accum );
1456 }
1457 if (buffer->Stencil) {
1458 FREE( buffer->Stencil );
1459 }
1460 if (buffer->FrontLeftAlpha) {
1461 FREE( buffer->FrontLeftAlpha );
1462 }
1463 if (buffer->BackLeftAlpha) {
1464 FREE( buffer->BackLeftAlpha );
1465 }
1466 if (buffer->FrontRightAlpha) {
1467 FREE( buffer->FrontRightAlpha );
1468 }
1469 if (buffer->BackRightAlpha) {
1470 FREE( buffer->BackRightAlpha );
1471 }
1472 FREE(buffer);
1473 }
1474 }
1475
1476
1477
1478 /*
1479 * Set the current context, binding the given frame buffer to the context.
1480 */
1481 void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1482 {
1483 gl_make_current2( newCtx, buffer, buffer );
1484 }
1485
1486
1487 /*
1488 * Bind the given context to the given draw-buffer and read-buffer
1489 * and make it the current context for this thread.
1490 */
1491 void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1492 GLframebuffer *readBuffer )
1493 {
1494 GET_CURRENT_CONTEXT(oldCtx);
1495
1496 /* Flush the old context
1497 */
1498 if (oldCtx) {
1499 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
1500 }
1501
1502 /* unbind frame buffers from context */
1503 if (oldCtx && oldCtx->DrawBuffer) {
1504 oldCtx->DrawBuffer = NULL;
1505 }
1506 if (oldCtx && oldCtx->ReadBuffer) {
1507 oldCtx->ReadBuffer = NULL;
1508 }
1509
1510 #ifdef THREADS
1511 /* TODO: unbind old buffer from context? */
1512 MesaSetTSD(&mesa_ctx_tsd, (void *) newCtx, mesa_ctx_thread_init);
1513 #else
1514 _mesa_current_context = newCtx;
1515 #endif
1516 if (newCtx) {
1517 SET_IMMEDIATE(newCtx, newCtx->input);
1518 }
1519
1520 if (newCtx)
1521 _glapi_set_dispatch(newCtx->CurrentDispatch);
1522 else
1523 _glapi_set_dispatch(NULL); /* none current */
1524
1525 if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1526
1527 if (newCtx && drawBuffer && readBuffer) {
1528 /* TODO: check if newCtx and buffer's visual match??? */
1529 newCtx->DrawBuffer = drawBuffer;
1530 newCtx->ReadBuffer = readBuffer;
1531 newCtx->NewState = NEW_ALL; /* just to be safe */
1532 gl_update_state( newCtx );
1533 }
1534 }
1535
1536
1537
1538 /*
1539 * Return current context handle for the calling thread.
1540 */
1541 GLcontext *gl_get_current_context( void )
1542 {
1543 #ifdef THREADS
1544 return (GLcontext *) MesaGetTSD(&mesa_ctx_tsd);
1545 #else
1546 return _mesa_current_context;
1547 #endif
1548 }
1549
1550
1551
1552 /*
1553 * Copy attribute groups from one context to another.
1554 * Input: src - source context
1555 * dst - destination context
1556 * mask - bitwise OR of GL_*_BIT flags
1557 */
1558 void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1559 {
1560 if (mask & GL_ACCUM_BUFFER_BIT) {
1561 MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1562 }
1563 if (mask & GL_COLOR_BUFFER_BIT) {
1564 MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1565 }
1566 if (mask & GL_CURRENT_BIT) {
1567 MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1568 }
1569 if (mask & GL_DEPTH_BUFFER_BIT) {
1570 MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1571 }
1572 if (mask & GL_ENABLE_BIT) {
1573 /* no op */
1574 }
1575 if (mask & GL_EVAL_BIT) {
1576 MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1577 }
1578 if (mask & GL_FOG_BIT) {
1579 MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1580 }
1581 if (mask & GL_HINT_BIT) {
1582 MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1583 }
1584 if (mask & GL_LIGHTING_BIT) {
1585 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1586 /* gl_reinit_light_attrib( &dst->Light ); */
1587 }
1588 if (mask & GL_LINE_BIT) {
1589 MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1590 }
1591 if (mask & GL_LIST_BIT) {
1592 MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1593 }
1594 if (mask & GL_PIXEL_MODE_BIT) {
1595 MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1596 }
1597 if (mask & GL_POINT_BIT) {
1598 MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1599 }
1600 if (mask & GL_POLYGON_BIT) {
1601 MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1602 }
1603 if (mask & GL_POLYGON_STIPPLE_BIT) {
1604 /* Use loop instead of MEMCPY due to problem with Portland Group's
1605 * C compiler. Reported by John Stone.
1606 */
1607 int i;
1608 for (i=0;i<32;i++) {
1609 dst->PolygonStipple[i] = src->PolygonStipple[i];
1610 }
1611 }
1612 if (mask & GL_SCISSOR_BIT) {
1613 MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1614 }
1615 if (mask & GL_STENCIL_BUFFER_BIT) {
1616 MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1617 }
1618 if (mask & GL_TEXTURE_BIT) {
1619 MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1620 }
1621 if (mask & GL_TRANSFORM_BIT) {
1622 MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1623 }
1624 if (mask & GL_VIEWPORT_BIT) {
1625 MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1626 }
1627 }
1628
1629
1630 /*
1631 * This should be called by device drivers just before they do a
1632 * swapbuffers. Any pending rendering commands will be executed.
1633 */
1634 void
1635 _mesa_swapbuffers(GLcontext *ctx)
1636 {
1637 FLUSH_VB( ctx, "swap buffers" );
1638 }
1639
1640
1641 /*
1642 * Return pointer to this context's current API dispatch table.
1643 * It'll either be the immediate-mode execute dispatcher or the
1644 * display list compile dispatcher.
1645 */
1646 struct _glapi_table *
1647 _mesa_get_dispatch(GLcontext *ctx)
1648 {
1649 return ctx->CurrentDispatch;
1650 }
1651
1652
1653
1654 void
1655 _mesa_ResizeBuffersMESA( void )
1656 {
1657 GET_CURRENT_CONTEXT(ctx);
1658
1659 GLuint buf_width, buf_height;
1660
1661 if (MESA_VERBOSE & VERBOSE_API)
1662 fprintf(stderr, "glResizeBuffersMESA\n");
1663
1664 /* ask device driver for size of output buffer */
1665 (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1666
1667 /* see if size of device driver's color buffer (window) has changed */
1668 if (ctx->DrawBuffer->Width == (GLint) buf_width &&
1669 ctx->DrawBuffer->Height == (GLint) buf_height)
1670 return;
1671
1672 ctx->NewState |= NEW_RASTER_OPS; /* to update scissor / window bounds */
1673
1674 /* save buffer size */
1675 ctx->DrawBuffer->Width = buf_width;
1676 ctx->DrawBuffer->Height = buf_height;
1677
1678 /* Reallocate other buffers if needed. */
1679 if (ctx->Visual->DepthBits>0) {
1680 /* reallocate depth buffer */
1681 (*ctx->Driver.AllocDepthBuffer)( ctx );
1682 }
1683 if (ctx->Visual->StencilBits>0) {
1684 /* reallocate stencil buffer */
1685 gl_alloc_stencil_buffer( ctx );
1686 }
1687 if (ctx->Visual->AccumBits>0) {
1688 /* reallocate accum buffer */
1689 gl_alloc_accum_buffer( ctx );
1690 }
1691 if (ctx->Visual->SoftwareAlpha) {
1692 gl_alloc_alpha_buffers( ctx );
1693 }
1694 }
1695
1696
1697
1698 /**********************************************************************/
1699 /***** Miscellaneous functions *****/
1700 /**********************************************************************/
1701
1702
1703 /*
1704 * This function is called when the Mesa user has stumbled into a code
1705 * path which may not be implemented fully or correctly.
1706 */
1707 void gl_problem( const GLcontext *ctx, const char *s )
1708 {
1709 fprintf( stderr, "Mesa implementation error: %s\n", s );
1710 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1711 (void) ctx;
1712 }
1713
1714
1715
1716 /*
1717 * This is called to inform the user that he or she has tried to do
1718 * something illogical or if there's likely a bug in their program
1719 * (like enabled depth testing without a depth buffer).
1720 */
1721 void gl_warning( const GLcontext *ctx, const char *s )
1722 {
1723 GLboolean debug;
1724 #ifdef DEBUG
1725 debug = GL_TRUE;
1726 #else
1727 if (getenv("MESA_DEBUG")) {
1728 debug = GL_TRUE;
1729 }
1730 else {
1731 debug = GL_FALSE;
1732 }
1733 #endif
1734 if (debug) {
1735 fprintf( stderr, "Mesa warning: %s\n", s );
1736 }
1737 (void) ctx;
1738 }
1739
1740
1741
1742 void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1743 {
1744 if (ctx->CompileFlag)
1745 gl_save_error( ctx, error, s );
1746
1747 if (ctx->ExecuteFlag)
1748 gl_error( ctx, error, s );
1749 }
1750
1751
1752 /*
1753 * This is Mesa's error handler. Normally, all that's done is the updating
1754 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1755 * environment variable "MESA_DEBUG" is defined then a real error message
1756 * is printed to stderr.
1757 * Input: error - the error value
1758 * s - a diagnostic string
1759 */
1760 void gl_error( GLcontext *ctx, GLenum error, const char *s )
1761 {
1762 GLboolean debug;
1763
1764 #ifdef DEBUG
1765 debug = GL_TRUE;
1766 #else
1767 if (getenv("MESA_DEBUG")) {
1768 debug = GL_TRUE;
1769 }
1770 else {
1771 debug = GL_FALSE;
1772 }
1773 #endif
1774
1775 if (debug) {
1776 char errstr[1000];
1777
1778 switch (error) {
1779 case GL_NO_ERROR:
1780 strcpy( errstr, "GL_NO_ERROR" );
1781 break;
1782 case GL_INVALID_VALUE:
1783 strcpy( errstr, "GL_INVALID_VALUE" );
1784 break;
1785 case GL_INVALID_ENUM:
1786 strcpy( errstr, "GL_INVALID_ENUM" );
1787 break;
1788 case GL_INVALID_OPERATION:
1789 strcpy( errstr, "GL_INVALID_OPERATION" );
1790 break;
1791 case GL_STACK_OVERFLOW:
1792 strcpy( errstr, "GL_STACK_OVERFLOW" );
1793 break;
1794 case GL_STACK_UNDERFLOW:
1795 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1796 break;
1797 case GL_OUT_OF_MEMORY:
1798 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1799 break;
1800 default:
1801 strcpy( errstr, "unknown" );
1802 break;
1803 }
1804 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1805 }
1806
1807 if (ctx->ErrorValue==GL_NO_ERROR) {
1808 ctx->ErrorValue = error;
1809 }
1810
1811 /* Call device driver's error handler, if any. This is used on the Mac. */
1812 if (ctx->Driver.Error) {
1813 (*ctx->Driver.Error)( ctx );
1814 }
1815 }
1816
1817
1818
1819 /**********************************************************************/
1820 /***** State update logic *****/
1821 /**********************************************************************/
1822
1823
1824 /*
1825 * Since the device driver may or may not support pixel logic ops we
1826 * have to make some extensive tests to determine whether or not
1827 * software-implemented logic operations have to be used.
1828 */
1829 static void update_pixel_logic( GLcontext *ctx )
1830 {
1831 if (ctx->Visual->RGBAflag) {
1832 /* RGBA mode blending w/ Logic Op */
1833 if (ctx->Color.ColorLogicOpEnabled) {
1834 if (ctx->Driver.LogicOp
1835 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1836 /* Device driver can do logic, don't have to do it in software */
1837 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1838 }
1839 else {
1840 /* Device driver can't do logic op so we do it in software */
1841 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1842 }
1843 }
1844 else {
1845 /* no logic op */
1846 if (ctx->Driver.LogicOp) {
1847 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1848 }
1849 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1850 }
1851 }
1852 else {
1853 /* CI mode Logic Op */
1854 if (ctx->Color.IndexLogicOpEnabled) {
1855 if (ctx->Driver.LogicOp
1856 && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1857 /* Device driver can do logic, don't have to do it in software */
1858 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1859 }
1860 else {
1861 /* Device driver can't do logic op so we do it in software */
1862 ctx->Color.SWLogicOpEnabled = GL_TRUE;
1863 }
1864 }
1865 else {
1866 /* no logic op */
1867 if (ctx->Driver.LogicOp) {
1868 (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1869 }
1870 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1871 }
1872 }
1873 }
1874
1875
1876
1877 /*
1878 * Check if software implemented RGBA or Color Index masking is needed.
1879 */
1880 static void update_pixel_masking( GLcontext *ctx )
1881 {
1882 if (ctx->Visual->RGBAflag) {
1883 GLuint *colorMask = (GLuint *) ctx->Color.ColorMask;
1884 if (*colorMask == 0xffffffff) {
1885 /* disable masking */
1886 if (ctx->Driver.ColorMask) {
1887 (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1888 }
1889 ctx->Color.SWmasking = GL_FALSE;
1890 }
1891 else {
1892 /* Ask driver to do color masking, if it can't then
1893 * do it in software
1894 */
1895 GLboolean red = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE;
1896 GLboolean green = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE;
1897 GLboolean blue = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE;
1898 GLboolean alpha = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE;
1899 if (ctx->Driver.ColorMask
1900 && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1901 ctx->Color.SWmasking = GL_FALSE;
1902 }
1903 else {
1904 ctx->Color.SWmasking = GL_TRUE;
1905 }
1906 }
1907 }
1908 else {
1909 if (ctx->Color.IndexMask==0xffffffff) {
1910 /* disable masking */
1911 if (ctx->Driver.IndexMask) {
1912 (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1913 }
1914 ctx->Color.SWmasking = GL_FALSE;
1915 }
1916 else {
1917 /* Ask driver to do index masking, if it can't then
1918 * do it in software
1919 */
1920 if (ctx->Driver.IndexMask
1921 && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1922 ctx->Color.SWmasking = GL_FALSE;
1923 }
1924 else {
1925 ctx->Color.SWmasking = GL_TRUE;
1926 }
1927 }
1928 }
1929 }
1930
1931
1932 static void update_fog_mode( GLcontext *ctx )
1933 {
1934 int old_mode = ctx->FogMode;
1935
1936 if (ctx->Fog.Enabled) {
1937 if (ctx->Texture.Enabled)
1938 ctx->FogMode = FOG_FRAGMENT;
1939 else if (ctx->Hint.Fog == GL_NICEST)
1940 ctx->FogMode = FOG_FRAGMENT;
1941 else
1942 ctx->FogMode = FOG_VERTEX;
1943
1944 if (ctx->Driver.GetParameteri)
1945 if ((ctx->Driver.GetParameteri)( ctx, DD_HAVE_HARDWARE_FOG ))
1946 ctx->FogMode = FOG_FRAGMENT;
1947 }
1948 else {
1949 ctx->FogMode = FOG_NONE;
1950 }
1951
1952 if (old_mode != ctx->FogMode)
1953 ctx->NewState |= NEW_FOG;
1954 }
1955
1956
1957 /*
1958 * Recompute the value of ctx->RasterMask, etc. according to
1959 * the current context.
1960 */
1961 static void update_rasterflags( GLcontext *ctx )
1962 {
1963 ctx->RasterMask = 0;
1964
1965 if (ctx->Color.AlphaEnabled) ctx->RasterMask |= ALPHATEST_BIT;
1966 if (ctx->Color.BlendEnabled) ctx->RasterMask |= BLEND_BIT;
1967 if (ctx->Depth.Test) ctx->RasterMask |= DEPTH_BIT;
1968 if (ctx->FogMode==FOG_FRAGMENT) ctx->RasterMask |= FOG_BIT;
1969 if (ctx->Color.SWLogicOpEnabled) ctx->RasterMask |= LOGIC_OP_BIT;
1970 if (ctx->Scissor.Enabled) ctx->RasterMask |= SCISSOR_BIT;
1971 if (ctx->Stencil.Enabled) ctx->RasterMask |= STENCIL_BIT;
1972 if (ctx->Color.SWmasking) ctx->RasterMask |= MASKING_BIT;
1973
1974 if (ctx->Visual->SoftwareAlpha && ctx->Color.ColorMask[ACOMP]
1975 && ctx->Color.DrawBuffer != GL_NONE)
1976 ctx->RasterMask |= ALPHABUF_BIT;
1977
1978 if ( ctx->Viewport.X<0
1979 || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
1980 || ctx->Viewport.Y<0
1981 || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
1982 ctx->RasterMask |= WINCLIP_BIT;
1983 }
1984
1985 /* If we're not drawing to exactly one color buffer set the
1986 * MULTI_DRAW_BIT flag. Also set it if we're drawing to no
1987 * buffers or the RGBA or CI mask disables all writes.
1988 */
1989
1990 ctx->TriangleCaps &= ~DD_MULTIDRAW;
1991
1992 if (ctx->Color.MultiDrawBuffer) {
1993 ctx->RasterMask |= MULTI_DRAW_BIT;
1994 ctx->TriangleCaps |= DD_MULTIDRAW;
1995 }
1996 else if (ctx->Color.DrawBuffer==GL_NONE) {
1997 ctx->RasterMask |= MULTI_DRAW_BIT;
1998 ctx->TriangleCaps |= DD_MULTIDRAW;
1999 }
2000 else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
2001 /* all RGBA channels disabled */
2002 ctx->RasterMask |= MULTI_DRAW_BIT;
2003 ctx->TriangleCaps |= DD_MULTIDRAW;
2004 ctx->Color.DrawDestMask = 0;
2005 }
2006 else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
2007 /* all color index bits disabled */
2008 ctx->RasterMask |= MULTI_DRAW_BIT;
2009 ctx->TriangleCaps |= DD_MULTIDRAW;
2010 ctx->Color.DrawDestMask = 0;
2011 }
2012 }
2013
2014
2015 void gl_print_state( const char *msg, GLuint state )
2016 {
2017 fprintf(stderr,
2018 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
2019 msg,
2020 state,
2021 (state & NEW_LIGHTING) ? "lighting, " : "",
2022 (state & NEW_RASTER_OPS) ? "raster-ops, " : "",
2023 (state & NEW_TEXTURING) ? "texturing, " : "",
2024 (state & NEW_POLYGON) ? "polygon, " : "",
2025 (state & NEW_DRVSTATE0) ? "driver-0, " : "",
2026 (state & NEW_DRVSTATE1) ? "driver-1, " : "",
2027 (state & NEW_DRVSTATE2) ? "driver-2, " : "",
2028 (state & NEW_DRVSTATE3) ? "driver-3, " : "",
2029 (state & NEW_MODELVIEW) ? "modelview, " : "",
2030 (state & NEW_PROJECTION) ? "projection, " : "",
2031 (state & NEW_TEXTURE_MATRIX) ? "texture-matrix, " : "",
2032 (state & NEW_USER_CLIP) ? "user-clip, " : "",
2033 (state & NEW_TEXTURE_ENV) ? "texture-env, " : "",
2034 (state & NEW_CLIENT_STATE) ? "client-state, " : "",
2035 (state & NEW_FOG) ? "fog, " : "",
2036 (state & NEW_NORMAL_TRANSFORM) ? "normal-transform, " : "",
2037 (state & NEW_VIEWPORT) ? "viewport, " : "",
2038 (state & NEW_TEXTURE_ENABLE) ? "texture-enable, " : "");
2039 }
2040
2041 void gl_print_enable_flags( const char *msg, GLuint flags )
2042 {
2043 fprintf(stderr,
2044 "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
2045 msg,
2046 flags,
2047 (flags & ENABLE_TEX0) ? "tex-0, " : "",
2048 (flags & ENABLE_TEX1) ? "tex-1, " : "",
2049 (flags & ENABLE_LIGHT) ? "light, " : "",
2050 (flags & ENABLE_FOG) ? "fog, " : "",
2051 (flags & ENABLE_USERCLIP) ? "userclip, " : "",
2052 (flags & ENABLE_TEXGEN0) ? "tex-gen-0, " : "",
2053 (flags & ENABLE_TEXGEN1) ? "tex-gen-1, " : "",
2054 (flags & ENABLE_TEXMAT0) ? "tex-mat-0, " : "",
2055 (flags & ENABLE_TEXMAT1) ? "tex-mat-1, " : "",
2056 (flags & ENABLE_NORMALIZE) ? "normalize, " : "",
2057 (flags & ENABLE_RESCALE) ? "rescale, " : "");
2058 }
2059
2060
2061 /*
2062 * If ctx->NewState is non-zero then this function MUST be called before
2063 * rendering any primitive. Basically, function pointers and miscellaneous
2064 * flags are updated to reflect the current state of the state machine.
2065 */
2066 void gl_update_state( GLcontext *ctx )
2067 {
2068 GLuint i;
2069
2070 if (MESA_VERBOSE & VERBOSE_STATE)
2071 gl_print_state("", ctx->NewState);
2072
2073 if (ctx->NewState & NEW_CLIENT_STATE)
2074 gl_update_client_state( ctx );
2075
2076 if ((ctx->NewState & NEW_TEXTURE_ENABLE) &&
2077 (ctx->Enabled & ENABLE_TEX_ANY) != ctx->Texture.Enabled)
2078 ctx->NewState |= NEW_TEXTURING | NEW_RASTER_OPS;
2079
2080 if (ctx->NewState & NEW_TEXTURE_ENV) {
2081 if (ctx->Texture.Unit[0].EnvMode == ctx->Texture.Unit[0].LastEnvMode &&
2082 ctx->Texture.Unit[1].EnvMode == ctx->Texture.Unit[1].LastEnvMode)
2083 ctx->NewState &= ~NEW_TEXTURE_ENV;
2084 ctx->Texture.Unit[0].LastEnvMode = ctx->Texture.Unit[0].EnvMode;
2085 ctx->Texture.Unit[1].LastEnvMode = ctx->Texture.Unit[1].EnvMode;
2086 }
2087
2088 if (ctx->NewState & NEW_TEXTURE_MATRIX) {
2089 ctx->Enabled &= ~(ENABLE_TEXMAT0|ENABLE_TEXMAT1);
2090
2091 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2092 if (ctx->TextureMatrix[i].flags & MAT_DIRTY_ALL_OVER)
2093 {
2094 gl_matrix_analyze( &ctx->TextureMatrix[i] );
2095 ctx->TextureMatrix[i].flags &= ~MAT_DIRTY_DEPENDENTS;
2096
2097 if (ctx->Texture.Unit[i].Enabled &&
2098 ctx->TextureMatrix[i].type != MATRIX_IDENTITY)
2099 ctx->Enabled |= ENABLE_TEXMAT0 << i;
2100 }
2101 }
2102 }
2103
2104 if (ctx->NewState & (NEW_TEXTURING | NEW_TEXTURE_ENABLE)) {
2105 ctx->Texture.NeedNormals = GL_FALSE;
2106 gl_update_dirty_texobjs(ctx);
2107 ctx->Enabled &= ~(ENABLE_TEXGEN0|ENABLE_TEXGEN1);
2108 ctx->Texture.ReallyEnabled = 0;
2109
2110 for (i=0; i < MAX_TEXTURE_UNITS; i++) {
2111 if (ctx->Texture.Unit[i].Enabled) {
2112 gl_update_texture_unit( ctx, &ctx->Texture.Unit[i] );
2113
2114 ctx->Texture.ReallyEnabled |=
2115 ctx->Texture.Unit[i].ReallyEnabled<<(i*4);
2116
2117 if (ctx->Texture.Unit[i].GenFlags != 0) {
2118 ctx->Enabled |= ENABLE_TEXGEN0 << i;
2119
2120 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_NORMALS)
2121 {
2122 ctx->Texture.NeedNormals = GL_TRUE;
2123 ctx->Texture.NeedEyeCoords = GL_TRUE;
2124 }
2125
2126 if (ctx->Texture.Unit[i].GenFlags & TEXGEN_NEED_EYE_COORD)
2127 {
2128 ctx->Texture.NeedEyeCoords = GL_TRUE;
2129 }
2130 }
2131 }
2132 }
2133
2134 ctx->Texture.Enabled = ctx->Enabled & ENABLE_TEX_ANY;
2135 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2136 }
2137
2138 if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING | NEW_FOG)) {
2139
2140
2141 if (ctx->NewState & NEW_RASTER_OPS) {
2142 update_pixel_logic(ctx);
2143 update_pixel_masking(ctx);
2144 update_fog_mode(ctx);
2145 update_rasterflags(ctx);
2146 if (ctx->Driver.Dither) {
2147 (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
2148 }
2149
2150 /* Check if incoming colors can be modified during rasterization */
2151 if (ctx->Fog.Enabled ||
2152 ctx->Texture.Enabled ||
2153 ctx->Color.BlendEnabled ||
2154 ctx->Color.SWmasking ||
2155 ctx->Color.SWLogicOpEnabled) {
2156 ctx->MutablePixels = GL_TRUE;
2157 }
2158 else {
2159 ctx->MutablePixels = GL_FALSE;
2160 }
2161
2162 /* update scissor region */
2163
2164 ctx->DrawBuffer->Xmin = 0;
2165 ctx->DrawBuffer->Ymin = 0;
2166 ctx->DrawBuffer->Xmax = ctx->DrawBuffer->Width-1;
2167 ctx->DrawBuffer->Ymax = ctx->DrawBuffer->Height-1;
2168 if (ctx->Scissor.Enabled) {
2169 if (ctx->Scissor.X > ctx->DrawBuffer->Xmin) {
2170 ctx->DrawBuffer->Xmin = ctx->Scissor.X;
2171 }
2172 if (ctx->Scissor.Y > ctx->DrawBuffer->Ymin) {
2173 ctx->DrawBuffer->Ymin = ctx->Scissor.Y;
2174 }
2175 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->DrawBuffer->Xmax) {
2176 ctx->DrawBuffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
2177 }
2178 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->DrawBuffer->Ymax) {
2179 ctx->DrawBuffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
2180 }
2181 }
2182
2183 /* The driver isn't managing the depth buffer.
2184 */
2185 if (ctx->Driver.AllocDepthBuffer == gl_alloc_depth_buffer)
2186 {
2187 if (ctx->Depth.Mask) {
2188 switch (ctx->Depth.Func) {
2189 case GL_LESS:
2190 ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
2191 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
2192 break;
2193 case GL_GREATER:
2194 ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
2195 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
2196 break;
2197 default:
2198 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2199 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2200 }
2201 }
2202 else {
2203 ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
2204 ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
2205 }
2206 }
2207 }
2208
2209 if (ctx->NewState & NEW_LIGHTING) {
2210 ctx->TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2211 if (ctx->Light.Enabled) {
2212 if (ctx->Light.Model.TwoSide)
2213 ctx->TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
2214 gl_update_lighting(ctx);
2215 }
2216 }
2217 }
2218
2219 if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
2220
2221 ctx->TriangleCaps &= ~DD_TRI_CULL_FRONT_BACK;
2222
2223 if (ctx->NewState & NEW_POLYGON) {
2224 /* Setup CullBits bitmask */
2225 if (ctx->Polygon.CullFlag) {
2226 ctx->backface_sign = 1;
2227 switch(ctx->Polygon.CullFaceMode) {
2228 case GL_BACK:
2229 if(ctx->Polygon.FrontFace==GL_CCW)
2230 ctx->backface_sign = -1;
2231 ctx->Polygon.CullBits = 1;
2232 break;
2233 case GL_FRONT:
2234 if(ctx->Polygon.FrontFace!=GL_CCW)
2235 ctx->backface_sign = -1;
2236 ctx->Polygon.CullBits = 2;
2237 break;
2238 default:
2239 case GL_FRONT_AND_BACK:
2240 ctx->backface_sign = 0;
2241 ctx->Polygon.CullBits = 0;
2242 ctx->TriangleCaps |= DD_TRI_CULL_FRONT_BACK;
2243 break;
2244 }
2245 }
2246 else {
2247 ctx->Polygon.CullBits = 3;
2248 ctx->backface_sign = 0;
2249 }
2250
2251 /* Any Polygon offsets enabled? */
2252 ctx->TriangleCaps &= ~DD_TRI_OFFSET;
2253
2254 if (ctx->Polygon.OffsetPoint ||
2255 ctx->Polygon.OffsetLine ||
2256 ctx->Polygon.OffsetFill)
2257 ctx->TriangleCaps |= DD_TRI_OFFSET;
2258
2259 /* reset Z offsets now */
2260 ctx->PointZoffset = 0.0;
2261 ctx->LineZoffset = 0.0;
2262 ctx->PolygonZoffset = 0.0;
2263 }
2264 }
2265
2266 if (ctx->NewState & ~(NEW_CLIENT_STATE|
2267 NEW_DRIVER_STATE|NEW_USER_CLIP|
2268 NEW_POLYGON))
2269 gl_update_clipmask(ctx);
2270
2271 if (ctx->NewState & (NEW_LIGHTING|
2272 NEW_RASTER_OPS|
2273 NEW_TEXTURING|
2274 NEW_TEXTURE_ENABLE|
2275 NEW_TEXTURE_ENV|
2276 NEW_POLYGON|
2277 NEW_DRVSTATE0|
2278 NEW_DRVSTATE1|
2279 NEW_DRVSTATE2|
2280 NEW_DRVSTATE3|
2281 NEW_USER_CLIP))
2282 {
2283 ctx->IndirectTriangles = ctx->TriangleCaps & ~ctx->Driver.TriangleCaps;
2284 ctx->IndirectTriangles |= DD_SW_RASTERIZE;
2285
2286 if (MESA_VERBOSE&VERBOSE_CULL)
2287 gl_print_tri_caps("initial indirect tris", ctx->IndirectTriangles);
2288
2289 ctx->Driver.PointsFunc = NULL;
2290 ctx->Driver.LineFunc = NULL;
2291 ctx->Driver.TriangleFunc = NULL;
2292 ctx->Driver.QuadFunc = NULL;
2293 ctx->Driver.RectFunc = NULL;
2294 ctx->Driver.RenderVBClippedTab = NULL;
2295 ctx->Driver.RenderVBCulledTab = NULL;
2296 ctx->Driver.RenderVBRawTab = NULL;
2297
2298 /*
2299 * Here the driver sets up all the ctx->Driver function pointers to
2300 * it's specific, private functions.
2301 */
2302 ctx->Driver.UpdateState(ctx);
2303
2304 if (MESA_VERBOSE&VERBOSE_CULL)
2305 gl_print_tri_caps("indirect tris", ctx->IndirectTriangles);
2306
2307 /*
2308 * In case the driver didn't hook in an optimized point, line or
2309 * triangle function we'll now select "core/fallback" point, line
2310 * and triangle functions.
2311 */
2312 if (ctx->IndirectTriangles & DD_SW_RASTERIZE) {
2313 gl_set_point_function(ctx);
2314 gl_set_line_function(ctx);
2315 gl_set_triangle_function(ctx);
2316 gl_set_quad_function(ctx);
2317
2318 if ((ctx->IndirectTriangles &
2319 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL)) ==
2320 (DD_TRI_SW_RASTERIZE|DD_QUAD_SW_RASTERIZE|DD_TRI_CULL))
2321 ctx->IndirectTriangles &= ~DD_TRI_CULL;
2322 }
2323
2324 if (MESA_VERBOSE&VERBOSE_CULL)
2325 gl_print_tri_caps("indirect tris 2", ctx->IndirectTriangles);
2326
2327 gl_set_render_vb_function(ctx);
2328 }
2329
2330 /* Should only be calc'd when !need_eye_coords and not culling.
2331 */
2332 if (ctx->NewState & (NEW_MODELVIEW|NEW_PROJECTION)) {
2333 if (ctx->NewState & NEW_MODELVIEW) {
2334 gl_matrix_analyze( &ctx->ModelView );
2335 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2336 }
2337
2338 if (ctx->NewState & NEW_PROJECTION) {
2339 gl_matrix_analyze( &ctx->ProjectionMatrix );
2340 ctx->ProjectionMatrix.flags &= ~MAT_DIRTY_DEPENDENTS;
2341
2342 if (ctx->Transform.AnyClip) {
2343 gl_update_userclip( ctx );
2344 }
2345 }
2346
2347 gl_calculate_model_project_matrix( ctx );
2348 ctx->ModelProjectWinMatrixUptodate = 0;
2349 }
2350
2351 /* Figure out whether we can light in object space or not. If we
2352 * can, find the current positions of the lights in object space
2353 */
2354 if ((ctx->Enabled & (ENABLE_POINT_ATTEN | ENABLE_LIGHT | ENABLE_FOG |
2355 ENABLE_TEXGEN0 | ENABLE_TEXGEN1)) &&
2356 (ctx->NewState & (NEW_LIGHTING |
2357 NEW_FOG |
2358 NEW_MODELVIEW |
2359 NEW_PROJECTION |
2360 NEW_TEXTURING |
2361 NEW_RASTER_OPS |
2362 NEW_USER_CLIP)))
2363 {
2364 GLboolean oldcoord, oldnorm;
2365
2366 oldcoord = ctx->NeedEyeCoords;
2367 oldnorm = ctx->NeedEyeNormals;
2368
2369 ctx->NeedNormals = (ctx->Light.Enabled || ctx->Texture.NeedNormals);
2370 ctx->NeedEyeCoords = ((ctx->Fog.Enabled && ctx->Hint.Fog != GL_NICEST) ||
2371 ctx->Point.Attenuated);
2372 ctx->NeedEyeNormals = GL_FALSE;
2373
2374 if (ctx->Light.Enabled) {
2375 if (ctx->Light.Flags & LIGHT_POSITIONAL) {
2376 /* Need length for attenuation */
2377 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING))
2378 ctx->NeedEyeCoords = GL_TRUE;
2379 } else if (ctx->Light.NeedVertices) {
2380 /* Need angle for spot calculations */
2381 if (!TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_ANGLE_PRESERVING))
2382 ctx->NeedEyeCoords = GL_TRUE;
2383 }
2384 ctx->NeedEyeNormals = ctx->NeedEyeCoords;
2385 }
2386 if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
2387 if (ctx->Texture.NeedEyeCoords) ctx->NeedEyeCoords = GL_TRUE;
2388 if (ctx->Texture.NeedNormals)
2389 ctx->NeedNormals = ctx->NeedEyeNormals = GL_TRUE;
2390 }
2391
2392 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
2393
2394 if (ctx->NeedEyeCoords)
2395 ctx->vb_proj_matrix = &ctx->ProjectionMatrix;
2396
2397 if (ctx->Light.Enabled) {
2398 gl_update_lighting_function(ctx);
2399
2400 if ( (ctx->NewState & NEW_LIGHTING) ||
2401 ((ctx->NewState & (NEW_MODELVIEW| NEW_PROJECTION)) &&
2402 !ctx->NeedEyeCoords) ||
2403 oldcoord != ctx->NeedEyeCoords ||
2404 oldnorm != ctx->NeedEyeNormals) {
2405 gl_compute_light_positions(ctx);
2406 }
2407
2408 ctx->rescale_factor = 1.0F;
2409
2410 if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE |
2411 MAT_FLAG_GENERAL_SCALE |
2412 MAT_FLAG_GENERAL_3D |
2413 MAT_FLAG_GENERAL) )
2414
2415 {
2416 GLfloat *m = ctx->ModelView.inv;
2417 GLfloat f = m[2]*m[2] + m[6]*m[6] + m[10]*m[10];
2418 if (f > 1e-12 && (f-1)*(f-1) > 1e-12)
2419 ctx->rescale_factor = 1.0/GL_SQRT(f);
2420 }
2421 }
2422
2423 gl_update_normal_transform( ctx );
2424 }
2425
2426 gl_update_pipelines(ctx);
2427 ctx->NewState = 0;
2428 }