xref: /reactos/dll/opengl/mesa/context.c (revision 1734f297)
1 /* $Id: context.c,v 1.64 1998/02/05 00:34:56 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version:  2.6
6  * Copyright (C) 1995-1997  Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: context.c,v $
26  * Revision 1.64  1998/02/05 00:34:56  brianp
27  * added John Stone's initial thread modifications
28  *
29  * Revision 1.63  1998/01/06 02:40:52  brianp
30  * added DavidB's clipping interpolation optimization
31  *
32  * Revision 1.62  1997/12/31 06:10:03  brianp
33  * added Henk Kok's texture validation optimization (AnyDirty flag)
34  *
35  * Revision 1.61  1997/12/08 04:04:52  brianp
36  * changed gl_copy_context() to not use MEMCPY for PolygonStipple (John Stone)
37  *
38  * Revision 1.60  1997/12/06 18:06:50  brianp
39  * moved several static display list vars into GLcontext
40  *
41  * Revision 1.59  1997/11/25 03:37:53  brianp
42  * simple clean-ups for multi-threading (John Stone)
43  *
44  * Revision 1.58  1997/10/29 01:29:09  brianp
45  * added GL_EXT_point_parameters extension from Daniel Barrero
46  *
47  * Revision 1.57  1997/10/16 01:59:08  brianp
48  * added GL_EXT_shared_texture_palette extension
49  *
50  * Revision 1.56  1997/10/15 03:08:50  brianp
51  * don't clear depth buffer in gl_ResizeBuffersMESA()
52  *
53  * Revision 1.55  1997/09/29 22:25:28  brianp
54  * added const to a few function parameters
55  *
56  * Revision 1.54  1997/09/27 00:15:20  brianp
57  * added ctx->DirectContext flag
58  *
59  * Revision 1.53  1997/09/23 00:58:15  brianp
60  * now using hash table for texture objects
61  *
62  * Revision 1.52  1997/09/22 02:33:58  brianp
63  * display lists now implemented with hash table
64  *
65  * Revision 1.51  1997/09/17 01:39:11  brianp
66  * added update_clipmask() function from Michael Pichler
67  *
68  * Revision 1.50  1997/09/10 00:29:19  brianp
69  * set all NewState flags in gl_ResizeBuffersMESA() (Miklos Fazekas)
70  *
71  * Revision 1.49  1997/07/24 01:24:45  brianp
72  * changed precompiled header symbol from PCH to PC_HEADER
73  *
74  * Revision 1.48  1997/06/20 02:19:49  brianp
75  * replaced Current.IntColor with Current.ByteColor
76  *
77  * Revision 1.47  1997/06/20 01:57:28  brianp
78  * free_shared_state() didn't free display lists
79  *
80  * Revision 1.46  1997/05/31 16:57:14  brianp
81  * added MESA_NO_RASTER env var support
82  *
83  * Revision 1.45  1997/05/28 04:06:03  brianp
84  * implemented projection near/far value stack for Driver.NearFar() function
85  *
86  * Revision 1.44  1997/05/28 03:23:48  brianp
87  * added precompiled header (PCH) support
88  *
89  * Revision 1.43  1997/05/26 21:18:54  brianp
90  * better comments
91  *
92  * Revision 1.42  1997/05/26 21:14:13  brianp
93  * gl_create_visual() now takes red/green/blue/alpha_bits arguments
94  *
95  * Revision 1.41  1997/05/24 12:07:07  brianp
96  * removed unused vars
97  *
98  * Revision 1.40  1997/05/14 03:27:24  brianp
99  * miscellaneous alloc/free clean-ups
100  *
101  * Revision 1.39  1997/05/09 22:42:09  brianp
102  * replaced gl_init_vb() with gl_alloc_vb(), similarly for pb
103  *
104  * Revision 1.38  1997/05/01 02:07:35  brianp
105  * added shared state variable NextFreeTextureName
106  *
107  * Revision 1.37  1997/05/01 01:25:33  brianp
108  * added call to gl_init_math()
109  *
110  * Revision 1.36  1997/04/28 02:06:14  brianp
111  * also check if texturing enabled in the test for NeedNormals
112  *
113  * Revision 1.35  1997/04/26 04:34:43  brianp
114  * fixed problem with Depth/Accum/StencilBits initialization (Mark Kilgard)
115  *
116  * Revision 1.34  1997/04/24 01:49:02  brianp
117  * call gl_set_color_function() instead of directly setting pointers
118  *
119  * Revision 1.33  1997/04/24 00:18:10  brianp
120  * Proxy2D tex object was allocated twice.  reported by Randy Frank.
121  *
122  * Revision 1.32  1997/04/16 23:55:06  brianp
123  * added gl_set_api_table()
124  *
125  * Revision 1.31  1997/04/14 02:01:03  brianp
126  * #include "texstate.h" instead of "texture.h"
127  *
128  * Revision 1.30  1997/04/12 17:11:38  brianp
129  * added gl_get_current_context()
130  *
131  * Revision 1.29  1997/04/12 16:54:05  brianp
132  * new NEW_POLYGON state flag
133  *
134  * Revision 1.28  1997/04/12 16:20:51  brianp
135  * added call to Driver.Dither() in gl_update_state()
136  *
137  * Revision 1.27  1997/04/12 12:25:37  brianp
138  * added Driver.QuadFunc and Driver.RectFunc
139  *
140  * Revision 1.26  1997/04/01 04:20:22  brianp
141  * added new matrix type code
142  *
143  * Revision 1.25  1997/03/14 00:24:37  brianp
144  * only print runtime warnings if MESA_DEBUG env var is set
145  *
146  * Revision 1.24  1997/03/13 03:06:14  brianp
147  * init AlphaRefUbyte to zero
148  *
149  * Revision 1.23  1997/03/08 01:59:00  brianp
150  * if RenderMode != GL_RENDER then don't enable ctx->DirectTriangles
151  *
152  * Revision 1.22  1997/02/27 19:57:38  brianp
153  * added gl_problem() function
154  *
155  * Revision 1.21  1997/02/10 19:49:50  brianp
156  * added gl_ResizeBuffersMESA()
157  *
158  * Revision 1.20  1997/02/10 19:22:47  brianp
159  * added device driver Error() function
160  *
161  * Revision 1.19  1997/02/09 18:50:05  brianp
162  * added GL_EXT_texture3D support
163  *
164  * Revision 1.18  1997/01/28 22:15:14  brianp
165  * now there's separate state for CI and RGBA logic op enabled
166  *
167  * Revision 1.17  1997/01/09 19:56:09  brianp
168  * new error message format in gl_error()
169  *
170  * Revision 1.16  1997/01/09 19:47:32  brianp
171  * better checking and handling of out-of-memory errors
172  *
173  * Revision 1.15  1996/12/18 20:00:12  brianp
174  * added code to initialize ColorMaterialBitmask
175  *
176  * Revision 1.14  1996/12/11 20:18:53  brianp
177  * changed formatting of messages in gl_warning()
178  *
179  * Revision 1.13  1996/11/08 02:20:52  brianp
180  * added check for MESA_NO_RASTER env var
181  *
182  * Revision 1.12  1996/11/04 02:18:47  brianp
183  * multiply Viewport.Sz and .Tz by DEPTH_SCALE
184  *
185  * Revision 1.11  1996/10/16 00:52:22  brianp
186  * gl_initialize_api_function_pointers() now gl_init_api_function_pointers()
187  *
188  * Revision 1.10  1996/10/11 03:41:28  brianp
189  * removed Polygon.OffsetBias initialization
190  *
191  * Revision 1.9  1996/10/11 00:26:34  brianp
192  * initialize Point/Line/PolygonZoffset to 0.0
193  *
194  * Revision 1.8  1996/10/01 01:42:31  brianp
195  * moved device driver initialization into gl_update_state()
196  *
197  * Revision 1.7  1996/09/27 01:24:33  brianp
198  * removed unneeded set_thread_context(), added call to gl_init_vb()
199  *
200  * Revision 1.6  1996/09/25 03:22:53  brianp
201  * added NO_DRAW_BIT for glDrawBuffer(GL_NONE)
202  *
203  * Revision 1.5  1996/09/20 02:55:52  brianp
204  * fixed profiling bug
205  *
206  * Revision 1.4  1996/09/19 03:14:49  brianp
207  * now just one parameter for gl_create_framebuffer()
208  *
209  * Revision 1.3  1996/09/15 14:20:22  brianp
210  * added new functions for GLframebuffer and GLvisual support
211  *
212  * Revision 1.2  1996/09/14 20:12:05  brianp
213  * wasn't initializing a few pieces of context state
214  *
215  * Revision 1.1  1996/09/13 01:38:16  brianp
216  * Initial revision
217  *
218  */
219 
220 
221 /*
222  * If multi-threading is enabled (-DTHREADS) then each thread has it's
223  * own rendering context.  A thread obtains the pointer to its GLcontext
224  * with the gl_get_thread_context() function.  Otherwise, the global
225  * pointer, CC, points to the current context used by all threads in
226  * the address space.
227  */
228 
229 
230 #ifdef PC_HEADER
231 #include "all.h"
232 #else
233 #include <assert.h>
234 #include <math.h>
235 #include <stdio.h>
236 #include <stdlib.h>
237 #include <string.h>
238 #include "accum.h"
239 #include "alphabuf.h"
240 #include "clip.h"
241 #include "context.h"
242 #include "depth.h"
243 #include "eval.h"
244 #include "hash.h"
245 #include "light.h"
246 #include "lines.h"
247 #include "dlist.h"
248 #include "macros.h"
249 #include "mmath.h"
250 #include "pb.h"
251 #include "points.h"
252 #include "pointers.h"
253 #include "quads.h"
254 #include "stencil.h"
255 #include "triangle.h"
256 #include "teximage.h"
257 #include "texobj.h"
258 #include "texstate.h"
259 #include "types.h"
260 #include "vb.h"
261 #include "vbfill.h"
262 #endif
263 
264 #include <wine/debug.h>
265 WINE_DEFAULT_DEBUG_CHANNEL(opengl32);
266 
267 
268 
269 /**********************************************************************/
270 /*****                  Context and Thread management             *****/
271 /**********************************************************************/
272 
273 
274 
275 
276 /**********************************************************************/
277 /*****                   Profiling functions                      *****/
278 /**********************************************************************/
279 
280 #ifdef PROFILE
281 
282 #include <sys/times.h>
283 #include <sys/param.h>
284 
285 
286 /*
287  * Return system time in seconds.
288  * NOTE:  this implementation may not be very portable!
289  */
290 GLdouble gl_time( void )
291 {
292    static GLdouble prev_time = 0.0;
293    static GLdouble time;
294    struct tms tm;
295    clock_t clk;
296 
297    clk = times(&tm);
298 
299 #ifdef CLK_TCK
300    time = (double)clk / (double)CLK_TCK;
301 #else
302    time = (double)clk / (double)HZ;
303 #endif
304 
305    if (time>prev_time) {
306       prev_time = time;
307       return time;
308    }
309    else {
310       return prev_time;
311    }
312 }
313 
314 
315 
316 /*
317  * Reset the timing/profiling counters
318  */
319 static void init_timings( GLcontext *ctx )
320 {
321    ctx->BeginEndCount = 0;
322    ctx->BeginEndTime = 0.0;
323    ctx->VertexCount = 0;
324    ctx->VertexTime = 0.0;
325    ctx->PointCount = 0;
326    ctx->PointTime = 0.0;
327    ctx->LineCount = 0;
328    ctx->LineTime = 0.0;
329    ctx->PolygonCount = 0;
330    ctx->PolygonTime = 0.0;
331    ctx->ClearCount = 0;
332    ctx->ClearTime = 0.0;
333    ctx->SwapCount = 0;
334    ctx->SwapTime = 0.0;
335 }
336 
337 
338 
339 /*
340  * Print the accumulated timing/profiling data.
341  */
342 static void print_timings( GLcontext *ctx )
343 {
344    GLdouble beginendrate;
345    GLdouble vertexrate;
346    GLdouble pointrate;
347    GLdouble linerate;
348    GLdouble polygonrate;
349    GLdouble overhead;
350    GLdouble clearrate;
351    GLdouble swaprate;
352    GLdouble avgvertices;
353 
354    if (ctx->BeginEndTime>0.0) {
355       beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
356    }
357    else {
358       beginendrate = 0.0;
359    }
360    if (ctx->VertexTime>0.0) {
361       vertexrate = ctx->VertexCount / ctx->VertexTime;
362    }
363    else {
364       vertexrate = 0.0;
365    }
366    if (ctx->PointTime>0.0) {
367       pointrate = ctx->PointCount / ctx->PointTime;
368    }
369    else {
370       pointrate = 0.0;
371    }
372    if (ctx->LineTime>0.0) {
373       linerate = ctx->LineCount / ctx->LineTime;
374    }
375    else {
376       linerate = 0.0;
377    }
378    if (ctx->PolygonTime>0.0) {
379       polygonrate = ctx->PolygonCount / ctx->PolygonTime;
380    }
381    else {
382       polygonrate = 0.0;
383    }
384    if (ctx->ClearTime>0.0) {
385       clearrate = ctx->ClearCount / ctx->ClearTime;
386    }
387    else {
388       clearrate = 0.0;
389    }
390    if (ctx->SwapTime>0.0) {
391       swaprate = ctx->SwapCount / ctx->SwapTime;
392    }
393    else {
394       swaprate = 0.0;
395    }
396 
397    if (ctx->BeginEndCount>0) {
398       avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
399    }
400    else {
401       avgvertices = 0.0;
402    }
403 
404    overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
405               - ctx->LineTime - ctx->PolygonTime;
406 
407 
408    printf("                          Count   Time (s)    Rate (/s) \n");
409    printf("--------------------------------------------------------\n");
410    printf("glBegin/glEnd           %7d  %8.3f   %10.3f\n",
411           ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
412    printf("  vertexes transformed  %7d  %8.3f   %10.3f\n",
413           ctx->VertexCount, ctx->VertexTime, vertexrate );
414    printf("  points rasterized     %7d  %8.3f   %10.3f\n",
415           ctx->PointCount, ctx->PointTime, pointrate );
416    printf("  lines rasterized      %7d  %8.3f   %10.3f\n",
417           ctx->LineCount, ctx->LineTime, linerate );
418    printf("  polygons rasterized   %7d  %8.3f   %10.3f\n",
419           ctx->PolygonCount, ctx->PolygonTime, polygonrate );
420    printf("  overhead                       %8.3f\n", overhead );
421    printf("glClear                 %7d  %8.3f   %10.3f\n",
422           ctx->ClearCount, ctx->ClearTime, clearrate );
423    printf("SwapBuffers             %7d  %8.3f   %10.3f\n",
424           ctx->SwapCount, ctx->SwapTime, swaprate );
425    printf("\n");
426 
427    printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
428 }
429 #endif
430 
431 
432 
433 
434 
435 /**********************************************************************/
436 /*****       Context allocation, initialization, destroying       *****/
437 /**********************************************************************/
438 
439 
440 /*
441  * Allocate and initialize a shared context state structure.
442  */
443 static struct gl_shared_state *alloc_shared_state( void )
444 {
445    struct gl_shared_state *ss;
446 
447    ss = (struct gl_shared_state*) calloc( 1, sizeof(struct gl_shared_state) );
448    if (!ss)
449       return NULL;
450 
451    ss->DisplayList = NewHashTable();
452 
453    ss->TexObjects = NewHashTable();
454 
455    /* Default Texture objects */
456    ss->Default1D = gl_alloc_texture_object(ss, 0, 1);
457    ss->Default2D = gl_alloc_texture_object(ss, 0, 2);
458 
459    if (!ss->DisplayList || !ss->TexObjects
460        || !ss->Default1D || !ss->Default2D) {
461       /* Ran out of memory at some point.  Free everything and return NULL */
462       if (!ss->DisplayList)
463          DeleteHashTable(ss->DisplayList);
464       if (!ss->TexObjects)
465          DeleteHashTable(ss->TexObjects);
466       if (!ss->Default1D)
467          gl_free_texture_object(ss, ss->Default1D);
468       if (!ss->Default2D)
469          gl_free_texture_object(ss, ss->Default2D);
470       free(ss);
471       return NULL;
472    }
473    else {
474       return ss;
475    }
476 }
477 
478 
479 /*
480  * Deallocate a shared state context and all children structures.
481  */
482 static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
483 {
484    /* Free display lists */
485    while (1) {
486       GLuint list = HashFirstEntry(ss->DisplayList);
487       if (list) {
488          gl_destroy_list(ctx, list);
489       }
490       else {
491          break;
492       }
493    }
494    DeleteHashTable(ss->DisplayList);
495 
496    /* Free texture objects */
497    while (ss->TexObjectList)
498    {
499       /* this function removes from linked list too! */
500       gl_free_texture_object(ss, ss->TexObjectList);
501    }
502    DeleteHashTable(ss->TexObjects);
503 
504    free(ss);
505 }
506 
507 
508 
509 
510 /*
511  * Initialize the nth light.  Note that the defaults for light 0 are
512  * different than the other lights.
513  */
514 static void init_light( struct gl_light *l, GLuint n )
515 {
516    ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
517    if (n==0) {
518       ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
519       ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
520    }
521    else {
522       ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
523       ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
524    }
525    ASSIGN_4V( l->Position, 0.0, 0.0, 1.0, 0.0 );
526    ASSIGN_3V( l->Direction, 0.0, 0.0, -1.0 );
527    l->SpotExponent = 0.0;
528    gl_compute_spot_exp_table( l );
529    l->SpotCutoff = 180.0;
530    l->CosCutoff = -1.0;
531    l->ConstantAttenuation = 1.0;
532    l->LinearAttenuation = 0.0;
533    l->QuadraticAttenuation = 0.0;
534    l->Enabled = GL_FALSE;
535 }
536 
537 
538 
539 static void init_lightmodel( struct gl_lightmodel *lm )
540 {
541    ASSIGN_4V( lm->Ambient, 0.2f, 0.2f, 0.2f, 1.0f );
542    lm->LocalViewer = GL_FALSE;
543    lm->TwoSide = GL_FALSE;
544 }
545 
546 
547 static void init_material( struct gl_material *m )
548 {
549    ASSIGN_4V( m->Ambient,  0.2f, 0.2f, 0.2f, 1.0f );
550    ASSIGN_4V( m->Diffuse,  0.8f, 0.8f, 0.8f, 1.0f );
551    ASSIGN_4V( m->Specular, 0.0f, 0.0f, 0.0f, 1.0f );
552    ASSIGN_4V( m->Emission, 0.0f, 0.0f, 0.0f, 1.0f );
553    m->Shininess = 0.0;
554    m->AmbientIndex = 0;
555    m->DiffuseIndex = 1;
556    m->SpecularIndex = 1;
557    gl_compute_material_shine_table( m );
558 }
559 
560 
561 
562 /*
563  * Initialize a gl_context structure to default values.
564  */
565 static void initialize_context( GLcontext *ctx )
566 {
567    static GLfloat identity[16] = {
568 	1.0, 0.0, 0.0, 0.0,
569 	0.0, 1.0, 0.0, 0.0,
570 	0.0, 0.0, 1.0, 0.0,
571 	0.0, 0.0, 0.0, 1.0
572    };
573    GLuint i;
574 
575    if (ctx) {
576       /* Modelview matrix stuff */
577       ctx->NewModelViewMatrix = GL_FALSE;
578       ctx->ModelViewMatrixType = MATRIX_IDENTITY;
579       MEMCPY( ctx->ModelViewMatrix, identity, 16*sizeof(GLfloat) );
580       MEMCPY( ctx->ModelViewInv, identity, 16*sizeof(GLfloat) );
581       ctx->ModelViewStackDepth = 0;
582 
583       /* Projection matrix stuff */
584       ctx->NewProjectionMatrix = GL_FALSE;
585       ctx->ProjectionMatrixType = MATRIX_IDENTITY;
586       MEMCPY( ctx->ProjectionMatrix, identity, 16*sizeof(GLfloat) );
587       ctx->ProjectionStackDepth = 0;
588       ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
589       ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
590 
591       /* Texture matrix stuff */
592       ctx->NewTextureMatrix = GL_FALSE;
593       ctx->TextureMatrixType = MATRIX_IDENTITY;
594       MEMCPY( ctx->TextureMatrix, identity, 16*sizeof(GLfloat) );
595       ctx->TextureStackDepth = 0;
596 
597       /* Accumulate buffer group */
598       ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
599 
600       /* Color buffer group */
601       ctx->Color.IndexMask = 0xffffffff;
602       ctx->Color.ColorMask = 0xf;
603       ctx->Color.SWmasking = GL_FALSE;
604       ctx->Color.ClearIndex = 0;
605       ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
606       ctx->Color.DrawBuffer = GL_FRONT;
607       ctx->Color.AlphaEnabled = GL_FALSE;
608       ctx->Color.AlphaFunc = GL_ALWAYS;
609       ctx->Color.AlphaRef = 0.0;
610       ctx->Color.AlphaRefUbyte = 0;
611       ctx->Color.BlendEnabled = GL_FALSE;
612       ctx->Color.BlendSrc = GL_ONE;
613       ctx->Color.BlendDst = GL_ZERO;
614       ctx->Color.IndexLogicOpEnabled = GL_FALSE;
615       ctx->Color.ColorLogicOpEnabled = GL_FALSE;
616       ctx->Color.SWLogicOpEnabled = GL_FALSE;
617       ctx->Color.LogicOp = GL_COPY;
618       ctx->Color.DitherFlag = GL_TRUE;
619 
620       /* Current group */
621       ctx->Current.Index = 1;
622       ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
623       ctx->Current.ByteColor[0] = (GLint) ctx->Visual->RedScale;
624       ctx->Current.ByteColor[1] = (GLint) ctx->Visual->GreenScale;
625       ctx->Current.ByteColor[2] = (GLint) ctx->Visual->BlueScale;
626       ctx->Current.ByteColor[3] = (GLint) ctx->Visual->AlphaScale;
627       ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
628       ctx->Current.RasterPosValid = GL_TRUE;
629       ctx->Current.RasterIndex = 1;
630       ASSIGN_4V( ctx->Current.TexCoord, 0.0, 0.0, 0.0, 1.0 );
631       ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
632       ctx->Current.EdgeFlag = GL_TRUE;
633 
634       /* Depth buffer group */
635       ctx->Depth.Test = GL_FALSE;
636       ctx->Depth.Clear = 1.0;
637       ctx->Depth.Func = GL_LESS;
638       ctx->Depth.Mask = GL_TRUE;
639 
640       /* Evaluators group */
641       ctx->Eval.Map1Color4 = GL_FALSE;
642       ctx->Eval.Map1Index = GL_FALSE;
643       ctx->Eval.Map1Normal = GL_FALSE;
644       ctx->Eval.Map1TextureCoord1 = GL_FALSE;
645       ctx->Eval.Map1TextureCoord2 = GL_FALSE;
646       ctx->Eval.Map1TextureCoord3 = GL_FALSE;
647       ctx->Eval.Map1TextureCoord4 = GL_FALSE;
648       ctx->Eval.Map1Vertex3 = GL_FALSE;
649       ctx->Eval.Map1Vertex4 = GL_FALSE;
650       ctx->Eval.Map2Color4 = GL_FALSE;
651       ctx->Eval.Map2Index = GL_FALSE;
652       ctx->Eval.Map2Normal = GL_FALSE;
653       ctx->Eval.Map2TextureCoord1 = GL_FALSE;
654       ctx->Eval.Map2TextureCoord2 = GL_FALSE;
655       ctx->Eval.Map2TextureCoord3 = GL_FALSE;
656       ctx->Eval.Map2TextureCoord4 = GL_FALSE;
657       ctx->Eval.Map2Vertex3 = GL_FALSE;
658       ctx->Eval.Map2Vertex4 = GL_FALSE;
659       ctx->Eval.AutoNormal = GL_FALSE;
660       ctx->Eval.MapGrid1un = 1;
661       ctx->Eval.MapGrid1u1 = 0.0;
662       ctx->Eval.MapGrid1u2 = 1.0;
663       ctx->Eval.MapGrid2un = 1;
664       ctx->Eval.MapGrid2vn = 1;
665       ctx->Eval.MapGrid2u1 = 0.0;
666       ctx->Eval.MapGrid2u2 = 1.0;
667       ctx->Eval.MapGrid2v1 = 0.0;
668       ctx->Eval.MapGrid2v2 = 1.0;
669 
670       /* Fog group */
671       ctx->Fog.Enabled = GL_FALSE;
672       ctx->Fog.Mode = GL_EXP;
673       ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
674       ctx->Fog.Index = 0.0;
675       ctx->Fog.Density = 1.0;
676       ctx->Fog.Start = 0.0;
677       ctx->Fog.End = 1.0;
678 
679       /* Hint group */
680       ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
681       ctx->Hint.PointSmooth = GL_DONT_CARE;
682       ctx->Hint.LineSmooth = GL_DONT_CARE;
683       ctx->Hint.PolygonSmooth = GL_DONT_CARE;
684       ctx->Hint.Fog = GL_DONT_CARE;
685 
686       /* Lighting group */
687       for (i=0;i<MAX_LIGHTS;i++) {
688 	 init_light( &ctx->Light.Light[i], i );
689       }
690       init_lightmodel( &ctx->Light.Model );
691       init_material( &ctx->Light.Material[0] );
692       init_material( &ctx->Light.Material[1] );
693       ctx->Light.ShadeModel = GL_SMOOTH;
694       ctx->Light.Enabled = GL_FALSE;
695       ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
696       ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
697       ctx->Light.ColorMaterialBitmask
698          = gl_material_bitmask( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
699 
700       ctx->Light.ColorMaterialEnabled = GL_FALSE;
701 
702       /* Line group */
703       ctx->Line.SmoothFlag = GL_FALSE;
704       ctx->Line.StippleFlag = GL_FALSE;
705       ctx->Line.Width = 1.0;
706       ctx->Line.StipplePattern = 0xffff;
707       ctx->Line.StippleFactor = 1;
708 
709       /* Display List group */
710       ctx->List.ListBase = 0;
711 
712       /* Pixel group */
713       ctx->Pixel.RedBias = 0.0;
714       ctx->Pixel.RedScale = 1.0;
715       ctx->Pixel.GreenBias = 0.0;
716       ctx->Pixel.GreenScale = 1.0;
717       ctx->Pixel.BlueBias = 0.0;
718       ctx->Pixel.BlueScale = 1.0;
719       ctx->Pixel.AlphaBias = 0.0;
720       ctx->Pixel.AlphaScale = 1.0;
721       ctx->Pixel.DepthBias = 0.0;
722       ctx->Pixel.DepthScale = 1.0;
723       ctx->Pixel.IndexOffset = 0;
724       ctx->Pixel.IndexShift = 0;
725       ctx->Pixel.ZoomX = 1.0;
726       ctx->Pixel.ZoomY = 1.0;
727       ctx->Pixel.MapColorFlag = GL_FALSE;
728       ctx->Pixel.MapStencilFlag = GL_FALSE;
729       ctx->Pixel.MapStoSsize = 1;
730       ctx->Pixel.MapItoIsize = 1;
731       ctx->Pixel.MapItoRsize = 1;
732       ctx->Pixel.MapItoGsize = 1;
733       ctx->Pixel.MapItoBsize = 1;
734       ctx->Pixel.MapItoAsize = 1;
735       ctx->Pixel.MapRtoRsize = 1;
736       ctx->Pixel.MapGtoGsize = 1;
737       ctx->Pixel.MapBtoBsize = 1;
738       ctx->Pixel.MapAtoAsize = 1;
739       ctx->Pixel.MapStoS[0] = 0;
740       ctx->Pixel.MapItoI[0] = 0;
741       ctx->Pixel.MapItoR[0] = 0.0;
742       ctx->Pixel.MapItoG[0] = 0.0;
743       ctx->Pixel.MapItoB[0] = 0.0;
744       ctx->Pixel.MapItoA[0] = 0.0;
745       ctx->Pixel.MapRtoR[0] = 0.0;
746       ctx->Pixel.MapGtoG[0] = 0.0;
747       ctx->Pixel.MapBtoB[0] = 0.0;
748       ctx->Pixel.MapAtoA[0] = 0.0;
749 
750       /* Point group */
751       ctx->Point.SmoothFlag = GL_FALSE;
752       ctx->Point.Size = 1.0;
753 
754       /* Polygon group */
755       ctx->Polygon.CullFlag = GL_FALSE;
756       ctx->Polygon.CullFaceMode = GL_BACK;
757       ctx->Polygon.FrontFace = GL_CCW;
758       ctx->Polygon.FrontMode = GL_FILL;
759       ctx->Polygon.BackMode = GL_FILL;
760       ctx->Polygon.Unfilled = GL_FALSE;
761       ctx->Polygon.SmoothFlag = GL_FALSE;
762       ctx->Polygon.StippleFlag = GL_FALSE;
763       ctx->Polygon.OffsetFactor = 0.0F;
764       ctx->Polygon.OffsetUnits = 0.0F;
765       ctx->Polygon.OffsetPoint = GL_FALSE;
766       ctx->Polygon.OffsetLine = GL_FALSE;
767       ctx->Polygon.OffsetFill = GL_FALSE;
768       ctx->Polygon.OffsetAny = GL_FALSE;
769 
770       /* Polygon Stipple group */
771       MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
772 
773       /* Scissor group */
774       ctx->Scissor.Enabled = GL_FALSE;
775       ctx->Scissor.X = 0;
776       ctx->Scissor.Y = 0;
777       ctx->Scissor.Width = 0;
778       ctx->Scissor.Height = 0;
779 
780       /* Stencil group */
781       ctx->Stencil.Enabled = GL_FALSE;
782       ctx->Stencil.Function = GL_ALWAYS;
783       ctx->Stencil.FailFunc = GL_KEEP;
784       ctx->Stencil.ZPassFunc = GL_KEEP;
785       ctx->Stencil.ZFailFunc = GL_KEEP;
786       ctx->Stencil.Ref = 0;
787       ctx->Stencil.ValueMask = 0xff;
788       ctx->Stencil.Clear = 0;
789       ctx->Stencil.WriteMask = 0xff;
790 
791       /* Texture group */
792       ctx->Texture.Enabled = 0;
793       ctx->Texture.EnvMode = GL_MODULATE;
794       ASSIGN_4V( ctx->Texture.EnvColor, 0.0, 0.0, 0.0, 0.0 );
795       ctx->Texture.TexGenEnabled = 0;
796       ctx->Texture.GenModeS = GL_EYE_LINEAR;
797       ctx->Texture.GenModeT = GL_EYE_LINEAR;
798       ctx->Texture.GenModeR = GL_EYE_LINEAR;
799       ctx->Texture.GenModeQ = GL_EYE_LINEAR;
800       ASSIGN_4V( ctx->Texture.ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
801       ASSIGN_4V( ctx->Texture.ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
802       ASSIGN_4V( ctx->Texture.ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
803       ASSIGN_4V( ctx->Texture.ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
804       ASSIGN_4V( ctx->Texture.EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
805       ASSIGN_4V( ctx->Texture.EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
806       ASSIGN_4V( ctx->Texture.EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
807       ASSIGN_4V( ctx->Texture.EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
808 
809       ctx->Texture.Current1D = ctx->Shared->Default1D;
810       ctx->Texture.Current2D = ctx->Shared->Default2D;
811 
812       ctx->Texture.AnyDirty = GL_FALSE;
813 
814       /* Transformation group */
815       ctx->Transform.MatrixMode = GL_MODELVIEW;
816       ctx->Transform.Normalize = GL_FALSE;
817       for (i=0;i<MAX_CLIP_PLANES;i++) {
818 	 ctx->Transform.ClipEnabled[i] = GL_FALSE;
819          ASSIGN_4V( ctx->Transform.ClipEquation[i], 0.0, 0.0, 0.0, 0.0 );
820       }
821       ctx->Transform.AnyClip = GL_FALSE;
822 
823       /* Viewport group */
824       ctx->Viewport.X = 0;
825       ctx->Viewport.Y = 0;
826       ctx->Viewport.Width = 0;
827       ctx->Viewport.Height = 0;
828       ctx->Viewport.Near = 0.0;
829       ctx->Viewport.Far = 1.0;
830       ctx->Viewport.Sx = 0.0;  /* Sx, Tx, Sy, Ty are computed later */
831       ctx->Viewport.Tx = 0.0;
832       ctx->Viewport.Sy = 0.0;
833       ctx->Viewport.Ty = 0.0;
834       ctx->Viewport.Sz = 0.5 * DEPTH_SCALE;
835       ctx->Viewport.Tz = 0.5 * DEPTH_SCALE;
836 
837       /* Pixel transfer */
838       ctx->Pack.Alignment = 4;
839       ctx->Pack.RowLength = 0;
840       ctx->Pack.SkipPixels = 0;
841       ctx->Pack.SkipRows = 0;
842       ctx->Pack.SwapBytes = GL_FALSE;
843       ctx->Pack.LsbFirst = GL_FALSE;
844       ctx->Unpack.Alignment = 4;
845       ctx->Unpack.RowLength = 0;
846       ctx->Unpack.SkipPixels = 0;
847       ctx->Unpack.SkipRows = 0;
848       ctx->Unpack.SwapBytes = GL_FALSE;
849       ctx->Unpack.LsbFirst = GL_FALSE;
850 
851       /* Feedback */
852       ctx->Feedback.Type = GL_2D;   /* TODO: verify */
853       ctx->Feedback.Buffer = NULL;
854       ctx->Feedback.BufferSize = 0;
855       ctx->Feedback.Count = 0;
856 
857       /* Selection/picking */
858       ctx->Select.Buffer = NULL;
859       ctx->Select.BufferSize = 0;
860       ctx->Select.BufferCount = 0;
861       ctx->Select.Hits = 0;
862       ctx->Select.NameStackDepth = 0;
863 
864       /* Renderer and client attribute stacks */
865       ctx->AttribStackDepth = 0;
866       ctx->ClientAttribStackDepth = 0;
867 
868       /*** Miscellaneous ***/
869       ctx->NewState = NEW_ALL;
870       ctx->RenderMode = GL_RENDER;
871       ctx->Primitive = GL_BITMAP;
872 
873       ctx->StippleCounter = 0;
874       ctx->NeedNormals = GL_FALSE;
875 
876       if (   ctx->Visual->RedScale==255.0F
877           && ctx->Visual->GreenScale==255.0F
878           && ctx->Visual->BlueScale==255.0F
879           && ctx->Visual->AlphaScale==255.0F) {
880          ctx->Visual->EightBitColor = GL_TRUE;
881       }
882       else {
883          ctx->Visual->EightBitColor = GL_FALSE;
884       }
885       ctx->FastDrawPixels = ctx->Visual->RGBAflag && ctx->Visual->EightBitColor;
886 
887 #if JUNK
888       ctx->PointsFunc = NULL;
889       ctx->LineFunc = NULL;
890       ctx->TriangleFunc = NULL;
891 #endif
892 
893       ctx->DirectContext = GL_TRUE;  /* XXXX temp */
894 
895       /* Display list */
896       ctx->CallDepth = 0;
897       ctx->ExecuteFlag = GL_TRUE;
898       ctx->CompileFlag = GL_FALSE;
899       ctx->CurrentListPtr = NULL;
900       ctx->CurrentBlock = NULL;
901       ctx->CurrentListNum = 0;
902       ctx->CurrentPos = 0;
903 
904       ctx->ErrorValue = GL_NO_ERROR;
905 
906       /* For debug/development only */
907       ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
908 
909       /* Dither disable */
910       ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
911       if (ctx->NoDither) {
912          TRACE("MESA_NO_DITHER set - dithering disabled\n");
913          ctx->Color.DitherFlag = GL_FALSE;
914       }
915    }
916 }
917 
918 
919 
920 /*
921  * Allocate a new GLvisual object.
922  * Input:  rgb_flag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
923  *         alpha_flag - alloc software alpha buffers?
924  *         db_flag - double buffering?
925  *         depth_bits - requested minimum bits per depth buffer value
926  *         stencil_bits - requested minimum bits per stencil buffer value
927  *         accum_bits - requested minimum bits per accum buffer component
928  *         index_bits - number of bits per pixel if rgb_flag==GL_FALSE
929  *         red/green/blue_scale - float-to-int color scaling
930  *         alpha_scale - ignored if alpha_flag is true
931  *         red/green/blue/alpha_bits - number of bits per color component
932  *                                     in frame buffer for RGB(A) mode.
933  * Return:  pointer to new GLvisual or NULL if requested parameters can't
934  *          be met.
935  */
936 GLvisual *gl_create_visual( GLboolean rgb_flag,
937                             GLboolean alpha_flag,
938                             GLboolean db_flag,
939                             GLint depth_bits,
940                             GLint stencil_bits,
941                             GLint accum_bits,
942                             GLint index_bits,
943                             GLfloat red_scale,
944                             GLfloat green_scale,
945                             GLfloat blue_scale,
946                             GLfloat alpha_scale,
947                             GLint red_bits,
948                             GLint green_bits,
949                             GLint blue_bits,
950                             GLint alpha_bits )
951 {
952    GLvisual *vis;
953 
954    /* Can't do better than 8-bit/channel color at this time */
955    assert( red_scale<=255.0 );
956    assert( green_scale<=255.0 );
957    assert( blue_scale<=255.0 );
958    assert( alpha_scale<=255.0 );
959 
960    if (depth_bits > 8*sizeof(GLdepth)) {
961       /* can't meet depth buffer requirements */
962       return NULL;
963    }
964    if (stencil_bits > 8*sizeof(GLstencil)) {
965       /* can't meet stencil buffer requirements */
966       return NULL;
967    }
968    if (accum_bits > 8*sizeof(GLaccum)) {
969       /* can't meet accum buffer requirements */
970       return NULL;
971    }
972 
973    vis = (GLvisual *) calloc( 1, sizeof(GLvisual) );
974    if (!vis) {
975       return NULL;
976    }
977 
978    vis->RGBAflag      = rgb_flag;
979    vis->DBflag        = db_flag;
980    vis->RedScale      = red_scale;
981    vis->GreenScale    = green_scale;
982    vis->BlueScale     = blue_scale;
983    vis->AlphaScale    = alpha_scale;
984    if (red_scale) {
985       vis->InvRedScale   = 1.0F / red_scale;
986    }
987    if (green_scale) {
988       vis->InvGreenScale = 1.0F / green_scale;
989    }
990    if (blue_scale) {
991       vis->InvBlueScale  = 1.0F / blue_scale;
992    }
993    if (alpha_scale) {
994       vis->InvAlphaScale = 1.0F / alpha_scale;
995    }
996 
997    vis->RedBits   = red_bits;
998    vis->GreenBits = green_bits;
999    vis->BlueBits  = blue_bits;
1000    vis->AlphaBits = alpha_flag ? 8*sizeof(GLubyte) : alpha_bits;
1001 
1002    vis->IndexBits   = index_bits;
1003    vis->DepthBits   = (depth_bits>0) ? 8*sizeof(GLdepth) : 0;
1004    vis->AccumBits   = (accum_bits>0) ? 8*sizeof(GLaccum) : 0;
1005    vis->StencilBits = (stencil_bits>0) ? 8*sizeof(GLstencil) : 0;
1006 
1007    if (red_scale==255.0F && green_scale==255.0F
1008        && blue_scale==255.0F && alpha_scale==255.0F) {
1009       vis->EightBitColor = GL_TRUE;
1010    }
1011    else {
1012       vis->EightBitColor = GL_FALSE;
1013    }
1014 
1015    /* software alpha buffers */
1016    if (alpha_flag) {
1017       vis->FrontAlphaEnabled = GL_TRUE;
1018       if (db_flag) {
1019          vis->BackAlphaEnabled = GL_TRUE;
1020       }
1021    }
1022 
1023    return vis;
1024 }
1025 
1026 
1027 
1028 
1029 void gl_destroy_visual( GLvisual *vis )
1030 {
1031    free( vis );
1032 }
1033 
1034 
1035 
1036 /*
1037  * Allocate the proxy textures.  If we run out of memory part way through
1038  * the allocations clean up and return GL_FALSE.
1039  * Return:  GL_TRUE=success, GL_FALSE=failure
1040  */
1041 static GLboolean alloc_proxy_textures( GLcontext *ctx )
1042 {
1043    GLboolean out_of_memory;
1044    GLint i;
1045 
1046    ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
1047    if (!ctx->Texture.Proxy1D) {
1048       return GL_FALSE;
1049    }
1050 
1051    ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
1052    if (!ctx->Texture.Proxy2D) {
1053       gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1054       return GL_FALSE;
1055    }
1056 
1057    out_of_memory = GL_FALSE;
1058    for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1059       ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
1060       ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
1061       if (!ctx->Texture.Proxy1D->Image[i]
1062           || !ctx->Texture.Proxy2D->Image[i]) {
1063          out_of_memory = GL_TRUE;
1064       }
1065    }
1066    if (out_of_memory) {
1067       for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1068          if (ctx->Texture.Proxy1D->Image[i]) {
1069             gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
1070          }
1071          if (ctx->Texture.Proxy2D->Image[i]) {
1072             gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
1073          }
1074       }
1075       gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1076       gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1077       return GL_FALSE;
1078    }
1079    else {
1080       return GL_TRUE;
1081    }
1082 }
1083 
1084 
1085 
1086 /*
1087  * Allocate and initialize a GLcontext structure.
1088  * Input:  visual - a GLvisual pointer
1089  *         sharelist - another context to share display lists with or NULL
1090  *         driver_ctx - pointer to device driver's context state struct
1091  * Return:  pointer to a new gl_context struct or NULL if error.
1092  */
1093 GLcontext *gl_create_context( GLvisual *visual,
1094                               GLcontext *share_list,
1095                               void *driver_ctx )
1096 {
1097    GLcontext *ctx;
1098 
1099    /* do some implementation tests */
1100    assert( sizeof(GLbyte) == 1 );
1101    assert( sizeof(GLshort) >= 2 );
1102    assert( sizeof(GLint) >= 4 );
1103    assert( sizeof(GLubyte) == 1 );
1104    assert( sizeof(GLushort) >= 2 );
1105    assert( sizeof(GLuint) >= 4 );
1106 
1107    /* misc one-time initializations */
1108    gl_init_math();
1109    gl_init_lists();
1110    gl_init_eval();
1111 
1112    ctx = (GLcontext *) calloc( 1, sizeof(GLcontext) );
1113    if (!ctx) {
1114       return NULL;
1115    }
1116 
1117    ctx->DriverCtx = driver_ctx;
1118    ctx->Visual = visual;
1119    ctx->Buffer = NULL;
1120 
1121    ctx->VB = gl_alloc_vb();
1122    if (!ctx->VB) {
1123       free( ctx );
1124       return NULL;
1125    }
1126 
1127    ctx->PB = gl_alloc_pb();
1128    if (!ctx->PB) {
1129       free( ctx->VB );
1130       free( ctx );
1131       return NULL;
1132    }
1133 
1134    if (share_list) {
1135       /* share the group of display lists of another context */
1136       ctx->Shared = share_list->Shared;
1137    }
1138    else {
1139       /* allocate new group of display lists */
1140       ctx->Shared = alloc_shared_state();
1141       if (!ctx->Shared) {
1142          free(ctx->VB);
1143          free(ctx->PB);
1144          free(ctx);
1145          return NULL;
1146       }
1147    }
1148    ctx->Shared->RefCount++;
1149 
1150    initialize_context( ctx );
1151 
1152    if (visual->DBflag) {
1153       ctx->Color.DrawBuffer = GL_BACK;
1154       ctx->Pixel.ReadBuffer = GL_BACK;
1155    }
1156    else {
1157       ctx->Color.DrawBuffer = GL_FRONT;
1158       ctx->Pixel.ReadBuffer = GL_FRONT;
1159    }
1160 
1161 #ifdef PROFILE
1162    init_timings( ctx );
1163 #endif
1164 
1165 #ifdef GL_VERSION_1_1
1166    if (!alloc_proxy_textures(ctx)) {
1167       free_shared_state(ctx, ctx->Shared);
1168       free(ctx->VB);
1169       free(ctx->PB);
1170       free(ctx);
1171       return NULL;
1172    }
1173 #endif
1174 
1175    gl_init_api_function_pointers( ctx );
1176    ctx->API = ctx->Exec;   /* GL_EXECUTE is default */
1177 
1178    return ctx;
1179 }
1180 
1181 
1182 
1183 /*
1184  * Destroy a gl_context structure.
1185  */
1186 void gl_destroy_context( GLcontext *ctx )
1187 {
1188    if (ctx) {
1189 
1190 #ifdef PROFILE
1191       if (getenv("MESA_PROFILE")) {
1192          print_timings( ctx );
1193       }
1194 #endif
1195 
1196       free( ctx->PB );
1197       free( ctx->VB );
1198 
1199       ctx->Shared->RefCount--;
1200       assert(ctx->Shared->RefCount>=0);
1201       if (ctx->Shared->RefCount==0) {
1202 	 /* free shared state */
1203 	 free_shared_state( ctx, ctx->Shared );
1204       }
1205 
1206       /* Free proxy texture objects */
1207       gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1208       gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1209 
1210       free( (void *) ctx );
1211 
1212 #ifndef THREADS
1213       if (ctx==CC) {
1214          CC = NULL;
1215       }
1216 #endif
1217 
1218    }
1219 }
1220 
1221 
1222 
1223 /*
1224  * Create a new framebuffer.  A GLframebuffer is a struct which
1225  * encapsulates the depth, stencil and accum buffers and related
1226  * parameters.
1227  * Input:  visual - a GLvisual pointer
1228  * Return:  pointer to new GLframebuffer struct or NULL if error.
1229  */
1230 GLframebuffer *gl_create_framebuffer( GLvisual *visual )
1231 {
1232    GLframebuffer *buffer;
1233 
1234    buffer = (GLframebuffer *) calloc( 1, sizeof(GLframebuffer) );
1235    if (!buffer) {
1236       return NULL;
1237    }
1238 
1239    buffer->Visual = visual;
1240 
1241    return buffer;
1242 }
1243 
1244 
1245 
1246 /*
1247  * Free a framebuffer struct and its buffers.
1248  */
1249 void gl_destroy_framebuffer( GLframebuffer *buffer )
1250 {
1251    if (buffer) {
1252       if (buffer->Depth) {
1253          free( buffer->Depth );
1254       }
1255       if (buffer->Accum) {
1256          free( buffer->Accum );
1257       }
1258       if (buffer->Stencil) {
1259          free( buffer->Stencil );
1260       }
1261       if (buffer->FrontAlpha) {
1262          free( buffer->FrontAlpha );
1263       }
1264       if (buffer->BackAlpha) {
1265          free( buffer->BackAlpha );
1266       }
1267       free(buffer);
1268    }
1269 }
1270 
1271 
1272 
1273 /*
1274  * Set the current context, binding the given frame buffer to the context.
1275  */
1276 void gl_make_current( GLcontext *ctx, GLframebuffer *buffer )
1277 {
1278    if (ctx && buffer) {
1279       /* TODO: check if ctx and buffer's visual match??? */
1280       ctx->Buffer = buffer;      /* Bind the frame buffer to the context */
1281       ctx->NewState = NEW_ALL;   /* just to be safe */
1282       gl_update_state( ctx );
1283    }
1284 }
1285 
1286 
1287 /*
1288  * Copy attribute groups from one context to another.
1289  * Input:  src - source context
1290  *         dst - destination context
1291  *         mask - bitwise OR of GL_*_BIT flags
1292  */
1293 void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1294 {
1295    if (mask & GL_ACCUM_BUFFER_BIT) {
1296       MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1297    }
1298    if (mask & GL_COLOR_BUFFER_BIT) {
1299       MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1300    }
1301    if (mask & GL_CURRENT_BIT) {
1302       MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1303    }
1304    if (mask & GL_DEPTH_BUFFER_BIT) {
1305       MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1306    }
1307    if (mask & GL_ENABLE_BIT) {
1308       /* no op */
1309    }
1310    if (mask & GL_EVAL_BIT) {
1311       MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1312    }
1313    if (mask & GL_FOG_BIT) {
1314       MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1315    }
1316    if (mask & GL_HINT_BIT) {
1317       MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1318    }
1319    if (mask & GL_LIGHTING_BIT) {
1320       MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
1321    }
1322    if (mask & GL_LINE_BIT) {
1323       MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1324    }
1325    if (mask & GL_LIST_BIT) {
1326       MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1327    }
1328    if (mask & GL_PIXEL_MODE_BIT) {
1329       MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1330    }
1331    if (mask & GL_POINT_BIT) {
1332       MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1333    }
1334    if (mask & GL_POLYGON_BIT) {
1335       MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1336    }
1337    if (mask & GL_POLYGON_STIPPLE_BIT) {
1338       /* Use loop instead of MEMCPY due to problem with Portland Group's
1339        * C compiler.  Reported by John Stone.
1340        */
1341       int i;
1342       for (i=0;i<32;i++) {
1343          dst->PolygonStipple[i] = src->PolygonStipple[i];
1344       }
1345    }
1346    if (mask & GL_SCISSOR_BIT) {
1347       MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1348    }
1349    if (mask & GL_STENCIL_BUFFER_BIT) {
1350       MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1351    }
1352    if (mask & GL_TEXTURE_BIT) {
1353       MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1354    }
1355    if (mask & GL_TRANSFORM_BIT) {
1356       MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1357    }
1358    if (mask & GL_VIEWPORT_BIT) {
1359       MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1360    }
1361 }
1362 
1363 
1364 
1365 /*
1366  * Someday a GLS library or OpenGL-like debugger may call this function
1367  * to register it's own set of API entry points.
1368  * Input: ctx - the context to set API pointers for
1369  *        api - if NULL, restore original API pointers
1370  *              else, set API function table to this table.
1371  */
1372 void gl_set_api_table( GLcontext *ctx, const struct gl_api_table *api )
1373 {
1374    if (api) {
1375       MEMCPY( &ctx->API, api, sizeof(struct gl_api_table) );
1376    }
1377    else {
1378       MEMCPY( &ctx->API, &ctx->Exec, sizeof(struct gl_api_table) );
1379    }
1380 }
1381 
1382 
1383 
1384 
1385 /**********************************************************************/
1386 /*****                Miscellaneous functions                     *****/
1387 /**********************************************************************/
1388 
1389 
1390 /*
1391  * This function is called when the Mesa user has stumbled into a code
1392  * path which may not be implemented fully or correctly.
1393  */
1394 void gl_problem( const GLcontext *ctx, const char *s )
1395 {
1396    ERR("MESA ERROR : %s\n", wine_dbgstr_a(s));
1397 }
1398 
1399 
1400 
1401 /*
1402  * This is called to inform the user that he or she has tried to do
1403  * something illogical or if there's likely a bug in their program
1404  * (like enabled depth testing without a depth buffer).
1405  */
1406 void gl_warning( const GLcontext *ctx, const char *s )
1407 {
1408    WARN("MESA WARNING: %s\n", wine_dbgstr_a(s));
1409 }
1410 
1411 
1412 
1413 /*
1414  * This is Mesa's error handler.  Normally, all that's done is the updating
1415  * of the current error value.  If Mesa is compiled with -DDEBUG or if the
1416  * environment variable "MESA_DEBUG" is defined then a real error message
1417  * is printed to stderr.
1418  * Input:  error - the error value
1419  *         s - a diagnostic string
1420  */
1421 void gl_error( GLcontext *ctx, GLenum error, const char *s )
1422 {
1423    GLboolean debug;
1424 
1425 #ifdef DEBUG
1426    debug = GL_TRUE;
1427 #else
1428    if (getenv("MESA_DEBUG")) {
1429       debug = GL_TRUE;
1430    }
1431    else {
1432       debug = GL_FALSE;
1433    }
1434 #endif
1435 
1436    if (debug) {
1437       char errstr[1000];
1438 
1439       switch (error) {
1440 	 case GL_NO_ERROR:
1441 	    strcpy( errstr, "GL_NO_ERROR" );
1442 	    break;
1443 	 case GL_INVALID_VALUE:
1444 	    strcpy( errstr, "GL_INVALID_VALUE" );
1445 	    break;
1446 	 case GL_INVALID_ENUM:
1447 	    strcpy( errstr, "GL_INVALID_ENUM" );
1448 	    break;
1449 	 case GL_INVALID_OPERATION:
1450 	    strcpy( errstr, "GL_INVALID_OPERATION" );
1451 	    break;
1452 	 case GL_STACK_OVERFLOW:
1453 	    strcpy( errstr, "GL_STACK_OVERFLOW" );
1454 	    break;
1455 	 case GL_STACK_UNDERFLOW:
1456 	    strcpy( errstr, "GL_STACK_UNDERFLOW" );
1457 	    break;
1458 	 case GL_OUT_OF_MEMORY:
1459 	    strcpy( errstr, "GL_OUT_OF_MEMORY" );
1460 	    break;
1461 	 default:
1462 	    strcpy( errstr, "unknown" );
1463 	    break;
1464       }
1465       ERR("Mesa user error: %s in %s\n", wine_dbgstr_a(errstr), wine_dbgstr_a(s));
1466    }
1467 
1468    if (ctx->ErrorValue==GL_NO_ERROR) {
1469       ctx->ErrorValue = error;
1470    }
1471 
1472    /* Call device driver's error handler, if any.  This is used on the Mac. */
1473    if (ctx->Driver.Error) {
1474       (*ctx->Driver.Error)( ctx );
1475    }
1476 }
1477 
1478 
1479 
1480 
1481 GLenum gl_GetError( GLcontext *ctx )
1482 {
1483    GLenum e;
1484 
1485    if (INSIDE_BEGIN_END(ctx)) {
1486       gl_error( ctx, GL_INVALID_OPERATION, "glGetError" );
1487       return GL_INVALID_OPERATION;
1488    }
1489 
1490    e = ctx->ErrorValue;
1491    ctx->ErrorValue = GL_NO_ERROR;
1492    return e;
1493 }
1494 
1495 
1496 
1497 void gl_ResizeBuffersMESA( GLcontext *ctx )
1498 {
1499    GLint newsize;
1500    GLuint buf_width, buf_height;
1501 
1502    ctx->NewState |= NEW_ALL;   /* just to be safe */
1503 
1504    /* ask device driver for size of output buffer */
1505    (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height );
1506 
1507    /* see if size of device driver's color buffer (window) has changed */
1508    newsize = ctx->Buffer->Width!=buf_width || ctx->Buffer->Height!=buf_height;
1509 
1510    /* save buffer size */
1511    ctx->Buffer->Width = buf_width;
1512    ctx->Buffer->Height = buf_height;
1513 
1514    /* Reallocate other buffers if needed. */
1515    if (newsize && ctx->Visual->DepthBits>0) {
1516       /* reallocate depth buffer */
1517       (*ctx->Driver.AllocDepthBuffer)( ctx );
1518       /*** if scissoring enabled then clearing can cause a problem ***/
1519       /***(*ctx->Driver.ClearDepthBuffer)( ctx );***/
1520    }
1521    if (newsize && ctx->Visual->StencilBits>0) {
1522       /* reallocate stencil buffer */
1523       gl_alloc_stencil_buffer( ctx );
1524    }
1525    if (newsize && ctx->Visual->AccumBits>0) {
1526       /* reallocate accum buffer */
1527       gl_alloc_accum_buffer( ctx );
1528    }
1529    if (newsize
1530        && (ctx->Visual->FrontAlphaEnabled || ctx->Visual->BackAlphaEnabled)) {
1531       gl_alloc_alpha_buffers( ctx );
1532    }
1533 }
1534 
1535 
1536 
1537 
1538 /**********************************************************************/
1539 /*****                   State update logic                       *****/
1540 /**********************************************************************/
1541 
1542 
1543 /*
1544  * Since the device driver may or may not support pixel logic ops we
1545  * have to make some extensive tests to determine whether or not
1546  * software-implemented logic operations have to be used.
1547  */
1548 static void update_pixel_logic( GLcontext *ctx )
1549 {
1550    if (ctx->Visual->RGBAflag) {
1551       /* RGBA mode blending w/ Logic Op */
1552       if (ctx->Color.ColorLogicOpEnabled) {
1553 	 if (ctx->Driver.LogicOp
1554              && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1555 	    /* Device driver can do logic, don't have to do it in software */
1556 	    ctx->Color.SWLogicOpEnabled = GL_FALSE;
1557 	 }
1558 	 else {
1559 	    /* Device driver can't do logic op so we do it in software */
1560 	    ctx->Color.SWLogicOpEnabled = GL_TRUE;
1561 	 }
1562       }
1563       else {
1564 	 /* no logic op */
1565 	 if (ctx->Driver.LogicOp) {
1566             (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1567          }
1568 	 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1569       }
1570    }
1571    else {
1572       /* CI mode Logic Op */
1573       if (ctx->Color.IndexLogicOpEnabled) {
1574 	 if (ctx->Driver.LogicOp
1575              && (*ctx->Driver.LogicOp)( ctx, ctx->Color.LogicOp )) {
1576 	    /* Device driver can do logic, don't have to do it in software */
1577 	    ctx->Color.SWLogicOpEnabled = GL_FALSE;
1578 	 }
1579 	 else {
1580 	    /* Device driver can't do logic op so we do it in software */
1581 	    ctx->Color.SWLogicOpEnabled = GL_TRUE;
1582 	 }
1583       }
1584       else {
1585 	 /* no logic op */
1586 	 if (ctx->Driver.LogicOp) {
1587             (void) (*ctx->Driver.LogicOp)( ctx, GL_COPY );
1588          }
1589 	 ctx->Color.SWLogicOpEnabled = GL_FALSE;
1590       }
1591    }
1592 }
1593 
1594 
1595 
1596 /*
1597  * Check if software implemented RGBA or Color Index masking is needed.
1598  */
1599 static void update_pixel_masking( GLcontext *ctx )
1600 {
1601    if (ctx->Visual->RGBAflag) {
1602       if (ctx->Color.ColorMask==0xf) {
1603          /* disable masking */
1604          if (ctx->Driver.ColorMask) {
1605             (void) (*ctx->Driver.ColorMask)( ctx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1606          }
1607          ctx->Color.SWmasking = GL_FALSE;
1608       }
1609       else {
1610          /* Ask driver to do color masking, if it can't then
1611           * do it in software
1612           */
1613          GLboolean red   = (ctx->Color.ColorMask & 8) ? GL_TRUE : GL_FALSE;
1614          GLboolean green = (ctx->Color.ColorMask & 4) ? GL_TRUE : GL_FALSE;
1615          GLboolean blue  = (ctx->Color.ColorMask & 2) ? GL_TRUE : GL_FALSE;
1616          GLboolean alpha = (ctx->Color.ColorMask & 1) ? GL_TRUE : GL_FALSE;
1617          if (ctx->Driver.ColorMask
1618              && (*ctx->Driver.ColorMask)( ctx, red, green, blue, alpha )) {
1619             ctx->Color.SWmasking = GL_FALSE;
1620          }
1621          else {
1622             ctx->Color.SWmasking = GL_TRUE;
1623          }
1624       }
1625    }
1626    else {
1627       if (ctx->Color.IndexMask==0xffffffff) {
1628          /* disable masking */
1629          if (ctx->Driver.IndexMask) {
1630             (void) (*ctx->Driver.IndexMask)( ctx, 0xffffffff );
1631          }
1632          ctx->Color.SWmasking = GL_FALSE;
1633       }
1634       else {
1635          /* Ask driver to do index masking, if it can't then
1636           * do it in software
1637           */
1638          if (ctx->Driver.IndexMask
1639              && (*ctx->Driver.IndexMask)( ctx, ctx->Color.IndexMask )) {
1640             ctx->Color.SWmasking = GL_FALSE;
1641          }
1642          else {
1643             ctx->Color.SWmasking = GL_TRUE;
1644          }
1645       }
1646    }
1647 }
1648 
1649 
1650 
1651 /*
1652  * Recompute the value of ctx->RasterMask, etc. according to
1653  * the current context.
1654  */
1655 static void update_rasterflags( GLcontext *ctx )
1656 {
1657    ctx->RasterMask = 0;
1658 
1659    if (ctx->Color.AlphaEnabled)		ctx->RasterMask |= ALPHATEST_BIT;
1660    if (ctx->Color.BlendEnabled)		ctx->RasterMask |= BLEND_BIT;
1661    if (ctx->Depth.Test)			ctx->RasterMask |= DEPTH_BIT;
1662    if (ctx->Fog.Enabled)		ctx->RasterMask |= FOG_BIT;
1663    if (ctx->Color.SWLogicOpEnabled)	ctx->RasterMask |= LOGIC_OP_BIT;
1664    if (ctx->Scissor.Enabled)		ctx->RasterMask |= SCISSOR_BIT;
1665    if (ctx->Stencil.Enabled)		ctx->RasterMask |= STENCIL_BIT;
1666    if (ctx->Color.SWmasking)		ctx->RasterMask |= MASKING_BIT;
1667    if (ctx->Visual->FrontAlphaEnabled)	ctx->RasterMask |= ALPHABUF_BIT;
1668    if (ctx->Visual->BackAlphaEnabled)	ctx->RasterMask |= ALPHABUF_BIT;
1669 
1670    if (   ctx->Viewport.X<0
1671        || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
1672        || ctx->Viewport.Y<0
1673        || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
1674       ctx->RasterMask |= WINCLIP_BIT;
1675    }
1676 
1677    /* check if drawing to front and back buffers */
1678    if (ctx->Color.DrawBuffer==GL_FRONT_AND_BACK) {
1679       ctx->RasterMask |= FRONT_AND_BACK_BIT;
1680    }
1681 
1682    /* check if writing to color buffer(s) is disabled */
1683    if (ctx->Color.DrawBuffer==GL_NONE) {
1684       ctx->RasterMask |= NO_DRAW_BIT;
1685    }
1686    else if (ctx->Visual->RGBAflag && ctx->Color.ColorMask==0) {
1687       ctx->RasterMask |= NO_DRAW_BIT;
1688    }
1689    else if (!ctx->Visual->RGBAflag && ctx->Color.IndexMask==0) {
1690       ctx->RasterMask |= NO_DRAW_BIT;
1691    }
1692 }
1693 
1694 
1695 /*
1696  * Recompute the value of ctx->ClipMask according to the current context.
1697  * ClipMask depends on Texturing and Lighting.
1698  */
1699 static void update_clipmask(GLcontext *ctx)
1700 {
1701    /* Recompute ClipMask (what has to be interpolated when clipping) */
1702    ctx->ClipMask = 0;
1703    if (ctx->Texture.Enabled) {
1704       ctx->ClipMask |= CLIP_TEXTURE_BIT;
1705    }
1706    if (ctx->Light.ShadeModel==GL_SMOOTH) {
1707       if (ctx->Visual->RGBAflag) {
1708 	 ctx->ClipMask |= CLIP_FCOLOR_BIT;
1709 	 if (ctx->Light.Model.TwoSide) {
1710 	    ctx->ClipMask |= CLIP_BCOLOR_BIT;
1711 	 }
1712       }
1713       else {
1714 	 ctx->ClipMask |= CLIP_FINDEX_BIT;
1715 	 if (ctx->Light.Model.TwoSide) {
1716 	    ctx->ClipMask |= CLIP_BINDEX_BIT;
1717 	 }
1718       }
1719    }
1720 
1721    switch(ctx->ClipMask) {
1722       case CLIP_FCOLOR_BIT|CLIP_TEXTURE_BIT:
1723          if(ctx->VB->TexCoordSize==2)
1724             ctx->ClipInterpAuxFunc = interpolate_aux_color_tex2;
1725          else
1726             ctx->ClipInterpAuxFunc = interpolate_aux;
1727          break;
1728       case CLIP_TEXTURE_BIT:
1729          if(ctx->VB->TexCoordSize==2)
1730             ctx->ClipInterpAuxFunc = interpolate_aux_tex2;
1731          else
1732             ctx->ClipInterpAuxFunc = interpolate_aux;
1733          break;
1734       case CLIP_FCOLOR_BIT:
1735          ctx->ClipInterpAuxFunc = interpolate_aux_color;
1736          break;
1737       default:
1738          ctx->ClipInterpAuxFunc = interpolate_aux;
1739    }
1740 }
1741 
1742 
1743 
1744 /*
1745  * If ctx->NewState is non-zero then this function MUST be called before
1746  * rendering any primitive.  Basically, function pointers and miscellaneous
1747  * flags are updated to reflect the current state of the state machine.
1748  */
1749 void gl_update_state( GLcontext *ctx )
1750 {
1751    if (ctx->NewState & NEW_RASTER_OPS) {
1752       update_pixel_logic(ctx);
1753       update_pixel_masking(ctx);
1754       update_rasterflags(ctx);
1755       if (ctx->Driver.Dither) {
1756          (*ctx->Driver.Dither)( ctx, ctx->Color.DitherFlag );
1757       }
1758    }
1759 
1760    if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING)) {
1761       update_clipmask(ctx);
1762    }
1763 
1764    if (ctx->NewState & NEW_LIGHTING) {
1765       gl_update_lighting(ctx);
1766       gl_set_color_function(ctx);
1767    }
1768 
1769    if (ctx->NewState & NEW_TEXTURING) {
1770       gl_update_texture_state(ctx);
1771    }
1772 
1773    if (ctx->NewState & (NEW_LIGHTING | NEW_TEXTURING)) {
1774       /* Check if normal vectors are needed */
1775       GLboolean sphereGen = ctx->Texture.Enabled
1776          && ((ctx->Texture.GenModeS==GL_SPHERE_MAP
1777               && (ctx->Texture.TexGenEnabled & S_BIT))
1778              || (ctx->Texture.GenModeT==GL_SPHERE_MAP
1779                  && (ctx->Texture.TexGenEnabled & T_BIT)));
1780       if (ctx->Light.Enabled || sphereGen) {
1781          ctx->NeedNormals = GL_TRUE;
1782       }
1783       else {
1784          ctx->NeedNormals = GL_FALSE;
1785       }
1786    }
1787 
1788    if (ctx->NewState & NEW_RASTER_OPS) {
1789       /* Check if incoming colors can be modified during rasterization */
1790       if (ctx->Fog.Enabled ||
1791           ctx->Texture.Enabled ||
1792           ctx->Color.BlendEnabled ||
1793           ctx->Color.SWmasking ||
1794           ctx->Color.SWLogicOpEnabled) {
1795          ctx->MutablePixels = GL_TRUE;
1796       }
1797       else {
1798          ctx->MutablePixels = GL_FALSE;
1799       }
1800    }
1801 
1802    if (ctx->NewState & (NEW_RASTER_OPS | NEW_LIGHTING)) {
1803       /* Check if all pixels generated are likely to be the same color */
1804       if (ctx->Light.ShadeModel==GL_SMOOTH ||
1805           ctx->Light.Enabled ||
1806           ctx->Fog.Enabled ||
1807           ctx->Texture.Enabled ||
1808           ctx->Color.BlendEnabled ||
1809           ctx->Color.SWmasking ||
1810           ctx->Color.SWLogicOpEnabled) {
1811          ctx->MonoPixels = GL_FALSE;       /* pixels probably multicolored */
1812       }
1813       else {
1814          /* pixels will all be same color,
1815           * only glColor() can invalidate this.
1816           */
1817          ctx->MonoPixels = GL_TRUE;
1818       }
1819    }
1820 
1821    if (ctx->NewState & NEW_POLYGON) {
1822       /* Setup CullBits bitmask */
1823       ctx->Polygon.CullBits = 0;
1824       if (ctx->Polygon.CullFlag) {
1825          if (ctx->Polygon.CullFaceMode==GL_FRONT ||
1826              ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK) {
1827             ctx->Polygon.CullBits |= 1;
1828          }
1829          if (ctx->Polygon.CullFaceMode==GL_BACK ||
1830              ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK) {
1831             ctx->Polygon.CullBits |= 2;
1832          }
1833       }
1834       /* Any Polygon offsets enabled? */
1835       ctx->Polygon.OffsetAny = ctx->Polygon.OffsetPoint ||
1836                                ctx->Polygon.OffsetLine ||
1837                                ctx->Polygon.OffsetFill;
1838       /* reset Z offsets now */
1839       ctx->PointZoffset   = 0.0;
1840       ctx->LineZoffset    = 0.0;
1841       ctx->PolygonZoffset = 0.0;
1842    }
1843 
1844    if (ctx->NewState & (NEW_POLYGON | NEW_LIGHTING)) {
1845       /* Determine if we can directly call the triangle rasterizer */
1846       if (   ctx->Polygon.Unfilled
1847           || ctx->Polygon.OffsetAny
1848           || ctx->Polygon.CullFlag
1849           || ctx->Light.Model.TwoSide
1850           || ctx->RenderMode!=GL_RENDER) {
1851          ctx->DirectTriangles = GL_FALSE;
1852       }
1853       else {
1854          ctx->DirectTriangles = GL_TRUE;
1855       }
1856    }
1857 
1858    /* update scissor region */
1859    ctx->Buffer->Xmin = 0;
1860    ctx->Buffer->Ymin = 0;
1861    ctx->Buffer->Xmax = ctx->Buffer->Width-1;
1862    ctx->Buffer->Ymax = ctx->Buffer->Height-1;
1863    if (ctx->Scissor.Enabled) {
1864       if (ctx->Scissor.X > ctx->Buffer->Xmin) {
1865          ctx->Buffer->Xmin = ctx->Scissor.X;
1866       }
1867       if (ctx->Scissor.Y > ctx->Buffer->Ymin) {
1868          ctx->Buffer->Ymin = ctx->Scissor.Y;
1869       }
1870       if (ctx->Scissor.X + ctx->Scissor.Width - 1 < ctx->Buffer->Xmax) {
1871          ctx->Buffer->Xmax = ctx->Scissor.X + ctx->Scissor.Width - 1;
1872       }
1873       if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < ctx->Buffer->Ymax) {
1874          ctx->Buffer->Ymax = ctx->Scissor.Y + ctx->Scissor.Height - 1;
1875       }
1876    }
1877 
1878    /*
1879     * Update Device Driver interface
1880     */
1881    if (ctx->NewState & NEW_RASTER_OPS) {
1882       ctx->Driver.AllocDepthBuffer = gl_alloc_depth_buffer;
1883       ctx->Driver.ClearDepthBuffer = gl_clear_depth_buffer;
1884       if (ctx->Depth.Mask) {
1885          switch (ctx->Depth.Func) {
1886             case GL_LESS:
1887                ctx->Driver.DepthTestSpan = gl_depth_test_span_less;
1888                ctx->Driver.DepthTestPixels = gl_depth_test_pixels_less;
1889                break;
1890             case GL_GREATER:
1891                ctx->Driver.DepthTestSpan = gl_depth_test_span_greater;
1892                ctx->Driver.DepthTestPixels = gl_depth_test_pixels_greater;
1893                break;
1894             default:
1895                ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
1896                ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
1897          }
1898       }
1899       else {
1900          ctx->Driver.DepthTestSpan = gl_depth_test_span_generic;
1901          ctx->Driver.DepthTestPixels = gl_depth_test_pixels_generic;
1902       }
1903       ctx->Driver.ReadDepthSpanFloat = gl_read_depth_span_float;
1904       ctx->Driver.ReadDepthSpanInt = gl_read_depth_span_int;
1905    }
1906 
1907    ctx->Driver.PointsFunc = NULL;
1908    ctx->Driver.LineFunc = NULL;
1909    ctx->Driver.TriangleFunc = NULL;
1910    ctx->Driver.QuadFunc = NULL;
1911    ctx->Driver.RectFunc = NULL;
1912 
1913    if (ctx->Driver.UpdateState) {
1914       (*ctx->Driver.UpdateState)(ctx);
1915    }
1916 
1917    gl_set_point_function(ctx);
1918    gl_set_line_function(ctx);
1919    gl_set_triangle_function(ctx);
1920    gl_set_quad_function(ctx);
1921 
1922    gl_set_vertex_function(ctx);
1923 
1924    ctx->NewState = 0;
1925 }
1926 
1927