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