blob: b1d922f6515e4a860ee4240ca8dd18f961a5d0fb [file] [log] [blame]
Brian Paul7fc29c52000-03-06 17:03:03 +00001/* $Id: context.c,v 1.45 2000/03/06 17:03:03 brianp Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
4 * Mesa 3-D graphics library
Brian Paulfbd8f211999-11-11 01:22:25 +00005 * Version: 3.3
jtgafb833d1999-08-19 00:55:39 +00006 *
Brian Paul54287052000-01-17 20:00:15 +00007 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
jtgafb833d1999-08-19 00:55:39 +00008 *
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
jtgafb833d1999-08-19 00:55:39 +000028#ifdef PC_HEADER
29#include "all.h"
30#else
Brian Paulfbd8f211999-11-11 01:22:25 +000031#include "glheader.h"
jtgafb833d1999-08-19 00:55:39 +000032#include "accum.h"
33#include "alphabuf.h"
jtgafb833d1999-08-19 00:55:39 +000034#include "clip.h"
35#include "context.h"
36#include "cva.h"
37#include "depth.h"
38#include "dlist.h"
39#include "eval.h"
40#include "enums.h"
Brian Paul585a68c1999-09-11 11:31:34 +000041#include "extensions.h"
jtgafb833d1999-08-19 00:55:39 +000042#include "fog.h"
Brian Paulb7a43041999-11-30 20:34:51 +000043#include "get.h"
Brian Paulfbd8f211999-11-11 01:22:25 +000044#include "glapi.h"
Brian Paulf9b97d92000-01-28 20:17:42 +000045#include "glapinoop.h"
Brian Paul9560f052000-01-31 23:11:39 +000046#include "glthread.h"
jtgafb833d1999-08-19 00:55:39 +000047#include "hash.h"
48#include "light.h"
jtgafb833d1999-08-19 00:55:39 +000049#include "macros.h"
50#include "matrix.h"
Brian Paulfbd8f211999-11-11 01:22:25 +000051#include "mem.h"
jtgafb833d1999-08-19 00:55:39 +000052#include "mmath.h"
53#include "pb.h"
54#include "pipeline.h"
jtgafb833d1999-08-19 00:55:39 +000055#include "shade.h"
56#include "simple_list.h"
57#include "stencil.h"
58#include "stages.h"
Brian Paulfa9df402000-02-02 19:16:46 +000059#include "state.h"
jtgafb833d1999-08-19 00:55:39 +000060#include "translate.h"
61#include "teximage.h"
62#include "texobj.h"
63#include "texstate.h"
64#include "texture.h"
65#include "types.h"
66#include "varray.h"
67#include "vb.h"
68#include "vbcull.h"
jtgafb833d1999-08-19 00:55:39 +000069#include "vbrender.h"
70#include "vbxform.h"
Keith Whitwell38756791999-08-29 10:26:31 +000071#include "vertices.h"
jtgafb833d1999-08-19 00:55:39 +000072#include "xform.h"
jtgafb833d1999-08-19 00:55:39 +000073#endif
74
75
76
77/**********************************************************************/
78/***** Context and Thread management *****/
79/**********************************************************************/
80
81
Brian Paul00037781999-12-17 14:52:35 +000082#if !defined(THREADS)
jtgafb833d1999-08-19 00:55:39 +000083
Brian Paul5666c632000-01-18 17:36:16 +000084struct immediate *_mesa_CurrentInput = NULL;
jtgafb833d1999-08-19 00:55:39 +000085
Brian Paul00037781999-12-17 14:52:35 +000086#endif
jtgafb833d1999-08-19 00:55:39 +000087
88
89
90
91/**********************************************************************/
92/***** Profiling functions *****/
93/**********************************************************************/
94
95#ifdef PROFILE
96
97#include <sys/times.h>
98#include <sys/param.h>
99
100
101/*
102 * Return system time in seconds.
103 * NOTE: this implementation may not be very portable!
104 */
105GLdouble gl_time( void )
106{
107 static GLdouble prev_time = 0.0;
108 static GLdouble time;
109 struct tms tm;
110 clock_t clk;
111
112 clk = times(&tm);
113
114#ifdef CLK_TCK
115 time = (double)clk / (double)CLK_TCK;
116#else
117 time = (double)clk / (double)HZ;
118#endif
119
120 if (time>prev_time) {
121 prev_time = time;
122 return time;
123 }
124 else {
125 return prev_time;
126 }
127}
128
129/*
130 * Reset the timing/profiling counters
131 */
132static void init_timings( GLcontext *ctx )
133{
134 ctx->BeginEndCount = 0;
135 ctx->BeginEndTime = 0.0;
136 ctx->VertexCount = 0;
137 ctx->VertexTime = 0.0;
138 ctx->PointCount = 0;
139 ctx->PointTime = 0.0;
140 ctx->LineCount = 0;
141 ctx->LineTime = 0.0;
142 ctx->PolygonCount = 0;
143 ctx->PolygonTime = 0.0;
144 ctx->ClearCount = 0;
145 ctx->ClearTime = 0.0;
146 ctx->SwapCount = 0;
147 ctx->SwapTime = 0.0;
148}
149
150
151/*
152 * Print the accumulated timing/profiling data.
153 */
154static void print_timings( GLcontext *ctx )
155{
156 GLdouble beginendrate;
157 GLdouble vertexrate;
158 GLdouble pointrate;
159 GLdouble linerate;
160 GLdouble polygonrate;
161 GLdouble overhead;
162 GLdouble clearrate;
163 GLdouble swaprate;
164 GLdouble avgvertices;
165
166 if (ctx->BeginEndTime>0.0) {
167 beginendrate = ctx->BeginEndCount / ctx->BeginEndTime;
168 }
169 else {
170 beginendrate = 0.0;
171 }
172 if (ctx->VertexTime>0.0) {
173 vertexrate = ctx->VertexCount / ctx->VertexTime;
174 }
175 else {
176 vertexrate = 0.0;
177 }
178 if (ctx->PointTime>0.0) {
179 pointrate = ctx->PointCount / ctx->PointTime;
180 }
181 else {
182 pointrate = 0.0;
183 }
184 if (ctx->LineTime>0.0) {
185 linerate = ctx->LineCount / ctx->LineTime;
186 }
187 else {
188 linerate = 0.0;
189 }
190 if (ctx->PolygonTime>0.0) {
191 polygonrate = ctx->PolygonCount / ctx->PolygonTime;
192 }
193 else {
194 polygonrate = 0.0;
195 }
196 if (ctx->ClearTime>0.0) {
197 clearrate = ctx->ClearCount / ctx->ClearTime;
198 }
199 else {
200 clearrate = 0.0;
201 }
202 if (ctx->SwapTime>0.0) {
203 swaprate = ctx->SwapCount / ctx->SwapTime;
204 }
205 else {
206 swaprate = 0.0;
207 }
208
209 if (ctx->BeginEndCount>0) {
210 avgvertices = (GLdouble) ctx->VertexCount / (GLdouble) ctx->BeginEndCount;
211 }
212 else {
213 avgvertices = 0.0;
214 }
215
216 overhead = ctx->BeginEndTime - ctx->VertexTime - ctx->PointTime
217 - ctx->LineTime - ctx->PolygonTime;
218
219
220 printf(" Count Time (s) Rate (/s) \n");
221 printf("--------------------------------------------------------\n");
222 printf("glBegin/glEnd %7d %8.3f %10.3f\n",
223 ctx->BeginEndCount, ctx->BeginEndTime, beginendrate);
224 printf(" vertexes transformed %7d %8.3f %10.3f\n",
225 ctx->VertexCount, ctx->VertexTime, vertexrate );
226 printf(" points rasterized %7d %8.3f %10.3f\n",
227 ctx->PointCount, ctx->PointTime, pointrate );
228 printf(" lines rasterized %7d %8.3f %10.3f\n",
229 ctx->LineCount, ctx->LineTime, linerate );
230 printf(" polygons rasterized %7d %8.3f %10.3f\n",
231 ctx->PolygonCount, ctx->PolygonTime, polygonrate );
232 printf(" overhead %8.3f\n", overhead );
233 printf("glClear %7d %8.3f %10.3f\n",
234 ctx->ClearCount, ctx->ClearTime, clearrate );
235 printf("SwapBuffers %7d %8.3f %10.3f\n",
236 ctx->SwapCount, ctx->SwapTime, swaprate );
237 printf("\n");
238
239 printf("Average number of vertices per begin/end: %8.3f\n", avgvertices );
240}
241#endif
242
243
244
245
246
247/**********************************************************************/
Brian Paul4d053dd2000-01-14 04:45:47 +0000248/***** GL Visual allocation/destruction *****/
249/**********************************************************************/
250
251
252/*
253 * Allocate a new GLvisual object.
254 * Input: rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode
255 * alphaFlag - alloc software alpha buffers?
256 * dbFlag - double buffering?
257 * stereoFlag - stereo buffer?
Brian Pauled30dfa2000-03-03 17:47:39 +0000258 * depthBits - requested bits per depth buffer value
259 * Any value in [0, 32] is acceptable but the actual
260 * depth type will be GLushort or GLuint as needed.
261 * stencilBits - requested minimum bits per stencil buffer value
262 * accumBits - requested minimum bits per accum buffer component
263 * indexBits - number of bits per pixel if rgbFlag==GL_FALSE
264 * red/green/blue/alphaBits - number of bits per color component
265 * in frame buffer for RGB(A) mode.
266 * We always use 8 in core Mesa though.
Brian Paul4d053dd2000-01-14 04:45:47 +0000267 * Return: pointer to new GLvisual or NULL if requested parameters can't
268 * be met.
269 */
270GLvisual *gl_create_visual( GLboolean rgbFlag,
271 GLboolean alphaFlag,
272 GLboolean dbFlag,
273 GLboolean stereoFlag,
274 GLint depthBits,
275 GLint stencilBits,
276 GLint accumBits,
277 GLint indexBits,
278 GLint redBits,
279 GLint greenBits,
280 GLint blueBits,
281 GLint alphaBits )
282{
283 GLvisual *vis;
284
Brian Pauled30dfa2000-03-03 17:47:39 +0000285 /* This is to catch bad values from device drivers not updated for
286 * Mesa 3.3. Some device drivers just passed 1. That's a REALLY
287 * bad value now (a 1-bit depth buffer!?!).
288 */
289 assert(depthBits == 0 || depthBits > 1);
290
291 if (depthBits < 0 || depthBits > 32) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000292 return NULL;
293 }
Brian Pauled30dfa2000-03-03 17:47:39 +0000294 if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000295 return NULL;
296 }
Brian Pauled30dfa2000-03-03 17:47:39 +0000297 if (accumBits < 0 || accumBits > (GLint) (8 * sizeof(GLaccum))) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000298 return NULL;
299 }
300
301 vis = (GLvisual *) CALLOC( sizeof(GLvisual) );
302 if (!vis) {
303 return NULL;
304 }
305
306 vis->RGBAflag = rgbFlag;
307 vis->DBflag = dbFlag;
308 vis->StereoFlag = stereoFlag;
309 vis->RedBits = redBits;
310 vis->GreenBits = greenBits;
311 vis->BlueBits = blueBits;
Brian Pauled30dfa2000-03-03 17:47:39 +0000312 vis->AlphaBits = alphaFlag ? (8 * sizeof(GLubyte)) : alphaBits;
Brian Paul4d053dd2000-01-14 04:45:47 +0000313
314 vis->IndexBits = indexBits;
Brian Pauled30dfa2000-03-03 17:47:39 +0000315 vis->DepthBits = depthBits;
316 vis->AccumBits = (accumBits > 0) ? (8 * sizeof(GLaccum)) : 0;
317 vis->StencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0;
Brian Paul4d053dd2000-01-14 04:45:47 +0000318
319 vis->SoftwareAlpha = alphaFlag;
320
Brian Pauled30dfa2000-03-03 17:47:39 +0000321 if (depthBits == 0) {
322 /* Special case. Even if we don't have a depth buffer we need
323 * good values for DepthMax for Z vertex transformation purposes.
324 */
325 vis->DepthMax = 1;
326 vis->DepthMaxF = 1.0F;
327 }
328 else {
329 vis->DepthMax = (1 << depthBits) - 1;
330 vis->DepthMaxF = (GLfloat) vis->DepthMax;
331 }
332
Brian Paul4d053dd2000-01-14 04:45:47 +0000333 return vis;
334}
335
336
337
338void gl_destroy_visual( GLvisual *vis )
339{
340 FREE( vis );
341}
342
343
344
345/**********************************************************************/
346/***** GL Framebuffer allocation/destruction *****/
347/**********************************************************************/
348
349
350/*
351 * Create a new framebuffer. A GLframebuffer is a struct which
352 * encapsulates the depth, stencil and accum buffers and related
353 * parameters.
354 * Input: visual - a GLvisual pointer
355 * softwareDepth - create/use a software depth buffer?
356 * softwareStencil - create/use a software stencil buffer?
357 * softwareAccum - create/use a software accum buffer?
358 * softwareAlpha - create/use a software alpha buffer?
359
360 * Return: pointer to new GLframebuffer struct or NULL if error.
361 */
362GLframebuffer *gl_create_framebuffer( GLvisual *visual,
363 GLboolean softwareDepth,
364 GLboolean softwareStencil,
365 GLboolean softwareAccum,
366 GLboolean softwareAlpha )
367{
368 GLframebuffer *buffer;
369
370 buffer = CALLOC_STRUCT(gl_frame_buffer);
371 if (!buffer) {
372 return NULL;
373 }
374
375 /* sanity checks */
376 if (softwareDepth ) {
377 assert(visual->DepthBits > 0);
378 }
379 if (softwareStencil) {
380 assert(visual->StencilBits > 0);
381 }
382 if (softwareAccum) {
383 assert(visual->RGBAflag);
384 assert(visual->AccumBits > 0);
385 }
386 if (softwareAlpha) {
387 assert(visual->RGBAflag);
388 assert(visual->AlphaBits > 0);
389 }
390
391 buffer->Visual = visual;
392 buffer->UseSoftwareDepthBuffer = softwareDepth;
393 buffer->UseSoftwareStencilBuffer = softwareStencil;
394 buffer->UseSoftwareAccumBuffer = softwareAccum;
395 buffer->UseSoftwareAlphaBuffers = softwareAlpha;
396
397 return buffer;
398}
399
400
401
402/*
403 * Free a framebuffer struct and its buffers.
404 */
405void gl_destroy_framebuffer( GLframebuffer *buffer )
406{
407 if (buffer) {
408 if (buffer->Depth) {
409 FREE( buffer->Depth );
410 }
411 if (buffer->Accum) {
412 FREE( buffer->Accum );
413 }
414 if (buffer->Stencil) {
415 FREE( buffer->Stencil );
416 }
417 if (buffer->FrontLeftAlpha) {
418 FREE( buffer->FrontLeftAlpha );
419 }
420 if (buffer->BackLeftAlpha) {
421 FREE( buffer->BackLeftAlpha );
422 }
423 if (buffer->FrontRightAlpha) {
424 FREE( buffer->FrontRightAlpha );
425 }
426 if (buffer->BackRightAlpha) {
427 FREE( buffer->BackRightAlpha );
428 }
429 FREE(buffer);
430 }
431}
432
433
434
435/**********************************************************************/
jtgafb833d1999-08-19 00:55:39 +0000436/***** Context allocation, initialization, destroying *****/
437/**********************************************************************/
438
439
Brian Paul9560f052000-01-31 23:11:39 +0000440_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
441
442
jtgafb833d1999-08-19 00:55:39 +0000443/*
444 * This function just calls all the various one-time-init functions in Mesa.
445 */
446static void one_time_init( void )
447{
448 static GLboolean alreadyCalled = GL_FALSE;
Brian Paul9560f052000-01-31 23:11:39 +0000449 _glthread_LOCK_MUTEX(OneTimeLock);
jtgafb833d1999-08-19 00:55:39 +0000450 if (!alreadyCalled) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000451 /* do some implementation tests */
452 assert( sizeof(GLbyte) == 1 );
453 assert( sizeof(GLshort) >= 2 );
454 assert( sizeof(GLint) >= 4 );
455 assert( sizeof(GLubyte) == 1 );
456 assert( sizeof(GLushort) >= 2 );
457 assert( sizeof(GLuint) >= 4 );
458
jtgafb833d1999-08-19 00:55:39 +0000459 gl_init_clip();
460 gl_init_eval();
Brian Paul5829f0c2000-02-02 22:21:39 +0000461 _mesa_init_fog();
jtgafb833d1999-08-19 00:55:39 +0000462 gl_init_math();
463 gl_init_lists();
464 gl_init_shade();
465 gl_init_texture();
466 gl_init_transformation();
467 gl_init_translate();
468 gl_init_vbrender();
469 gl_init_vbxform();
Keith Whitwell38756791999-08-29 10:26:31 +0000470 gl_init_vertices();
Brian Paul68ee4bc2000-01-28 19:02:22 +0000471
472 if (getenv("MESA_DEBUG")) {
473 _glapi_noop_enable_warnings(GL_TRUE);
474 }
475 else {
476 _glapi_noop_enable_warnings(GL_FALSE);
477 }
478
jtgafb833d1999-08-19 00:55:39 +0000479#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__)
480 fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__);
481#endif
Brian Paul68ee4bc2000-01-28 19:02:22 +0000482
483 alreadyCalled = GL_TRUE;
484 }
Brian Paul9560f052000-01-31 23:11:39 +0000485 _glthread_UNLOCK_MUTEX(OneTimeLock);
jtgafb833d1999-08-19 00:55:39 +0000486}
487
488
Brian Paul4d053dd2000-01-14 04:45:47 +0000489
jtgafb833d1999-08-19 00:55:39 +0000490/*
491 * Allocate and initialize a shared context state structure.
492 */
493static struct gl_shared_state *alloc_shared_state( void )
494{
Brian Paul6e6d4c61999-10-09 20:17:07 +0000495 GLuint d;
jtgafb833d1999-08-19 00:55:39 +0000496 struct gl_shared_state *ss;
497 GLboolean outOfMemory;
498
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000499 ss = CALLOC_STRUCT(gl_shared_state);
jtgafb833d1999-08-19 00:55:39 +0000500 if (!ss)
501 return NULL;
502
Brian Paulbb797902000-01-24 16:19:54 +0000503 ss->DisplayList = _mesa_NewHashTable();
jtgafb833d1999-08-19 00:55:39 +0000504
Brian Paulbb797902000-01-24 16:19:54 +0000505 ss->TexObjects = _mesa_NewHashTable();
jtgafb833d1999-08-19 00:55:39 +0000506
507 /* Default Texture objects */
508 outOfMemory = GL_FALSE;
Brian Paul6e6d4c61999-10-09 20:17:07 +0000509 for (d = 1 ; d <= 3 ; d++) {
510 ss->DefaultD[d] = gl_alloc_texture_object(ss, 0, d);
511 if (!ss->DefaultD[d]) {
512 outOfMemory = GL_TRUE;
513 break;
jtgafb833d1999-08-19 00:55:39 +0000514 }
Brian Paul6e6d4c61999-10-09 20:17:07 +0000515 ss->DefaultD[d]->RefCount++; /* don't free if not in use */
jtgafb833d1999-08-19 00:55:39 +0000516 }
517
518 if (!ss->DisplayList || !ss->TexObjects || outOfMemory) {
519 /* Ran out of memory at some point. Free everything and return NULL */
520 if (ss->DisplayList)
Brian Paulbb797902000-01-24 16:19:54 +0000521 _mesa_DeleteHashTable(ss->DisplayList);
jtgafb833d1999-08-19 00:55:39 +0000522 if (ss->TexObjects)
Brian Paulbb797902000-01-24 16:19:54 +0000523 _mesa_DeleteHashTable(ss->TexObjects);
Brian Paul6e6d4c61999-10-09 20:17:07 +0000524 if (ss->DefaultD[1])
525 gl_free_texture_object(ss, ss->DefaultD[1]);
526 if (ss->DefaultD[2])
527 gl_free_texture_object(ss, ss->DefaultD[2]);
528 if (ss->DefaultD[3])
529 gl_free_texture_object(ss, ss->DefaultD[3]);
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000530 FREE(ss);
jtgafb833d1999-08-19 00:55:39 +0000531 return NULL;
532 }
533 else {
534 return ss;
535 }
536}
537
538
539/*
540 * Deallocate a shared state context and all children structures.
541 */
542static void free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
543{
544 /* Free display lists */
545 while (1) {
Brian Paulbb797902000-01-24 16:19:54 +0000546 GLuint list = _mesa_HashFirstEntry(ss->DisplayList);
jtgafb833d1999-08-19 00:55:39 +0000547 if (list) {
548 gl_destroy_list(ctx, list);
549 }
550 else {
551 break;
552 }
553 }
Brian Paulbb797902000-01-24 16:19:54 +0000554 _mesa_DeleteHashTable(ss->DisplayList);
jtgafb833d1999-08-19 00:55:39 +0000555
556 /* Free texture objects */
557 while (ss->TexObjectList)
558 {
559 if (ctx->Driver.DeleteTexture)
560 (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
561 /* this function removes from linked list too! */
562 gl_free_texture_object(ss, ss->TexObjectList);
563 }
Brian Paulbb797902000-01-24 16:19:54 +0000564 _mesa_DeleteHashTable(ss->TexObjects);
jtgafb833d1999-08-19 00:55:39 +0000565
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000566 FREE(ss);
jtgafb833d1999-08-19 00:55:39 +0000567}
568
569
570
jtgafb833d1999-08-19 00:55:39 +0000571/*
572 * Initialize the nth light. Note that the defaults for light 0 are
573 * different than the other lights.
574 */
575static void init_light( struct gl_light *l, GLuint n )
576{
577 make_empty_list( l );
578
579 ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 );
580 if (n==0) {
581 ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 );
582 ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 );
583 }
584 else {
585 ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 );
586 ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 );
587 }
588 ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 );
589 ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 );
590 l->SpotExponent = 0.0;
591 gl_compute_spot_exp_table( l );
592 l->SpotCutoff = 180.0;
593 l->CosCutoff = 0.0; /* KW: -ve values not admitted */
594 l->ConstantAttenuation = 1.0;
595 l->LinearAttenuation = 0.0;
596 l->QuadraticAttenuation = 0.0;
597 l->Enabled = GL_FALSE;
598}
599
600
601
602static void init_lightmodel( struct gl_lightmodel *lm )
603{
604 ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 );
605 lm->LocalViewer = GL_FALSE;
606 lm->TwoSide = GL_FALSE;
607 lm->ColorControl = GL_SINGLE_COLOR;
608}
609
610
611static void init_material( struct gl_material *m )
612{
613 ASSIGN_4V( m->Ambient, 0.2, 0.2, 0.2, 1.0 );
614 ASSIGN_4V( m->Diffuse, 0.8, 0.8, 0.8, 1.0 );
615 ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 );
616 ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 );
617 m->Shininess = 0.0;
618 m->AmbientIndex = 0;
619 m->DiffuseIndex = 1;
620 m->SpecularIndex = 1;
621}
622
623
624
625static void init_texture_unit( GLcontext *ctx, GLuint unit )
626{
627 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
628
629 texUnit->EnvMode = GL_MODULATE;
630 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
631 texUnit->TexGenEnabled = 0;
632 texUnit->GenModeS = GL_EYE_LINEAR;
633 texUnit->GenModeT = GL_EYE_LINEAR;
634 texUnit->GenModeR = GL_EYE_LINEAR;
635 texUnit->GenModeQ = GL_EYE_LINEAR;
636 /* Yes, these plane coefficients are correct! */
637 ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
638 ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
639 ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
640 ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
641 ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
642 ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
643 ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
644 ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
645
Brian Paul6e6d4c61999-10-09 20:17:07 +0000646 texUnit->CurrentD[1] = ctx->Shared->DefaultD[1];
647 texUnit->CurrentD[2] = ctx->Shared->DefaultD[2];
648 texUnit->CurrentD[3] = ctx->Shared->DefaultD[3];
jtgafb833d1999-08-19 00:55:39 +0000649}
650
651
652static void init_fallback_arrays( GLcontext *ctx )
653{
654 struct gl_client_array *cl;
655 GLuint i;
656
657 cl = &ctx->Fallback.Normal;
658 cl->Size = 3;
659 cl->Type = GL_FLOAT;
660 cl->Stride = 0;
661 cl->StrideB = 0;
662 cl->Ptr = (void *) ctx->Current.Normal;
663 cl->Enabled = 1;
664
665 cl = &ctx->Fallback.Color;
666 cl->Size = 4;
667 cl->Type = GL_UNSIGNED_BYTE;
668 cl->Stride = 0;
669 cl->StrideB = 0;
670 cl->Ptr = (void *) ctx->Current.ByteColor;
671 cl->Enabled = 1;
672
673 cl = &ctx->Fallback.Index;
674 cl->Size = 1;
675 cl->Type = GL_UNSIGNED_INT;
676 cl->Stride = 0;
677 cl->StrideB = 0;
678 cl->Ptr = (void *) &ctx->Current.Index;
679 cl->Enabled = 1;
680
681 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
682 cl = &ctx->Fallback.TexCoord[i];
683 cl->Size = 4;
684 cl->Type = GL_FLOAT;
685 cl->Stride = 0;
686 cl->StrideB = 0;
687 cl->Ptr = (void *) ctx->Current.Texcoord[i];
688 cl->Enabled = 1;
689 }
690
691 cl = &ctx->Fallback.EdgeFlag;
692 cl->Size = 1;
693 cl->Type = GL_UNSIGNED_BYTE;
694 cl->Stride = 0;
695 cl->StrideB = 0;
696 cl->Ptr = (void *) &ctx->Current.EdgeFlag;
697 cl->Enabled = 1;
698}
699
Brian Paul4d053dd2000-01-14 04:45:47 +0000700
jtgafb833d1999-08-19 00:55:39 +0000701/* Initialize a 1-D evaluator map */
702static void init_1d_map( struct gl_1d_map *map, int n, const float *initial )
703{
704 map->Order = 1;
705 map->u1 = 0.0;
706 map->u2 = 1.0;
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000707 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
jtgafb833d1999-08-19 00:55:39 +0000708 if (map->Points) {
709 GLint i;
710 for (i=0;i<n;i++)
711 map->Points[i] = initial[i];
712 }
jtgafb833d1999-08-19 00:55:39 +0000713}
714
715
716/* Initialize a 2-D evaluator map */
717static void init_2d_map( struct gl_2d_map *map, int n, const float *initial )
718{
719 map->Uorder = 1;
720 map->Vorder = 1;
721 map->u1 = 0.0;
722 map->u2 = 1.0;
723 map->v1 = 0.0;
724 map->v2 = 1.0;
Brian Paulbd5cdaf1999-10-13 18:42:49 +0000725 map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat));
jtgafb833d1999-08-19 00:55:39 +0000726 if (map->Points) {
727 GLint i;
728 for (i=0;i<n;i++)
729 map->Points[i] = initial[i];
730 }
jtgafb833d1999-08-19 00:55:39 +0000731}
732
733
Brian Paulf0dee651999-11-19 22:51:29 +0000734static void init_color_table( struct gl_color_table *p )
Brian Paulfbd8f211999-11-11 01:22:25 +0000735{
736 p->Table[0] = 255;
737 p->Table[1] = 255;
738 p->Table[2] = 255;
739 p->Table[3] = 255;
740 p->Size = 1;
741 p->IntFormat = GL_RGBA;
742 p->Format = GL_RGBA;
743}
744
jtgafb833d1999-08-19 00:55:39 +0000745
746/*
Brian Paul4d053dd2000-01-14 04:45:47 +0000747 * Initialize the attribute groups in a GLcontext.
jtgafb833d1999-08-19 00:55:39 +0000748 */
Brian Paul4d053dd2000-01-14 04:45:47 +0000749static void init_attrib_groups( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +0000750{
751 GLuint i, j;
752
Brian Paul4d053dd2000-01-14 04:45:47 +0000753 assert(ctx);
jtgafb833d1999-08-19 00:55:39 +0000754
Brian Paul539cce52000-02-03 19:40:07 +0000755 /* Constants, may be overriden by device drivers */
Brian Paul4d053dd2000-01-14 04:45:47 +0000756 ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS;
757 ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
758 ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
759 ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
Brian Paul539cce52000-02-03 19:40:07 +0000760 ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
761 ctx->Const.MinPointSize = MIN_POINT_SIZE;
762 ctx->Const.MaxPointSize = MAX_POINT_SIZE;
763 ctx->Const.MinPointSizeAA = MIN_POINT_SIZE;
764 ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE;
765 ctx->Const.PointSizeGranularity = POINT_SIZE_GRANULARITY;
766 ctx->Const.MinLineWidth = MIN_LINE_WIDTH;
767 ctx->Const.MaxLineWidth = MAX_LINE_WIDTH;
768 ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH;
769 ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH;
770 ctx->Const.LineWidthGranularity = LINE_WIDTH_GRANULARITY;
771 ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS;
jtgafb833d1999-08-19 00:55:39 +0000772
Brian Paul4d053dd2000-01-14 04:45:47 +0000773 /* Modelview matrix */
774 gl_matrix_ctr( &ctx->ModelView );
775 gl_matrix_alloc_inv( &ctx->ModelView );
776
777 ctx->ModelViewStackDepth = 0;
Brian Paul7fc29c52000-03-06 17:03:03 +0000778 for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000779 gl_matrix_ctr( &ctx->ModelViewStack[i] );
780 gl_matrix_alloc_inv( &ctx->ModelViewStack[i] );
781 }
782
783 /* Projection matrix - need inv for user clipping in clip space*/
784 gl_matrix_ctr( &ctx->ProjectionMatrix );
785 gl_matrix_alloc_inv( &ctx->ProjectionMatrix );
786
787 gl_matrix_ctr( &ctx->ModelProjectMatrix );
788 gl_matrix_ctr( &ctx->ModelProjectWinMatrix );
789 ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
790
791 ctx->ProjectionStackDepth = 0;
792 ctx->NearFarStack[0][0] = 1.0; /* These values seem weird by make */
793 ctx->NearFarStack[0][1] = 0.0; /* sense mathematically. */
794
Brian Paul7fc29c52000-03-06 17:03:03 +0000795 for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000796 gl_matrix_ctr( &ctx->ProjectionStack[i] );
797 gl_matrix_alloc_inv( &ctx->ProjectionStack[i] );
798 }
799
800 /* Texture matrix */
801 for (i=0; i<MAX_TEXTURE_UNITS; i++) {
802 gl_matrix_ctr( &ctx->TextureMatrix[i] );
803 ctx->TextureStackDepth[i] = 0;
Brian Paul7fc29c52000-03-06 17:03:03 +0000804 for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
Brian Paul4d053dd2000-01-14 04:45:47 +0000805 ctx->TextureStack[i][j].inv = 0;
jtgafb833d1999-08-19 00:55:39 +0000806 }
Brian Paul4d053dd2000-01-14 04:45:47 +0000807 }
jtgafb833d1999-08-19 00:55:39 +0000808
Brian Paul4d053dd2000-01-14 04:45:47 +0000809 /* Accumulate buffer group */
810 ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 );
jtgafb833d1999-08-19 00:55:39 +0000811
Brian Paul4d053dd2000-01-14 04:45:47 +0000812 /* Color buffer group */
813 ctx->Color.IndexMask = 0xffffffff;
814 ctx->Color.ColorMask[0] = 0xff;
815 ctx->Color.ColorMask[1] = 0xff;
816 ctx->Color.ColorMask[2] = 0xff;
817 ctx->Color.ColorMask[3] = 0xff;
818 ctx->Color.SWmasking = GL_FALSE;
819 ctx->Color.ClearIndex = 0;
820 ASSIGN_4V( ctx->Color.ClearColor, 0.0, 0.0, 0.0, 0.0 );
821 ctx->Color.DrawBuffer = GL_FRONT;
822 ctx->Color.AlphaEnabled = GL_FALSE;
823 ctx->Color.AlphaFunc = GL_ALWAYS;
824 ctx->Color.AlphaRef = 0;
825 ctx->Color.BlendEnabled = GL_FALSE;
826 ctx->Color.BlendSrcRGB = GL_ONE;
827 ctx->Color.BlendDstRGB = GL_ZERO;
828 ctx->Color.BlendSrcA = GL_ONE;
829 ctx->Color.BlendDstA = GL_ZERO;
830 ctx->Color.BlendEquation = GL_FUNC_ADD_EXT;
831 ctx->Color.BlendFunc = NULL; /* this pointer set only when needed */
832 ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 );
833 ctx->Color.IndexLogicOpEnabled = GL_FALSE;
834 ctx->Color.ColorLogicOpEnabled = GL_FALSE;
835 ctx->Color.SWLogicOpEnabled = GL_FALSE;
836 ctx->Color.LogicOp = GL_COPY;
837 ctx->Color.DitherFlag = GL_TRUE;
838 ctx->Color.MultiDrawBuffer = GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +0000839
Brian Paul4d053dd2000-01-14 04:45:47 +0000840 /* Current group */
841 ASSIGN_4V( ctx->Current.ByteColor, 255, 255, 255, 255);
842 ctx->Current.Index = 1;
843 for (i=0; i<MAX_TEXTURE_UNITS; i++)
844 ASSIGN_4V( ctx->Current.Texcoord[i], 0.0, 0.0, 0.0, 1.0 );
845 ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 );
846 ctx->Current.RasterDistance = 0.0;
847 ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 );
848 ctx->Current.RasterIndex = 1;
849 for (i=0; i<MAX_TEXTURE_UNITS; i++)
850 ASSIGN_4V( ctx->Current.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 );
851 ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0];
852 ctx->Current.RasterPosValid = GL_TRUE;
853 ctx->Current.EdgeFlag = GL_TRUE;
854 ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 );
855 ctx->Current.Primitive = (GLenum) (GL_POLYGON + 1);
jtgafb833d1999-08-19 00:55:39 +0000856
Brian Paul4d053dd2000-01-14 04:45:47 +0000857 ctx->Current.Flag = (VERT_NORM|VERT_INDEX|VERT_RGBA|VERT_EDGE|
858 VERT_TEX0_1|VERT_TEX1_1|VERT_MATERIAL);
jtgafb833d1999-08-19 00:55:39 +0000859
Brian Paul4d053dd2000-01-14 04:45:47 +0000860 init_fallback_arrays( ctx );
jtgafb833d1999-08-19 00:55:39 +0000861
Brian Paul4d053dd2000-01-14 04:45:47 +0000862 /* Depth buffer group */
863 ctx->Depth.Test = GL_FALSE;
864 ctx->Depth.Clear = 1.0;
865 ctx->Depth.Func = GL_LESS;
866 ctx->Depth.Mask = GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +0000867
Brian Paul4d053dd2000-01-14 04:45:47 +0000868 /* Evaluators group */
869 ctx->Eval.Map1Color4 = GL_FALSE;
870 ctx->Eval.Map1Index = GL_FALSE;
871 ctx->Eval.Map1Normal = GL_FALSE;
872 ctx->Eval.Map1TextureCoord1 = GL_FALSE;
873 ctx->Eval.Map1TextureCoord2 = GL_FALSE;
874 ctx->Eval.Map1TextureCoord3 = GL_FALSE;
875 ctx->Eval.Map1TextureCoord4 = GL_FALSE;
876 ctx->Eval.Map1Vertex3 = GL_FALSE;
877 ctx->Eval.Map1Vertex4 = GL_FALSE;
878 ctx->Eval.Map2Color4 = GL_FALSE;
879 ctx->Eval.Map2Index = GL_FALSE;
880 ctx->Eval.Map2Normal = GL_FALSE;
881 ctx->Eval.Map2TextureCoord1 = GL_FALSE;
882 ctx->Eval.Map2TextureCoord2 = GL_FALSE;
883 ctx->Eval.Map2TextureCoord3 = GL_FALSE;
884 ctx->Eval.Map2TextureCoord4 = GL_FALSE;
885 ctx->Eval.Map2Vertex3 = GL_FALSE;
886 ctx->Eval.Map2Vertex4 = GL_FALSE;
887 ctx->Eval.AutoNormal = GL_FALSE;
888 ctx->Eval.MapGrid1un = 1;
889 ctx->Eval.MapGrid1u1 = 0.0;
890 ctx->Eval.MapGrid1u2 = 1.0;
891 ctx->Eval.MapGrid2un = 1;
892 ctx->Eval.MapGrid2vn = 1;
893 ctx->Eval.MapGrid2u1 = 0.0;
894 ctx->Eval.MapGrid2u2 = 1.0;
895 ctx->Eval.MapGrid2v1 = 0.0;
896 ctx->Eval.MapGrid2v2 = 1.0;
jtgafb833d1999-08-19 00:55:39 +0000897
Brian Paul4d053dd2000-01-14 04:45:47 +0000898 /* Evaluator data */
899 {
900 static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
901 static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
902 static GLfloat index[1] = { 1.0 };
903 static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
904 static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
jtgafb833d1999-08-19 00:55:39 +0000905
Brian Paul4d053dd2000-01-14 04:45:47 +0000906 init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
907 init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
908 init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
909 init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
910 init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
911 init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
912 init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
913 init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
914 init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
jtgafb833d1999-08-19 00:55:39 +0000915
Brian Paul4d053dd2000-01-14 04:45:47 +0000916 init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
917 init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
918 init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
919 init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
920 init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
921 init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
922 init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
923 init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
924 init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
925 }
jtgafb833d1999-08-19 00:55:39 +0000926
Brian Paul4d053dd2000-01-14 04:45:47 +0000927 /* Fog group */
928 ctx->Fog.Enabled = GL_FALSE;
929 ctx->Fog.Mode = GL_EXP;
930 ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 );
931 ctx->Fog.Index = 0.0;
932 ctx->Fog.Density = 1.0;
933 ctx->Fog.Start = 0.0;
934 ctx->Fog.End = 1.0;
jtgafb833d1999-08-19 00:55:39 +0000935
Brian Paul4d053dd2000-01-14 04:45:47 +0000936 /* Hint group */
937 ctx->Hint.PerspectiveCorrection = GL_DONT_CARE;
938 ctx->Hint.PointSmooth = GL_DONT_CARE;
939 ctx->Hint.LineSmooth = GL_DONT_CARE;
940 ctx->Hint.PolygonSmooth = GL_DONT_CARE;
941 ctx->Hint.Fog = GL_DONT_CARE;
jtgafb833d1999-08-19 00:55:39 +0000942
Brian Paul4d053dd2000-01-14 04:45:47 +0000943 ctx->Hint.AllowDrawWin = GL_TRUE;
944 ctx->Hint.AllowDrawSpn = GL_TRUE;
945 ctx->Hint.AllowDrawMem = GL_TRUE;
946 ctx->Hint.StrictLighting = GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +0000947
Brian Paul4d053dd2000-01-14 04:45:47 +0000948 /* Pipeline */
949 gl_pipeline_init( ctx );
950 gl_cva_init( ctx );
jtgafb833d1999-08-19 00:55:39 +0000951
Brian Paul4d053dd2000-01-14 04:45:47 +0000952 /* Extensions */
953 gl_extensions_ctr( ctx );
jtgafb833d1999-08-19 00:55:39 +0000954
Brian Paul4d053dd2000-01-14 04:45:47 +0000955 ctx->AllowVertexCull = CLIP_CULLED_BIT;
jtgafb833d1999-08-19 00:55:39 +0000956
Brian Paul4d053dd2000-01-14 04:45:47 +0000957 /* Lighting group */
958 for (i=0;i<MAX_LIGHTS;i++) {
959 init_light( &ctx->Light.Light[i], i );
960 }
961 make_empty_list( &ctx->Light.EnabledList );
jtgafb833d1999-08-19 00:55:39 +0000962
Brian Paul4d053dd2000-01-14 04:45:47 +0000963 init_lightmodel( &ctx->Light.Model );
964 init_material( &ctx->Light.Material[0] );
965 init_material( &ctx->Light.Material[1] );
966 ctx->Light.ShadeModel = GL_SMOOTH;
967 ctx->Light.Enabled = GL_FALSE;
968 ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
969 ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
970 ctx->Light.ColorMaterialBitmask
971 = gl_material_bitmask( ctx,
972 GL_FRONT_AND_BACK,
973 GL_AMBIENT_AND_DIFFUSE, ~0, 0 );
jtgafb833d1999-08-19 00:55:39 +0000974
Brian Paul4d053dd2000-01-14 04:45:47 +0000975 ctx->Light.ColorMaterialEnabled = GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +0000976
Brian Paul4d053dd2000-01-14 04:45:47 +0000977 /* Lighting miscellaneous */
978 ctx->ShineTabList = MALLOC_STRUCT( gl_shine_tab );
979 make_empty_list( ctx->ShineTabList );
980 for (i = 0 ; i < 10 ; i++) {
981 struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab );
982 s->shininess = -1;
983 s->refcount = 0;
984 insert_at_tail( ctx->ShineTabList, s );
985 }
986 for (i = 0 ; i < 4 ; i++) {
987 ctx->ShineTable[i] = ctx->ShineTabList->prev;
988 ctx->ShineTable[i]->refcount++;
989 }
jtgafb833d1999-08-19 00:55:39 +0000990
jtgafb833d1999-08-19 00:55:39 +0000991
Brian Paul4d053dd2000-01-14 04:45:47 +0000992 /* Line group */
993 ctx->Line.SmoothFlag = GL_FALSE;
994 ctx->Line.StippleFlag = GL_FALSE;
995 ctx->Line.Width = 1.0;
996 ctx->Line.StipplePattern = 0xffff;
997 ctx->Line.StippleFactor = 1;
jtgafb833d1999-08-19 00:55:39 +0000998
Brian Paul4d053dd2000-01-14 04:45:47 +0000999 /* Display List group */
1000 ctx->List.ListBase = 0;
jtgafb833d1999-08-19 00:55:39 +00001001
Brian Paul4d053dd2000-01-14 04:45:47 +00001002 /* Pixel group */
1003 ctx->Pixel.RedBias = 0.0;
1004 ctx->Pixel.RedScale = 1.0;
1005 ctx->Pixel.GreenBias = 0.0;
1006 ctx->Pixel.GreenScale = 1.0;
1007 ctx->Pixel.BlueBias = 0.0;
1008 ctx->Pixel.BlueScale = 1.0;
1009 ctx->Pixel.AlphaBias = 0.0;
1010 ctx->Pixel.AlphaScale = 1.0;
1011 ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
1012 ctx->Pixel.DepthBias = 0.0;
1013 ctx->Pixel.DepthScale = 1.0;
1014 ctx->Pixel.IndexOffset = 0;
1015 ctx->Pixel.IndexShift = 0;
1016 ctx->Pixel.ZoomX = 1.0;
1017 ctx->Pixel.ZoomY = 1.0;
1018 ctx->Pixel.MapColorFlag = GL_FALSE;
1019 ctx->Pixel.MapStencilFlag = GL_FALSE;
1020 ctx->Pixel.MapStoSsize = 1;
1021 ctx->Pixel.MapItoIsize = 1;
1022 ctx->Pixel.MapItoRsize = 1;
1023 ctx->Pixel.MapItoGsize = 1;
1024 ctx->Pixel.MapItoBsize = 1;
1025 ctx->Pixel.MapItoAsize = 1;
1026 ctx->Pixel.MapRtoRsize = 1;
1027 ctx->Pixel.MapGtoGsize = 1;
1028 ctx->Pixel.MapBtoBsize = 1;
1029 ctx->Pixel.MapAtoAsize = 1;
1030 ctx->Pixel.MapStoS[0] = 0;
1031 ctx->Pixel.MapItoI[0] = 0;
1032 ctx->Pixel.MapItoR[0] = 0.0;
1033 ctx->Pixel.MapItoG[0] = 0.0;
1034 ctx->Pixel.MapItoB[0] = 0.0;
1035 ctx->Pixel.MapItoA[0] = 0.0;
1036 ctx->Pixel.MapItoR8[0] = 0;
1037 ctx->Pixel.MapItoG8[0] = 0;
1038 ctx->Pixel.MapItoB8[0] = 0;
1039 ctx->Pixel.MapItoA8[0] = 0;
1040 ctx->Pixel.MapRtoR[0] = 0.0;
1041 ctx->Pixel.MapGtoG[0] = 0.0;
1042 ctx->Pixel.MapBtoB[0] = 0.0;
1043 ctx->Pixel.MapAtoA[0] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001044
Brian Paul4d053dd2000-01-14 04:45:47 +00001045 /* Point group */
1046 ctx->Point.SmoothFlag = GL_FALSE;
1047 ctx->Point.Size = 1.0;
1048 ctx->Point.Params[0] = 1.0;
1049 ctx->Point.Params[1] = 0.0;
1050 ctx->Point.Params[2] = 0.0;
1051 ctx->Point.Attenuated = GL_FALSE;
1052 ctx->Point.MinSize = 0.0;
1053 ctx->Point.MaxSize = (GLfloat) MAX_POINT_SIZE;
1054 ctx->Point.Threshold = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001055
Brian Paul4d053dd2000-01-14 04:45:47 +00001056 /* Polygon group */
1057 ctx->Polygon.CullFlag = GL_FALSE;
1058 ctx->Polygon.CullFaceMode = GL_BACK;
1059 ctx->Polygon.FrontFace = GL_CCW;
1060 ctx->Polygon.FrontBit = 0;
1061 ctx->Polygon.FrontMode = GL_FILL;
1062 ctx->Polygon.BackMode = GL_FILL;
1063 ctx->Polygon.Unfilled = GL_FALSE;
1064 ctx->Polygon.SmoothFlag = GL_FALSE;
1065 ctx->Polygon.StippleFlag = GL_FALSE;
1066 ctx->Polygon.OffsetFactor = 0.0F;
1067 ctx->Polygon.OffsetUnits = 0.0F;
1068 ctx->Polygon.OffsetPoint = GL_FALSE;
1069 ctx->Polygon.OffsetLine = GL_FALSE;
1070 ctx->Polygon.OffsetFill = GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001071
Brian Paul4d053dd2000-01-14 04:45:47 +00001072 /* Polygon Stipple group */
1073 MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) );
jtgafb833d1999-08-19 00:55:39 +00001074
Brian Paul4d053dd2000-01-14 04:45:47 +00001075 /* Scissor group */
1076 ctx->Scissor.Enabled = GL_FALSE;
1077 ctx->Scissor.X = 0;
1078 ctx->Scissor.Y = 0;
1079 ctx->Scissor.Width = 0;
1080 ctx->Scissor.Height = 0;
jtgafb833d1999-08-19 00:55:39 +00001081
Brian Paul4d053dd2000-01-14 04:45:47 +00001082 /* Stencil group */
1083 ctx->Stencil.Enabled = GL_FALSE;
1084 ctx->Stencil.Function = GL_ALWAYS;
1085 ctx->Stencil.FailFunc = GL_KEEP;
1086 ctx->Stencil.ZPassFunc = GL_KEEP;
1087 ctx->Stencil.ZFailFunc = GL_KEEP;
1088 ctx->Stencil.Ref = 0;
1089 ctx->Stencil.ValueMask = STENCIL_MAX;
1090 ctx->Stencil.Clear = 0;
1091 ctx->Stencil.WriteMask = STENCIL_MAX;
jtgafb833d1999-08-19 00:55:39 +00001092
Brian Paul4d053dd2000-01-14 04:45:47 +00001093 /* Texture group */
1094 ctx->Texture.CurrentUnit = 0; /* multitexture */
1095 ctx->Texture.CurrentTransformUnit = 0; /* multitexture */
1096 ctx->Texture.Enabled = 0;
1097 for (i=0; i<MAX_TEXTURE_UNITS; i++)
1098 init_texture_unit( ctx, i );
1099 init_color_table(&ctx->Texture.Palette);
jtgafb833d1999-08-19 00:55:39 +00001100
Brian Paul4d053dd2000-01-14 04:45:47 +00001101 /* Transformation group */
1102 ctx->Transform.MatrixMode = GL_MODELVIEW;
1103 ctx->Transform.Normalize = GL_FALSE;
1104 ctx->Transform.RescaleNormals = GL_FALSE;
1105 for (i=0;i<MAX_CLIP_PLANES;i++) {
1106 ctx->Transform.ClipEnabled[i] = GL_FALSE;
1107 ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 );
1108 }
1109 ctx->Transform.AnyClip = GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001110
Brian Paul4d053dd2000-01-14 04:45:47 +00001111 /* Viewport group */
1112 ctx->Viewport.X = 0;
1113 ctx->Viewport.Y = 0;
1114 ctx->Viewport.Width = 0;
1115 ctx->Viewport.Height = 0;
1116 ctx->Viewport.Near = 0.0;
1117 ctx->Viewport.Far = 1.0;
1118 gl_matrix_ctr(&ctx->Viewport.WindowMap);
jtgafb833d1999-08-19 00:55:39 +00001119
1120#define Sz 10
1121#define Tz 14
Brian Pauled30dfa2000-03-03 17:47:39 +00001122 ctx->Viewport.WindowMap.m[Sz] = 0.5 * ctx->Visual->DepthMaxF;
1123 ctx->Viewport.WindowMap.m[Tz] = 0.5 * ctx->Visual->DepthMaxF;
jtgafb833d1999-08-19 00:55:39 +00001124#undef Sz
1125#undef Tz
1126
Brian Paul4d053dd2000-01-14 04:45:47 +00001127 ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
1128 ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
jtgafb833d1999-08-19 00:55:39 +00001129
Brian Paul4d053dd2000-01-14 04:45:47 +00001130 /* Vertex arrays */
1131 ctx->Array.Vertex.Size = 4;
1132 ctx->Array.Vertex.Type = GL_FLOAT;
1133 ctx->Array.Vertex.Stride = 0;
1134 ctx->Array.Vertex.StrideB = 0;
1135 ctx->Array.Vertex.Ptr = NULL;
1136 ctx->Array.Vertex.Enabled = GL_FALSE;
1137 ctx->Array.Normal.Type = GL_FLOAT;
1138 ctx->Array.Normal.Stride = 0;
1139 ctx->Array.Normal.StrideB = 0;
1140 ctx->Array.Normal.Ptr = NULL;
1141 ctx->Array.Normal.Enabled = GL_FALSE;
1142 ctx->Array.Color.Size = 4;
1143 ctx->Array.Color.Type = GL_FLOAT;
1144 ctx->Array.Color.Stride = 0;
1145 ctx->Array.Color.StrideB = 0;
1146 ctx->Array.Color.Ptr = NULL;
1147 ctx->Array.Color.Enabled = GL_FALSE;
1148 ctx->Array.Index.Type = GL_FLOAT;
1149 ctx->Array.Index.Stride = 0;
1150 ctx->Array.Index.StrideB = 0;
1151 ctx->Array.Index.Ptr = NULL;
1152 ctx->Array.Index.Enabled = GL_FALSE;
1153 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1154 ctx->Array.TexCoord[i].Size = 4;
1155 ctx->Array.TexCoord[i].Type = GL_FLOAT;
1156 ctx->Array.TexCoord[i].Stride = 0;
1157 ctx->Array.TexCoord[i].StrideB = 0;
1158 ctx->Array.TexCoord[i].Ptr = NULL;
1159 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
1160 }
1161 ctx->Array.TexCoordInterleaveFactor = 1;
1162 ctx->Array.EdgeFlag.Stride = 0;
1163 ctx->Array.EdgeFlag.StrideB = 0;
1164 ctx->Array.EdgeFlag.Ptr = NULL;
1165 ctx->Array.EdgeFlag.Enabled = GL_FALSE;
1166 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1167
1168 /* Pixel transfer */
1169 ctx->Pack.Alignment = 4;
1170 ctx->Pack.RowLength = 0;
1171 ctx->Pack.ImageHeight = 0;
1172 ctx->Pack.SkipPixels = 0;
1173 ctx->Pack.SkipRows = 0;
1174 ctx->Pack.SkipImages = 0;
1175 ctx->Pack.SwapBytes = GL_FALSE;
1176 ctx->Pack.LsbFirst = GL_FALSE;
1177 ctx->Unpack.Alignment = 4;
1178 ctx->Unpack.RowLength = 0;
1179 ctx->Unpack.ImageHeight = 0;
1180 ctx->Unpack.SkipPixels = 0;
1181 ctx->Unpack.SkipRows = 0;
1182 ctx->Unpack.SkipImages = 0;
1183 ctx->Unpack.SwapBytes = GL_FALSE;
1184 ctx->Unpack.LsbFirst = GL_FALSE;
1185
1186 /* Feedback */
1187 ctx->Feedback.Type = GL_2D; /* TODO: verify */
1188 ctx->Feedback.Buffer = NULL;
1189 ctx->Feedback.BufferSize = 0;
1190 ctx->Feedback.Count = 0;
1191
1192 /* Selection/picking */
1193 ctx->Select.Buffer = NULL;
1194 ctx->Select.BufferSize = 0;
1195 ctx->Select.BufferCount = 0;
1196 ctx->Select.Hits = 0;
1197 ctx->Select.NameStackDepth = 0;
1198
1199 /* Optimized Accum buffer */
1200 ctx->IntegerAccumMode = GL_TRUE;
1201 ctx->IntegerAccumScaler = 0.0;
1202
1203 /* Renderer and client attribute stacks */
1204 ctx->AttribStackDepth = 0;
1205 ctx->ClientAttribStackDepth = 0;
1206
1207 /* Miscellaneous */
1208 ctx->NewState = NEW_ALL;
1209 ctx->RenderMode = GL_RENDER;
1210 ctx->StippleCounter = 0;
1211 ctx->NeedNormals = GL_FALSE;
1212 ctx->DoViewportMapping = GL_TRUE;
1213
1214 ctx->NeedEyeCoords = GL_FALSE;
1215 ctx->NeedEyeNormals = GL_FALSE;
1216 ctx->vb_proj_matrix = &ctx->ModelProjectMatrix;
1217
1218 /* Display list */
1219 ctx->CallDepth = 0;
1220 ctx->ExecuteFlag = GL_TRUE;
1221 ctx->CompileFlag = GL_FALSE;
1222 ctx->CurrentListPtr = NULL;
1223 ctx->CurrentBlock = NULL;
1224 ctx->CurrentListNum = 0;
1225 ctx->CurrentPos = 0;
1226
1227 ctx->ErrorValue = (GLenum) GL_NO_ERROR;
1228
1229 ctx->CatchSignals = GL_TRUE;
1230
1231 /* For debug/development only */
1232 ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE;
1233 ctx->FirstTimeCurrent = GL_TRUE;
1234
1235 /* Dither disable */
1236 ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE;
1237 if (ctx->NoDither) {
1238 if (getenv("MESA_DEBUG")) {
1239 fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n");
jtgafb833d1999-08-19 00:55:39 +00001240 }
Brian Paul4d053dd2000-01-14 04:45:47 +00001241 ctx->Color.DitherFlag = GL_FALSE;
Brian Paul00037781999-12-17 14:52:35 +00001242 }
1243}
1244
1245
1246
1247
jtgafb833d1999-08-19 00:55:39 +00001248/*
1249 * Allocate the proxy textures. If we run out of memory part way through
1250 * the allocations clean up and return GL_FALSE.
1251 * Return: GL_TRUE=success, GL_FALSE=failure
1252 */
1253static GLboolean alloc_proxy_textures( GLcontext *ctx )
1254{
1255 GLboolean out_of_memory;
1256 GLint i;
1257
1258 ctx->Texture.Proxy1D = gl_alloc_texture_object(NULL, 0, 1);
1259 if (!ctx->Texture.Proxy1D) {
1260 return GL_FALSE;
1261 }
1262
1263 ctx->Texture.Proxy2D = gl_alloc_texture_object(NULL, 0, 2);
1264 if (!ctx->Texture.Proxy2D) {
1265 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1266 return GL_FALSE;
1267 }
1268
1269 ctx->Texture.Proxy3D = gl_alloc_texture_object(NULL, 0, 3);
1270 if (!ctx->Texture.Proxy3D) {
1271 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1272 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1273 return GL_FALSE;
1274 }
1275
1276 out_of_memory = GL_FALSE;
1277 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1278 ctx->Texture.Proxy1D->Image[i] = gl_alloc_texture_image();
1279 ctx->Texture.Proxy2D->Image[i] = gl_alloc_texture_image();
1280 ctx->Texture.Proxy3D->Image[i] = gl_alloc_texture_image();
1281 if (!ctx->Texture.Proxy1D->Image[i]
1282 || !ctx->Texture.Proxy2D->Image[i]
1283 || !ctx->Texture.Proxy3D->Image[i]) {
1284 out_of_memory = GL_TRUE;
1285 }
1286 }
1287 if (out_of_memory) {
1288 for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
1289 if (ctx->Texture.Proxy1D->Image[i]) {
1290 gl_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
1291 }
1292 if (ctx->Texture.Proxy2D->Image[i]) {
1293 gl_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
1294 }
1295 if (ctx->Texture.Proxy3D->Image[i]) {
1296 gl_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
1297 }
1298 }
1299 gl_free_texture_object(NULL, ctx->Texture.Proxy1D);
1300 gl_free_texture_object(NULL, ctx->Texture.Proxy2D);
1301 gl_free_texture_object(NULL, ctx->Texture.Proxy3D);
1302 return GL_FALSE;
1303 }
1304 else {
1305 return GL_TRUE;
1306 }
1307}
1308
1309
1310
jtgafb833d1999-08-19 00:55:39 +00001311/*
Brian Paul4d053dd2000-01-14 04:45:47 +00001312 * Initialize a GLcontext struct.
jtgafb833d1999-08-19 00:55:39 +00001313 */
Brian Paul4d053dd2000-01-14 04:45:47 +00001314GLboolean gl_initialize_context_data( GLcontext *ctx,
1315 GLvisual *visual,
1316 GLcontext *share_list,
1317 void *driver_ctx,
1318 GLboolean direct )
jtgafb833d1999-08-19 00:55:39 +00001319{
jtgafb833d1999-08-19 00:55:39 +00001320 (void) direct; /* not used */
1321
jtgafb833d1999-08-19 00:55:39 +00001322 /* misc one-time initializations */
1323 one_time_init();
1324
jtgafb833d1999-08-19 00:55:39 +00001325 ctx->DriverCtx = driver_ctx;
1326 ctx->Visual = visual;
Brian Paul3f02f901999-11-24 18:48:30 +00001327 ctx->DrawBuffer = NULL;
1328 ctx->ReadBuffer = NULL;
jtgafb833d1999-08-19 00:55:39 +00001329
1330 ctx->VB = gl_vb_create_for_immediate( ctx );
1331 if (!ctx->VB) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001332 FREE( ctx );
Brian Paul4d053dd2000-01-14 04:45:47 +00001333 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001334 }
1335 ctx->input = ctx->VB->IM;
1336
1337 ctx->PB = gl_alloc_pb();
1338 if (!ctx->PB) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001339 FREE( ctx->VB );
1340 FREE( ctx );
Brian Paul4d053dd2000-01-14 04:45:47 +00001341 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001342 }
1343
1344 if (share_list) {
1345 /* share the group of display lists of another context */
1346 ctx->Shared = share_list->Shared;
1347 }
1348 else {
1349 /* allocate new group of display lists */
1350 ctx->Shared = alloc_shared_state();
1351 if (!ctx->Shared) {
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001352 FREE(ctx->VB);
1353 FREE(ctx->PB);
1354 FREE(ctx);
Brian Paul4d053dd2000-01-14 04:45:47 +00001355 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001356 }
1357 }
Brian Paul9560f052000-01-31 23:11:39 +00001358 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
jtgafb833d1999-08-19 00:55:39 +00001359 ctx->Shared->RefCount++;
Brian Paul9560f052000-01-31 23:11:39 +00001360 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
jtgafb833d1999-08-19 00:55:39 +00001361
Brian Paul4d053dd2000-01-14 04:45:47 +00001362 init_attrib_groups( ctx );
1363
jtgafb833d1999-08-19 00:55:39 +00001364 gl_reset_vb( ctx->VB );
1365 gl_reset_input( ctx );
1366
jtgafb833d1999-08-19 00:55:39 +00001367 if (visual->DBflag) {
1368 ctx->Color.DrawBuffer = GL_BACK;
1369 ctx->Color.DriverDrawBuffer = GL_BACK_LEFT;
1370 ctx->Color.DrawDestMask = BACK_LEFT_BIT;
1371 ctx->Pixel.ReadBuffer = GL_BACK;
1372 ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT;
1373 }
1374 else {
1375 ctx->Color.DrawBuffer = GL_FRONT;
1376 ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT;
1377 ctx->Color.DrawDestMask = FRONT_LEFT_BIT;
1378 ctx->Pixel.ReadBuffer = GL_FRONT;
1379 ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT;
1380 }
1381
1382#ifdef PROFILE
1383 init_timings( ctx );
1384#endif
1385
jtgafb833d1999-08-19 00:55:39 +00001386 if (!alloc_proxy_textures(ctx)) {
1387 free_shared_state(ctx, ctx->Shared);
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001388 FREE(ctx->VB);
1389 FREE(ctx->PB);
1390 FREE(ctx);
Brian Paul4d053dd2000-01-14 04:45:47 +00001391 return GL_FALSE;
jtgafb833d1999-08-19 00:55:39 +00001392 }
jtgafb833d1999-08-19 00:55:39 +00001393
Brian Paulfbd8f211999-11-11 01:22:25 +00001394 /* setup API dispatch tables */
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001395 ctx->Exec = CALLOC(_glapi_get_dispatch_table_size() * sizeof(void *));
1396 ctx->Save = CALLOC(_glapi_get_dispatch_table_size() * sizeof(void *));
1397 if (!ctx->Exec || !ctx->Save) {
1398 free_shared_state(ctx, ctx->Shared);
1399 FREE(ctx->VB);
1400 FREE(ctx->PB);
1401 if (ctx->Exec)
1402 FREE(ctx->Exec);
1403 FREE(ctx);
1404 }
1405 _mesa_init_exec_table( ctx->Exec );
1406 _mesa_init_dlist_table( ctx->Save );
1407 ctx->CurrentDispatch = ctx->Exec;
jtgafb833d1999-08-19 00:55:39 +00001408
Brian Paul4d053dd2000-01-14 04:45:47 +00001409 return GL_TRUE;
jtgafb833d1999-08-19 00:55:39 +00001410}
1411
jtgafb833d1999-08-19 00:55:39 +00001412
1413
1414/*
Brian Paul4d053dd2000-01-14 04:45:47 +00001415 * Allocate and initialize a GLcontext structure.
1416 * Input: visual - a GLvisual pointer
1417 * sharelist - another context to share display lists with or NULL
1418 * driver_ctx - pointer to device driver's context state struct
1419 * Return: pointer to a new gl_context struct or NULL if error.
1420 */
1421GLcontext *gl_create_context( GLvisual *visual,
1422 GLcontext *share_list,
1423 void *driver_ctx,
1424 GLboolean direct )
1425{
1426 GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) );
1427 if (!ctx) {
1428 return NULL;
1429 }
1430
1431 if (gl_initialize_context_data(ctx, visual, share_list,
1432 driver_ctx, direct)) {
1433 return ctx;
1434 }
1435 else {
1436 FREE(ctx);
1437 return NULL;
1438 }
1439}
1440
1441
1442
1443/*
1444 * Free the data associated with the given context.
1445 * But don't free() the GLcontext struct itself!
1446 */
1447void gl_free_context_data( GLcontext *ctx )
1448{
Brian Paul4d053dd2000-01-14 04:45:47 +00001449 struct gl_shine_tab *s, *tmps;
Brian Paul7fc29c52000-03-06 17:03:03 +00001450 GLuint i, j;
Brian Paul4d053dd2000-01-14 04:45:47 +00001451
1452 /* if we're destroying the current context, unbind it first */
1453 if (ctx == gl_get_current_context()) {
1454 gl_make_current(NULL, NULL);
1455 }
1456
1457#ifdef PROFILE
1458 if (getenv("MESA_PROFILE")) {
1459 print_timings( ctx );
1460 }
1461#endif
1462
1463 gl_matrix_dtr( &ctx->ModelView );
Brian Paul7fc29c52000-03-06 17:03:03 +00001464 for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001465 gl_matrix_dtr( &ctx->ModelViewStack[i] );
1466 }
1467 gl_matrix_dtr( &ctx->ProjectionMatrix );
Brian Paul7fc29c52000-03-06 17:03:03 +00001468 for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001469 gl_matrix_dtr( &ctx->ProjectionStack[i] );
1470 }
Brian Paul7fc29c52000-03-06 17:03:03 +00001471 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1472 gl_matrix_dtr( &ctx->TextureMatrix[i] );
1473 for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) {
1474 gl_matrix_dtr( &ctx->TextureStack[i][j] );
1475 }
1476 }
Brian Paul4d053dd2000-01-14 04:45:47 +00001477
1478 FREE( ctx->PB );
1479
1480 if(ctx->input != ctx->VB->IM)
1481 gl_immediate_free( ctx->input );
1482
1483 gl_vb_free( ctx->VB );
1484
Brian Paul9560f052000-01-31 23:11:39 +00001485 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
Brian Paul4d053dd2000-01-14 04:45:47 +00001486 ctx->Shared->RefCount--;
Brian Paul9560f052000-01-31 23:11:39 +00001487 assert(ctx->Shared->RefCount >= 0);
1488 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1489 if (ctx->Shared->RefCount == 0) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001490 /* free shared state */
1491 free_shared_state( ctx, ctx->Shared );
1492 }
1493
1494 foreach_s( s, tmps, ctx->ShineTabList ) {
1495 FREE( s );
1496 }
1497 FREE( ctx->ShineTabList );
1498
1499 /* Free proxy texture objects */
1500 gl_free_texture_object( NULL, ctx->Texture.Proxy1D );
1501 gl_free_texture_object( NULL, ctx->Texture.Proxy2D );
1502 gl_free_texture_object( NULL, ctx->Texture.Proxy3D );
1503
1504 /* Free evaluator data */
1505 if (ctx->EvalMap.Map1Vertex3.Points)
1506 FREE( ctx->EvalMap.Map1Vertex3.Points );
1507 if (ctx->EvalMap.Map1Vertex4.Points)
1508 FREE( ctx->EvalMap.Map1Vertex4.Points );
1509 if (ctx->EvalMap.Map1Index.Points)
1510 FREE( ctx->EvalMap.Map1Index.Points );
1511 if (ctx->EvalMap.Map1Color4.Points)
1512 FREE( ctx->EvalMap.Map1Color4.Points );
1513 if (ctx->EvalMap.Map1Normal.Points)
1514 FREE( ctx->EvalMap.Map1Normal.Points );
1515 if (ctx->EvalMap.Map1Texture1.Points)
1516 FREE( ctx->EvalMap.Map1Texture1.Points );
1517 if (ctx->EvalMap.Map1Texture2.Points)
1518 FREE( ctx->EvalMap.Map1Texture2.Points );
1519 if (ctx->EvalMap.Map1Texture3.Points)
1520 FREE( ctx->EvalMap.Map1Texture3.Points );
1521 if (ctx->EvalMap.Map1Texture4.Points)
1522 FREE( ctx->EvalMap.Map1Texture4.Points );
1523
1524 if (ctx->EvalMap.Map2Vertex3.Points)
1525 FREE( ctx->EvalMap.Map2Vertex3.Points );
1526 if (ctx->EvalMap.Map2Vertex4.Points)
1527 FREE( ctx->EvalMap.Map2Vertex4.Points );
1528 if (ctx->EvalMap.Map2Index.Points)
1529 FREE( ctx->EvalMap.Map2Index.Points );
1530 if (ctx->EvalMap.Map2Color4.Points)
1531 FREE( ctx->EvalMap.Map2Color4.Points );
1532 if (ctx->EvalMap.Map2Normal.Points)
1533 FREE( ctx->EvalMap.Map2Normal.Points );
1534 if (ctx->EvalMap.Map2Texture1.Points)
1535 FREE( ctx->EvalMap.Map2Texture1.Points );
1536 if (ctx->EvalMap.Map2Texture2.Points)
1537 FREE( ctx->EvalMap.Map2Texture2.Points );
1538 if (ctx->EvalMap.Map2Texture3.Points)
1539 FREE( ctx->EvalMap.Map2Texture3.Points );
1540 if (ctx->EvalMap.Map2Texture4.Points)
1541 FREE( ctx->EvalMap.Map2Texture4.Points );
1542
1543 /* Free cache of immediate buffers. */
1544 while (ctx->nr_im_queued-- > 0) {
1545 struct immediate * next = ctx->freed_im_queue->next;
1546 FREE( ctx->freed_im_queue );
1547 ctx->freed_im_queue = next;
1548 }
1549 gl_extensions_dtr(ctx);
Brian Paul3ab6bbe2000-02-12 17:26:15 +00001550
1551 FREE(ctx->Exec);
1552 FREE(ctx->Save);
Brian Paul4d053dd2000-01-14 04:45:47 +00001553}
1554
1555
1556
1557/*
1558 * Destroy a GLcontext structure.
jtgafb833d1999-08-19 00:55:39 +00001559 */
1560void gl_destroy_context( GLcontext *ctx )
1561{
1562 if (ctx) {
Brian Paul4d053dd2000-01-14 04:45:47 +00001563 gl_free_context_data(ctx);
Brian Paulbd5cdaf1999-10-13 18:42:49 +00001564 FREE( (void *) ctx );
jtgafb833d1999-08-19 00:55:39 +00001565 }
1566}
1567
1568
1569
1570/*
Brian Paul4d053dd2000-01-14 04:45:47 +00001571 * Called by the driver after both the context and driver are fully
1572 * initialized. Currently just reads the config file.
jtgafb833d1999-08-19 00:55:39 +00001573 */
Brian Paul00037781999-12-17 14:52:35 +00001574void gl_context_initialize( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001575{
Brian Paul00037781999-12-17 14:52:35 +00001576 gl_read_config_file( ctx );
jtgafb833d1999-08-19 00:55:39 +00001577}
1578
1579
1580
1581/*
1582 * Copy attribute groups from one context to another.
1583 * Input: src - source context
1584 * dst - destination context
1585 * mask - bitwise OR of GL_*_BIT flags
1586 */
1587void gl_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask )
1588{
1589 if (mask & GL_ACCUM_BUFFER_BIT) {
1590 MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) );
1591 }
1592 if (mask & GL_COLOR_BUFFER_BIT) {
1593 MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) );
1594 }
1595 if (mask & GL_CURRENT_BIT) {
1596 MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) );
1597 }
1598 if (mask & GL_DEPTH_BUFFER_BIT) {
1599 MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) );
1600 }
1601 if (mask & GL_ENABLE_BIT) {
1602 /* no op */
1603 }
1604 if (mask & GL_EVAL_BIT) {
1605 MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) );
1606 }
1607 if (mask & GL_FOG_BIT) {
1608 MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) );
1609 }
1610 if (mask & GL_HINT_BIT) {
1611 MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) );
1612 }
1613 if (mask & GL_LIGHTING_BIT) {
1614 MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) );
Brian Paul00037781999-12-17 14:52:35 +00001615 /* gl_reinit_light_attrib( &dst->Light ); */
jtgafb833d1999-08-19 00:55:39 +00001616 }
1617 if (mask & GL_LINE_BIT) {
1618 MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) );
1619 }
1620 if (mask & GL_LIST_BIT) {
1621 MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) );
1622 }
1623 if (mask & GL_PIXEL_MODE_BIT) {
1624 MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) );
1625 }
1626 if (mask & GL_POINT_BIT) {
1627 MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) );
1628 }
1629 if (mask & GL_POLYGON_BIT) {
1630 MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) );
1631 }
1632 if (mask & GL_POLYGON_STIPPLE_BIT) {
1633 /* Use loop instead of MEMCPY due to problem with Portland Group's
1634 * C compiler. Reported by John Stone.
1635 */
1636 int i;
1637 for (i=0;i<32;i++) {
1638 dst->PolygonStipple[i] = src->PolygonStipple[i];
1639 }
1640 }
1641 if (mask & GL_SCISSOR_BIT) {
1642 MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) );
1643 }
1644 if (mask & GL_STENCIL_BUFFER_BIT) {
1645 MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) );
1646 }
1647 if (mask & GL_TEXTURE_BIT) {
1648 MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) );
1649 }
1650 if (mask & GL_TRANSFORM_BIT) {
1651 MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) );
1652 }
1653 if (mask & GL_VIEWPORT_BIT) {
1654 MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) );
1655 }
1656}
1657
1658
jtgafb833d1999-08-19 00:55:39 +00001659/*
Brian Paul00037781999-12-17 14:52:35 +00001660 * Set the current context, binding the given frame buffer to the context.
1661 */
1662void gl_make_current( GLcontext *newCtx, GLframebuffer *buffer )
1663{
1664 gl_make_current2( newCtx, buffer, buffer );
1665}
1666
1667
1668/*
1669 * Bind the given context to the given draw-buffer and read-buffer
1670 * and make it the current context for this thread.
1671 */
1672void gl_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer,
1673 GLframebuffer *readBuffer )
1674{
1675#if 0
Brian Paulf9b97d92000-01-28 20:17:42 +00001676 GLcontext *oldCtx = gl_get_context();
Brian Paul00037781999-12-17 14:52:35 +00001677
1678 /* Flush the old context
1679 */
1680 if (oldCtx) {
1681 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(oldCtx, "gl_make_current");
1682
1683 /* unbind frame buffers from context */
1684 if (oldCtx->DrawBuffer) {
1685 oldCtx->DrawBuffer = NULL;
1686 }
1687 if (oldCtx->ReadBuffer) {
1688 oldCtx->ReadBuffer = NULL;
1689 }
1690 }
1691#endif
1692
1693 /* We call this function periodically (just here for now) in
1694 * order to detect when multithreading has begun.
1695 */
1696 _glapi_check_multithread();
1697
Brian Paulf9b97d92000-01-28 20:17:42 +00001698 _glapi_set_context((void *) newCtx);
Brian Paul00037781999-12-17 14:52:35 +00001699 ASSERT(gl_get_current_context() == newCtx);
1700 if (newCtx) {
1701 SET_IMMEDIATE(newCtx, newCtx->input);
1702 _glapi_set_dispatch(newCtx->CurrentDispatch);
1703 }
1704 else {
1705 _glapi_set_dispatch(NULL); /* none current */
1706 }
1707
1708 if (MESA_VERBOSE) fprintf(stderr, "gl_make_current()\n");
1709
1710 if (newCtx && drawBuffer && readBuffer) {
1711 /* TODO: check if newCtx and buffer's visual match??? */
1712 newCtx->DrawBuffer = drawBuffer;
1713 newCtx->ReadBuffer = readBuffer;
1714 newCtx->NewState = NEW_ALL; /* just to be safe */
1715 gl_update_state( newCtx );
1716 }
1717
1718 /* We can use this to help debug user's problems. Tell the to set
1719 * the MESA_INFO env variable before running their app. Then the
1720 * first time each context is made current we'll print some useful
1721 * information.
1722 */
1723 if (newCtx && newCtx->FirstTimeCurrent) {
1724 if (getenv("MESA_INFO")) {
1725 fprintf(stderr, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION));
1726 fprintf(stderr, "Mesa GL_RENDERER = %s\n", (char *) _mesa_GetString(GL_RENDERER));
1727 fprintf(stderr, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR));
1728 fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", (char *) _mesa_GetString(GL_EXTENSIONS));
Brian Paul09cb1481999-12-17 17:00:32 +00001729#if defined(THREADS)
1730 fprintf(stderr, "Mesa thread-safe: YES\n");
1731#else
1732 fprintf(stderr, "Mesa thread-safe: NO\n");
1733#endif
Brian Paul54287052000-01-17 20:00:15 +00001734#if defined(USE_X86_ASM)
1735 fprintf(stderr, "Mesa x86-optimized: YES\n");
1736#else
1737 fprintf(stderr, "Mesa x86-optimized: NO\n");
1738#endif
Brian Paul00037781999-12-17 14:52:35 +00001739 }
1740 newCtx->FirstTimeCurrent = GL_FALSE;
1741 }
1742}
1743
1744
1745
1746/*
1747 * Return current context handle for the calling thread.
1748 * This isn't the fastest way to get the current context.
1749 * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h
1750 */
1751GLcontext *gl_get_current_context( void )
1752{
Brian Paulf9b97d92000-01-28 20:17:42 +00001753 return (GLcontext *) _glapi_get_context();
Brian Paul00037781999-12-17 14:52:35 +00001754}
1755
1756
1757
1758/*
Brian Paulfbd8f211999-11-11 01:22:25 +00001759 * This should be called by device drivers just before they do a
1760 * swapbuffers. Any pending rendering commands will be executed.
jtgafb833d1999-08-19 00:55:39 +00001761 */
Brian Paulfbd8f211999-11-11 01:22:25 +00001762void
1763_mesa_swapbuffers(GLcontext *ctx)
jtgafb833d1999-08-19 00:55:39 +00001764{
Brian Paulfbd8f211999-11-11 01:22:25 +00001765 FLUSH_VB( ctx, "swap buffers" );
jtgafb833d1999-08-19 00:55:39 +00001766}
1767
1768
Brian Paul00037781999-12-17 14:52:35 +00001769
Brian Paulfbd8f211999-11-11 01:22:25 +00001770/*
1771 * Return pointer to this context's current API dispatch table.
1772 * It'll either be the immediate-mode execute dispatcher or the
1773 * display list compile dispatcher.
1774 */
1775struct _glapi_table *
1776_mesa_get_dispatch(GLcontext *ctx)
1777{
1778 return ctx->CurrentDispatch;
1779}
1780
1781
1782
jtgafb833d1999-08-19 00:55:39 +00001783/**********************************************************************/
1784/***** Miscellaneous functions *****/
1785/**********************************************************************/
1786
1787
1788/*
1789 * This function is called when the Mesa user has stumbled into a code
1790 * path which may not be implemented fully or correctly.
1791 */
1792void gl_problem( const GLcontext *ctx, const char *s )
1793{
1794 fprintf( stderr, "Mesa implementation error: %s\n", s );
1795 fprintf( stderr, "Report to mesa-bugs@mesa3d.org\n" );
1796 (void) ctx;
1797}
1798
1799
1800
1801/*
1802 * This is called to inform the user that he or she has tried to do
1803 * something illogical or if there's likely a bug in their program
1804 * (like enabled depth testing without a depth buffer).
1805 */
1806void gl_warning( const GLcontext *ctx, const char *s )
1807{
1808 GLboolean debug;
1809#ifdef DEBUG
1810 debug = GL_TRUE;
1811#else
1812 if (getenv("MESA_DEBUG")) {
1813 debug = GL_TRUE;
1814 }
1815 else {
1816 debug = GL_FALSE;
1817 }
1818#endif
1819 if (debug) {
1820 fprintf( stderr, "Mesa warning: %s\n", s );
1821 }
1822 (void) ctx;
1823}
1824
1825
1826
Brian Paulfa9df402000-02-02 19:16:46 +00001827/*
1828 * Compile an error into current display list.
1829 */
jtgafb833d1999-08-19 00:55:39 +00001830void gl_compile_error( GLcontext *ctx, GLenum error, const char *s )
1831{
1832 if (ctx->CompileFlag)
1833 gl_save_error( ctx, error, s );
1834
1835 if (ctx->ExecuteFlag)
1836 gl_error( ctx, error, s );
1837}
1838
1839
Brian Paulfa9df402000-02-02 19:16:46 +00001840
jtgafb833d1999-08-19 00:55:39 +00001841/*
1842 * This is Mesa's error handler. Normally, all that's done is the updating
1843 * of the current error value. If Mesa is compiled with -DDEBUG or if the
1844 * environment variable "MESA_DEBUG" is defined then a real error message
1845 * is printed to stderr.
1846 * Input: error - the error value
1847 * s - a diagnostic string
1848 */
1849void gl_error( GLcontext *ctx, GLenum error, const char *s )
1850{
1851 GLboolean debug;
1852
1853#ifdef DEBUG
1854 debug = GL_TRUE;
1855#else
1856 if (getenv("MESA_DEBUG")) {
1857 debug = GL_TRUE;
1858 }
1859 else {
1860 debug = GL_FALSE;
1861 }
1862#endif
1863
1864 if (debug) {
1865 char errstr[1000];
1866
1867 switch (error) {
1868 case GL_NO_ERROR:
1869 strcpy( errstr, "GL_NO_ERROR" );
1870 break;
1871 case GL_INVALID_VALUE:
1872 strcpy( errstr, "GL_INVALID_VALUE" );
1873 break;
1874 case GL_INVALID_ENUM:
1875 strcpy( errstr, "GL_INVALID_ENUM" );
1876 break;
1877 case GL_INVALID_OPERATION:
1878 strcpy( errstr, "GL_INVALID_OPERATION" );
1879 break;
1880 case GL_STACK_OVERFLOW:
1881 strcpy( errstr, "GL_STACK_OVERFLOW" );
1882 break;
1883 case GL_STACK_UNDERFLOW:
1884 strcpy( errstr, "GL_STACK_UNDERFLOW" );
1885 break;
1886 case GL_OUT_OF_MEMORY:
1887 strcpy( errstr, "GL_OUT_OF_MEMORY" );
1888 break;
1889 default:
1890 strcpy( errstr, "unknown" );
1891 break;
1892 }
1893 fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s );
1894 }
1895
1896 if (ctx->ErrorValue==GL_NO_ERROR) {
1897 ctx->ErrorValue = error;
1898 }
1899
1900 /* Call device driver's error handler, if any. This is used on the Mac. */
1901 if (ctx->Driver.Error) {
1902 (*ctx->Driver.Error)( ctx );
1903 }
1904}
1905
1906
1907
Brian Paulfa9df402000-02-02 19:16:46 +00001908void
1909_mesa_Finish( void )
jtgafb833d1999-08-19 00:55:39 +00001910{
Brian Paulfa9df402000-02-02 19:16:46 +00001911 GET_CURRENT_CONTEXT(ctx);
1912 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFinish");
1913 if (ctx->Driver.Finish) {
1914 (*ctx->Driver.Finish)( ctx );
jtgafb833d1999-08-19 00:55:39 +00001915 }
1916}
1917
1918
1919
Brian Paulfa9df402000-02-02 19:16:46 +00001920void
1921_mesa_Flush( void )
jtgafb833d1999-08-19 00:55:39 +00001922{
Brian Paulfa9df402000-02-02 19:16:46 +00001923 GET_CURRENT_CONTEXT(ctx);
1924 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glFlush");
1925 if (ctx->Driver.Flush) {
1926 (*ctx->Driver.Flush)( ctx );
jtgafb833d1999-08-19 00:55:39 +00001927 }
jtgafb833d1999-08-19 00:55:39 +00001928}