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