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