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