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