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