attrib.c revision 2c3d34c905fa6b831a066afae83b938de05eb241
1/* $Id: attrib.c,v 1.47 2001/03/18 08:53:49 gareth Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "accum.h" 33#include "alpha.h" 34#include "attrib.h" 35#include "blend.h" 36#include "buffers.h" 37#include "clip.h" 38#include "colormac.h" 39#include "context.h" 40#include "depth.h" 41#include "enable.h" 42#include "enums.h" 43#include "fog.h" 44#include "hint.h" 45#include "light.h" 46#include "lines.h" 47#include "logic.h" 48#include "masking.h" 49#include "matrix.h" 50#include "mem.h" 51#include "points.h" 52#include "polygon.h" 53#include "scissor.h" 54#include "simple_list.h" 55#include "stencil.h" 56#include "texstate.h" 57#include "mtypes.h" 58#endif 59 60 61 62 63/* 64 * Allocate a new attribute state node. These nodes have a 65 * "kind" value and a pointer to a struct of state data. 66 */ 67static struct gl_attrib_node * 68new_attrib_node( GLbitfield kind ) 69{ 70 struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node); 71 if (an) { 72 an->kind = kind; 73 } 74 return an; 75} 76 77 78 79/* 80 * Copy texture object state from one texture object to another. 81 */ 82static void 83copy_texobj_state( struct gl_texture_object *dest, 84 const struct gl_texture_object *src ) 85{ 86 /* 87 dest->Name = src->Name; 88 dest->Dimensions = src->Dimensions; 89 */ 90 dest->Priority = src->Priority; 91 dest->BorderColor[0] = src->BorderColor[0]; 92 dest->BorderColor[1] = src->BorderColor[1]; 93 dest->BorderColor[2] = src->BorderColor[2]; 94 dest->BorderColor[3] = src->BorderColor[3]; 95 dest->WrapS = src->WrapS; 96 dest->WrapT = src->WrapT; 97 dest->WrapR = src->WrapR; 98 dest->MinFilter = src->MinFilter; 99 dest->MagFilter = src->MagFilter; 100 dest->MinLod = src->MinLod; 101 dest->MaxLod = src->MaxLod; 102 dest->BaseLevel = src->BaseLevel; 103 dest->MaxLevel = src->MaxLevel; 104 dest->MaxAnisotropy = src->MaxAnisotropy; 105 dest->CompareFlag = src->CompareFlag; 106 dest->CompareOperator = src->CompareOperator; 107 dest->ShadowAmbient = src->ShadowAmbient; 108 dest->_MaxLevel = src->_MaxLevel; 109 dest->_MaxLambda = src->_MaxLambda; 110 dest->Palette = src->Palette; 111 dest->Complete = src->Complete; 112} 113 114 115 116void 117_mesa_PushAttrib(GLbitfield mask) 118{ 119 struct gl_attrib_node *newnode; 120 struct gl_attrib_node *head; 121 122 GET_CURRENT_CONTEXT(ctx); 123 ASSERT_OUTSIDE_BEGIN_END(ctx); 124 125 if (MESA_VERBOSE&VERBOSE_API) 126 fprintf(stderr, "glPushAttrib %x\n", (int)mask); 127 128 if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { 129 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); 130 return; 131 } 132 133 /* Build linked list of attribute nodes which save all attribute */ 134 /* groups specified by the mask. */ 135 head = NULL; 136 137 if (mask & GL_ACCUM_BUFFER_BIT) { 138 struct gl_accum_attrib *attr; 139 attr = MALLOC_STRUCT( gl_accum_attrib ); 140 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); 141 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT ); 142 newnode->data = attr; 143 newnode->next = head; 144 head = newnode; 145 } 146 147 if (mask & GL_COLOR_BUFFER_BIT) { 148 struct gl_colorbuffer_attrib *attr; 149 attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); 150 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); 151 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT ); 152 newnode->data = attr; 153 newnode->next = head; 154 head = newnode; 155 } 156 157 if (mask & GL_CURRENT_BIT) { 158 struct gl_current_attrib *attr; 159 FLUSH_CURRENT( ctx, 0 ); 160 attr = MALLOC_STRUCT( gl_current_attrib ); 161 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); 162 newnode = new_attrib_node( GL_CURRENT_BIT ); 163 newnode->data = attr; 164 newnode->next = head; 165 head = newnode; 166 } 167 168 if (mask & GL_DEPTH_BUFFER_BIT) { 169 struct gl_depthbuffer_attrib *attr; 170 attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); 171 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); 172 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT ); 173 newnode->data = attr; 174 newnode->next = head; 175 head = newnode; 176 } 177 178 if (mask & GL_ENABLE_BIT) { 179 struct gl_enable_attrib *attr; 180 GLuint i; 181 attr = MALLOC_STRUCT( gl_enable_attrib ); 182 /* Copy enable flags from all other attributes into the enable struct. */ 183 attr->AlphaTest = ctx->Color.AlphaEnabled; 184 attr->AutoNormal = ctx->Eval.AutoNormal; 185 attr->Blend = ctx->Color.BlendEnabled; 186 for (i=0;i<MAX_CLIP_PLANES;i++) { 187 attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i]; 188 } 189 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 190 attr->Convolution1D = ctx->Pixel.Convolution1DEnabled; 191 attr->Convolution2D = ctx->Pixel.Convolution2DEnabled; 192 attr->Separable2D = ctx->Pixel.Separable2DEnabled; 193 attr->CullFace = ctx->Polygon.CullFlag; 194 attr->DepthTest = ctx->Depth.Test; 195 attr->Dither = ctx->Color.DitherFlag; 196 attr->Fog = ctx->Fog.Enabled; 197 for (i=0;i<MAX_LIGHTS;i++) { 198 attr->Light[i] = ctx->Light.Light[i].Enabled; 199 } 200 attr->Lighting = ctx->Light.Enabled; 201 attr->LineSmooth = ctx->Line.SmoothFlag; 202 attr->LineStipple = ctx->Line.StippleFlag; 203 attr->Histogram = ctx->Pixel.HistogramEnabled; 204 attr->MinMax = ctx->Pixel.MinMaxEnabled; 205 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 206 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 207 attr->Map1Color4 = ctx->Eval.Map1Color4; 208 attr->Map1Index = ctx->Eval.Map1Index; 209 attr->Map1Normal = ctx->Eval.Map1Normal; 210 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 211 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 212 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 213 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 214 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 215 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 216 attr->Map2Color4 = ctx->Eval.Map2Color4; 217 attr->Map2Index = ctx->Eval.Map2Index; 218 attr->Map2Normal = ctx->Eval.Map2Normal; 219 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 220 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 221 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 222 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 223 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 224 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 225 attr->Normalize = ctx->Transform.Normalize; 226 attr->PixelTexture = ctx->Pixel.PixelTextureEnabled; 227 attr->PointSmooth = ctx->Point.SmoothFlag; 228 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 229 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 230 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 231 attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 232 attr->PolygonStipple = ctx->Polygon.StippleFlag; 233 attr->RescaleNormals = ctx->Transform.RescaleNormals; 234 attr->Scissor = ctx->Scissor.Enabled; 235 attr->Stencil = ctx->Stencil.Enabled; 236 for (i=0; i<MAX_TEXTURE_UNITS; i++) { 237 attr->Texture[i] = ctx->Texture.Unit[i].Enabled; 238 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; 239 } 240 newnode = new_attrib_node( GL_ENABLE_BIT ); 241 newnode->data = attr; 242 newnode->next = head; 243 head = newnode; 244 } 245 246 if (mask & GL_EVAL_BIT) { 247 struct gl_eval_attrib *attr; 248 attr = MALLOC_STRUCT( gl_eval_attrib ); 249 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); 250 newnode = new_attrib_node( GL_EVAL_BIT ); 251 newnode->data = attr; 252 newnode->next = head; 253 head = newnode; 254 } 255 256 if (mask & GL_FOG_BIT) { 257 struct gl_fog_attrib *attr; 258 attr = MALLOC_STRUCT( gl_fog_attrib ); 259 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); 260 newnode = new_attrib_node( GL_FOG_BIT ); 261 newnode->data = attr; 262 newnode->next = head; 263 head = newnode; 264 } 265 266 if (mask & GL_HINT_BIT) { 267 struct gl_hint_attrib *attr; 268 attr = MALLOC_STRUCT( gl_hint_attrib ); 269 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); 270 newnode = new_attrib_node( GL_HINT_BIT ); 271 newnode->data = attr; 272 newnode->next = head; 273 head = newnode; 274 } 275 276 if (mask & GL_LIGHTING_BIT) { 277 struct gl_light_attrib *attr; 278 FLUSH_CURRENT(ctx, 0); /* flush material changes */ 279 attr = MALLOC_STRUCT( gl_light_attrib ); 280 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); 281 newnode = new_attrib_node( GL_LIGHTING_BIT ); 282 newnode->data = attr; 283 newnode->next = head; 284 head = newnode; 285 } 286 287 if (mask & GL_LINE_BIT) { 288 struct gl_line_attrib *attr; 289 attr = MALLOC_STRUCT( gl_line_attrib ); 290 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); 291 newnode = new_attrib_node( GL_LINE_BIT ); 292 newnode->data = attr; 293 newnode->next = head; 294 head = newnode; 295 } 296 297 if (mask & GL_LIST_BIT) { 298 struct gl_list_attrib *attr; 299 attr = MALLOC_STRUCT( gl_list_attrib ); 300 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) ); 301 newnode = new_attrib_node( GL_LIST_BIT ); 302 newnode->data = attr; 303 newnode->next = head; 304 head = newnode; 305 } 306 307 if (mask & GL_PIXEL_MODE_BIT) { 308 struct gl_pixel_attrib *attr; 309 attr = MALLOC_STRUCT( gl_pixel_attrib ); 310 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); 311 newnode = new_attrib_node( GL_PIXEL_MODE_BIT ); 312 newnode->data = attr; 313 newnode->next = head; 314 head = newnode; 315 } 316 317 if (mask & GL_POINT_BIT) { 318 struct gl_point_attrib *attr; 319 attr = MALLOC_STRUCT( gl_point_attrib ); 320 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); 321 newnode = new_attrib_node( GL_POINT_BIT ); 322 newnode->data = attr; 323 newnode->next = head; 324 head = newnode; 325 } 326 327 if (mask & GL_POLYGON_BIT) { 328 struct gl_polygon_attrib *attr; 329 attr = MALLOC_STRUCT( gl_polygon_attrib ); 330 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); 331 newnode = new_attrib_node( GL_POLYGON_BIT ); 332 newnode->data = attr; 333 newnode->next = head; 334 head = newnode; 335 } 336 337 if (mask & GL_POLYGON_STIPPLE_BIT) { 338 GLuint *stipple; 339 stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) ); 340 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); 341 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT ); 342 newnode->data = stipple; 343 newnode->next = head; 344 head = newnode; 345 } 346 347 if (mask & GL_SCISSOR_BIT) { 348 struct gl_scissor_attrib *attr; 349 attr = MALLOC_STRUCT( gl_scissor_attrib ); 350 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); 351 newnode = new_attrib_node( GL_SCISSOR_BIT ); 352 newnode->data = attr; 353 newnode->next = head; 354 head = newnode; 355 } 356 357 if (mask & GL_STENCIL_BUFFER_BIT) { 358 struct gl_stencil_attrib *attr; 359 attr = MALLOC_STRUCT( gl_stencil_attrib ); 360 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); 361 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT ); 362 newnode->data = attr; 363 newnode->next = head; 364 head = newnode; 365 } 366 367 if (mask & GL_TEXTURE_BIT) { 368 struct gl_texture_attrib *attr; 369 GLuint u; 370 /* Take care of texture object reference counters */ 371 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 372 ctx->Texture.Unit[u].Current1D->RefCount++; 373 ctx->Texture.Unit[u].Current2D->RefCount++; 374 ctx->Texture.Unit[u].Current3D->RefCount++; 375 ctx->Texture.Unit[u].CurrentCubeMap->RefCount++; 376 } 377 attr = MALLOC_STRUCT( gl_texture_attrib ); 378 MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); 379 /* copy state of the currently bound texture objects */ 380 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 381 copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].Current1D); 382 copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].Current2D); 383 copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].Current3D); 384 copy_texobj_state(&attr->Unit[u].SavedCubeMap, attr->Unit[u].CurrentCubeMap); 385 } 386 newnode = new_attrib_node( GL_TEXTURE_BIT ); 387 newnode->data = attr; 388 newnode->next = head; 389 head = newnode; 390 } 391 392 if (mask & GL_TRANSFORM_BIT) { 393 struct gl_transform_attrib *attr; 394 attr = MALLOC_STRUCT( gl_transform_attrib ); 395 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); 396 newnode = new_attrib_node( GL_TRANSFORM_BIT ); 397 newnode->data = attr; 398 newnode->next = head; 399 head = newnode; 400 } 401 402 if (mask & GL_VIEWPORT_BIT) { 403 struct gl_viewport_attrib *attr; 404 attr = MALLOC_STRUCT( gl_viewport_attrib ); 405 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); 406 newnode = new_attrib_node( GL_VIEWPORT_BIT ); 407 newnode->data = attr; 408 newnode->next = head; 409 head = newnode; 410 } 411 412 ctx->AttribStack[ctx->AttribStackDepth] = head; 413 ctx->AttribStackDepth++; 414} 415 416 417 418static void 419pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) 420{ 421 GLuint i; 422 423#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ 424 if ((VALUE) != (NEWVALUE)) { \ 425 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ 426 } 427 428 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 429 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->AutoNormal, GL_NORMALIZE); 430 TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); 431 432 for (i=0;i<MAX_CLIP_PLANES;i++) { 433 if (ctx->Transform.ClipEnabled[i] != enable->ClipPlane[i]) 434 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), 435 enable->ClipPlane[i]); 436 } 437 438 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 439 GL_COLOR_MATERIAL); 440 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 441 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 442 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 443 TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D, 444 GL_CONVOLUTION_1D); 445 TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D, 446 GL_CONVOLUTION_2D); 447 TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D, 448 GL_SEPARABLE_2D); 449 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 450 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 451 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 452 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 453 GL_LINE_STIPPLE); 454 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 455 GL_INDEX_LOGIC_OP); 456 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 457 GL_COLOR_LOGIC_OP); 458 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 459 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 460 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 461 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 462 GL_MAP1_TEXTURE_COORD_1); 463 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 464 GL_MAP1_TEXTURE_COORD_2); 465 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 466 GL_MAP1_TEXTURE_COORD_3); 467 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 468 GL_MAP1_TEXTURE_COORD_4); 469 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 470 GL_MAP1_VERTEX_3); 471 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 472 GL_MAP1_VERTEX_4); 473 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 474 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 475 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 476 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 477 GL_MAP2_TEXTURE_COORD_1); 478 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 479 GL_MAP2_TEXTURE_COORD_2); 480 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 481 GL_MAP2_TEXTURE_COORD_3); 482 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 483 GL_MAP2_TEXTURE_COORD_4); 484 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 485 GL_MAP2_VERTEX_3); 486 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 487 GL_MAP2_VERTEX_4); 488 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 489 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 490 GL_RESCALE_NORMAL_EXT); 491 TEST_AND_UPDATE(ctx->Pixel.PixelTextureEnabled, enable->PixelTexture, 492 GL_POINT_SMOOTH); 493 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 494 GL_POINT_SMOOTH); 495 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 496 GL_POLYGON_OFFSET_POINT); 497 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 498 GL_POLYGON_OFFSET_LINE); 499 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 500 GL_POLYGON_OFFSET_FILL); 501 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 502 GL_POLYGON_SMOOTH); 503 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 504 GL_POLYGON_STIPPLE); 505 TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); 506 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 507#undef TEST_AND_UPDATE 508 509 /* texture unit enables */ 510 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 511 if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) { 512 ctx->Texture.Unit[i].Enabled = enable->Texture[i]; 513 if (ctx->Driver.Enable) { 514 if (ctx->Driver.ActiveTexture) { 515 (*ctx->Driver.ActiveTexture)(ctx, i); 516 } 517 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, 518 (GLboolean) (enable->Texture[i] & TEXTURE0_1D) ); 519 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, 520 (GLboolean) (enable->Texture[i] & TEXTURE0_2D) ); 521 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, 522 (GLboolean) (enable->Texture[i] & TEXTURE0_3D) ); 523 } 524 } 525 526 if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) { 527 ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i]; 528 if (ctx->Driver.Enable) { 529 if (ctx->Driver.ActiveTexture) { 530 (*ctx->Driver.ActiveTexture)(ctx, i); 531 } 532 if (enable->TexGen[i] & S_BIT) 533 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE); 534 else 535 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE); 536 if (enable->TexGen[i] & T_BIT) 537 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE); 538 else 539 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE); 540 if (enable->TexGen[i] & R_BIT) 541 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE); 542 else 543 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE); 544 if (enable->TexGen[i] & Q_BIT) 545 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE); 546 else 547 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 548 } 549 } 550 } 551 552 if (ctx->Driver.ActiveTexture) { 553 (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit); 554 } 555} 556 557 558 559/* 560 * This function is kind of long just because we have to call a lot 561 * of device driver functions to update device driver state. 562 * 563 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions 564 * in order to restore GL state. This isn't terribly efficient but it 565 * ensures that dirty flags and any derived state gets updated correctly. 566 * We could at least check if the value to restore equals the current value 567 * and then skip the Mesa call. 568 */ 569void 570_mesa_PopAttrib(void) 571{ 572 struct gl_attrib_node *attr, *next; 573 GET_CURRENT_CONTEXT(ctx); 574 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 575 576 if (ctx->AttribStackDepth == 0) { 577 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); 578 return; 579 } 580 581 ctx->AttribStackDepth--; 582 attr = ctx->AttribStack[ctx->AttribStackDepth]; 583 584 while (attr) { 585 586 if (MESA_VERBOSE&VERBOSE_API) 587 fprintf(stderr, "glPopAttrib %s\n", _mesa_lookup_enum_by_nr(attr->kind)); 588 589 switch (attr->kind) { 590 case GL_ACCUM_BUFFER_BIT: 591 { 592 const struct gl_accum_attrib *accum; 593 accum = (const struct gl_accum_attrib *) attr->data; 594 _mesa_ClearAccum(accum->ClearColor[0], 595 accum->ClearColor[1], 596 accum->ClearColor[2], 597 accum->ClearColor[3]); 598 } 599 break; 600 case GL_COLOR_BUFFER_BIT: 601 { 602 const struct gl_colorbuffer_attrib *color; 603 color = (const struct gl_colorbuffer_attrib *) attr->data; 604 _mesa_ClearIndex(color->ClearIndex); 605 _mesa_ClearColor(CHAN_TO_FLOAT(color->ClearColor[0]), 606 CHAN_TO_FLOAT(color->ClearColor[1]), 607 CHAN_TO_FLOAT(color->ClearColor[2]), 608 CHAN_TO_FLOAT(color->ClearColor[3])); 609 _mesa_IndexMask(color->IndexMask); 610 _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0), 611 (GLboolean) (color->ColorMask[1] != 0), 612 (GLboolean) (color->ColorMask[2] != 0), 613 (GLboolean) (color->ColorMask[3] != 0)); 614 _mesa_DrawBuffer(color->DrawBuffer); 615 _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); 616 _mesa_AlphaFunc(color->AlphaFunc, 617 CHAN_TO_FLOAT(color->AlphaRef)); 618 _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); 619 _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, 620 color->BlendDstRGB, 621 color->BlendSrcA, 622 color->BlendDstA); 623 _mesa_BlendEquation(color->BlendEquation); 624 _mesa_BlendColor(color->BlendColor[0], 625 color->BlendColor[1], 626 color->BlendColor[2], 627 color->BlendColor[3]); 628 _mesa_LogicOp(color->LogicOp); 629 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, 630 color->ColorLogicOpEnabled); 631 _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, 632 color->IndexLogicOpEnabled); 633 _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); 634 } 635 break; 636 case GL_CURRENT_BIT: 637 FLUSH_CURRENT( ctx, 0 ); 638 MEMCPY( &ctx->Current, attr->data, 639 sizeof(struct gl_current_attrib) ); 640 break; 641 case GL_DEPTH_BUFFER_BIT: 642 { 643 const struct gl_depthbuffer_attrib *depth; 644 depth = (const struct gl_depthbuffer_attrib *) attr->data; 645 _mesa_DepthFunc(depth->Func); 646 _mesa_ClearDepth(depth->Clear); 647 _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); 648 _mesa_DepthMask(depth->Mask); 649 if (ctx->Extensions.HP_occlusion_test) 650 _mesa_set_enable(ctx, GL_OCCLUSION_TEST_HP, 651 depth->OcclusionTest); 652 } 653 break; 654 case GL_ENABLE_BIT: 655 { 656 const struct gl_enable_attrib *enable; 657 enable = (const struct gl_enable_attrib *) attr->data; 658 pop_enable_group(ctx, enable); 659 ctx->NewState |= _NEW_ALL; 660 } 661 break; 662 case GL_EVAL_BIT: 663 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); 664 ctx->NewState |= _NEW_EVAL; 665 break; 666 case GL_FOG_BIT: 667 { 668 const struct gl_fog_attrib *fog; 669 fog = (const struct gl_fog_attrib *) attr->data; 670 _mesa_set_enable(ctx, GL_FOG, fog->Enabled); 671 _mesa_Fogfv(GL_FOG_COLOR, fog->Color); 672 _mesa_Fogf(GL_FOG_DENSITY, fog->Density); 673 _mesa_Fogf(GL_FOG_START, fog->Start); 674 _mesa_Fogf(GL_FOG_END, fog->End); 675 _mesa_Fogf(GL_FOG_INDEX, fog->Index); 676 _mesa_Fogi(GL_FOG_MODE, fog->Mode); 677 } 678 break; 679 case GL_HINT_BIT: 680 { 681 const struct gl_hint_attrib *hint; 682 hint = (const struct gl_hint_attrib *) attr->data; 683 /* XXX this memcpy is temporary: */ 684 MEMCPY(&ctx->Hint, hint, sizeof(struct gl_hint_attrib)); 685 _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, 686 hint->PerspectiveCorrection ); 687 _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); 688 _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); 689 _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); 690 _mesa_Hint(GL_FOG_HINT, hint->Fog); 691 _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, 692 hint->ClipVolumeClipping); 693 if (ctx->Extensions.ARB_texture_compression) 694 _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, 695 hint->TextureCompression); 696 } 697 break; 698 case GL_LIGHTING_BIT: 699 { 700 GLuint i; 701 const struct gl_light_attrib *light; 702 light = (const struct gl_light_attrib *) attr->data; 703 /* lighting enable */ 704 _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); 705 /* per-light state */ 706 for (i = 0; i < MAX_LIGHTS; i++) { 707 GLenum lgt = (GLenum) (GL_LIGHT0 + i); 708 _mesa_set_enable(ctx, lgt, light->Light[i].Enabled); 709 MEMCPY(&ctx->Light.Light[i], &light->Light[i], 710 sizeof(struct gl_light)); 711 } 712 /* light model */ 713 _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, 714 light->Model.Ambient); 715 _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 716 (GLfloat) light->Model.LocalViewer); 717 _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, 718 (GLfloat) light->Model.TwoSide); 719 _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, 720 (GLfloat) light->Model.ColorControl); 721 /* materials */ 722 MEMCPY(ctx->Light.Material, light->Material, 723 2 * sizeof(struct gl_material)); 724 /* shade model */ 725 _mesa_ShadeModel(light->ShadeModel); 726 /* color material */ 727 _mesa_ColorMaterial(light->ColorMaterialFace, 728 light->ColorMaterialMode); 729 _mesa_set_enable(ctx, GL_COLOR_MATERIAL, 730 light->ColorMaterialEnabled); 731 } 732 break; 733 case GL_LINE_BIT: 734 { 735 const struct gl_line_attrib *line; 736 line = (const struct gl_line_attrib *) attr->data; 737 _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); 738 _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); 739 _mesa_LineStipple(line->StippleFactor, line->StipplePattern); 740 _mesa_LineWidth(line->Width); 741 } 742 break; 743 case GL_LIST_BIT: 744 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); 745 break; 746 case GL_PIXEL_MODE_BIT: 747 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); 748 ctx->NewState |= _NEW_PIXEL; 749 break; 750 case GL_POINT_BIT: 751 { 752 const struct gl_point_attrib *point; 753 point = (const struct gl_point_attrib *) attr->data; 754 _mesa_PointSize(point->Size); 755 _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); 756 _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, 757 point->Params); 758 _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT, point->MinSize); 759 _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT, point->MaxSize); 760 _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 761 point->Threshold); 762 } 763 break; 764 case GL_POLYGON_BIT: 765 { 766 const struct gl_polygon_attrib *polygon; 767 polygon = (const struct gl_polygon_attrib *) attr->data; 768 _mesa_CullFace(polygon->CullFaceMode); 769 _mesa_FrontFace(polygon->FrontFace); 770 _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); 771 _mesa_PolygonMode(GL_BACK, polygon->BackMode); 772 _mesa_PolygonOffset(polygon->OffsetFactor, 773 polygon->OffsetUnits); 774 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); 775 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); 776 _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); 777 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, 778 polygon->OffsetPoint); 779 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, 780 polygon->OffsetLine); 781 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, 782 polygon->OffsetFill); 783 } 784 break; 785 case GL_POLYGON_STIPPLE_BIT: 786 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); 787 ctx->NewState |= _NEW_POLYGONSTIPPLE; 788 if (ctx->Driver.PolygonStipple) 789 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); 790 break; 791 case GL_SCISSOR_BIT: 792 { 793 const struct gl_scissor_attrib *scissor; 794 scissor = (const struct gl_scissor_attrib *) attr->data; 795 _mesa_Scissor(scissor->X, scissor->Y, 796 scissor->Width, scissor->Height); 797 _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); 798 } 799 break; 800 case GL_STENCIL_BUFFER_BIT: 801 { 802 const struct gl_stencil_attrib *stencil; 803 stencil = (const struct gl_stencil_attrib *) attr->data; 804 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 805 _mesa_ClearStencil(stencil->Clear); 806 _mesa_StencilFunc(stencil->Function, stencil->Ref, 807 stencil->ValueMask); 808 _mesa_StencilMask(stencil->WriteMask); 809 _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, 810 stencil->ZPassFunc); 811 } 812 break; 813 case GL_TRANSFORM_BIT: 814 { 815 GLuint i; 816 const struct gl_transform_attrib *xform; 817 xform = (const struct gl_transform_attrib *) attr->data; 818 _mesa_MatrixMode(xform->MatrixMode); 819 /* clip planes */ 820 MEMCPY(ctx->Transform.EyeUserPlane, xform->EyeUserPlane, 821 sizeof(xform->EyeUserPlane)); 822 MEMCPY(ctx->Transform._ClipUserPlane, xform->_ClipUserPlane, 823 sizeof(xform->EyeUserPlane)); 824 /* clip plane enable flags */ 825 for (i = 0; i < MAX_CLIP_PLANES; i++) { 826 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, 827 xform->ClipEnabled[i]); 828 } 829 /* normalize/rescale */ 830 _mesa_set_enable(ctx, GL_NORMALIZE, ctx->Transform.Normalize); 831 _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, 832 ctx->Transform.RescaleNormals); 833 } 834 break; 835 case GL_TEXTURE_BIT: 836 /* Take care of texture object reference counters */ 837 { 838 GLuint u; 839 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 840 ctx->Texture.Unit[u].Current1D->RefCount--; 841 ctx->Texture.Unit[u].Current2D->RefCount--; 842 ctx->Texture.Unit[u].Current3D->RefCount--; 843 ctx->Texture.Unit[u].CurrentCubeMap->RefCount--; 844 } 845 MEMCPY( &ctx->Texture, attr->data, 846 sizeof(struct gl_texture_attrib) ); 847 ctx->NewState |= _NEW_TEXTURE; 848 /* restore state of the currently bound texture objects */ 849 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 850 copy_texobj_state( ctx->Texture.Unit[u].Current1D, 851 &(ctx->Texture.Unit[u].Saved1D) ); 852 copy_texobj_state( ctx->Texture.Unit[u].Current2D, 853 &(ctx->Texture.Unit[u].Saved2D) ); 854 copy_texobj_state( ctx->Texture.Unit[u].Current3D, 855 &(ctx->Texture.Unit[u].Saved3D) ); 856 copy_texobj_state( ctx->Texture.Unit[u].CurrentCubeMap, 857 &(ctx->Texture.Unit[u].SavedCubeMap) ); 858 859 ctx->Texture.Unit[u].Current1D->Complete = GL_FALSE; 860 ctx->Texture.Unit[u].Current2D->Complete = GL_FALSE; 861 ctx->Texture.Unit[u].Current3D->Complete = GL_FALSE; 862 ctx->Texture.Unit[u].CurrentCubeMap->Complete = GL_FALSE; 863 } 864 } 865 break; 866 case GL_VIEWPORT_BIT: 867 { 868 const struct gl_viewport_attrib *vp; 869 vp = (const struct gl_viewport_attrib *)attr->data; 870 _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); 871 _mesa_DepthRange(vp->Near, vp->Far); 872 } 873 break; 874 default: 875 _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); 876 break; 877 } 878 879 next = attr->next; 880 FREE( attr->data ); 881 FREE( attr ); 882 attr = next; 883 } 884} 885 886 887#define GL_CLIENT_PACK_BIT (1<<20) 888#define GL_CLIENT_UNPACK_BIT (1<<21) 889 890 891void 892_mesa_PushClientAttrib(GLbitfield mask) 893{ 894 struct gl_attrib_node *newnode; 895 struct gl_attrib_node *head; 896 897 GET_CURRENT_CONTEXT(ctx); 898 ASSERT_OUTSIDE_BEGIN_END(ctx); 899 900 if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { 901 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); 902 return; 903 } 904 905 /* Build linked list of attribute nodes which save all attribute */ 906 /* groups specified by the mask. */ 907 head = NULL; 908 909 if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 910 struct gl_pixelstore_attrib *attr; 911 /* packing attribs */ 912 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 913 MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) ); 914 newnode = new_attrib_node( GL_CLIENT_PACK_BIT ); 915 newnode->data = attr; 916 newnode->next = head; 917 head = newnode; 918 /* unpacking attribs */ 919 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 920 MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) ); 921 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT ); 922 newnode->data = attr; 923 newnode->next = head; 924 head = newnode; 925 } 926 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 927 struct gl_array_attrib *attr; 928 attr = MALLOC_STRUCT( gl_array_attrib ); 929 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); 930 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT ); 931 newnode->data = attr; 932 newnode->next = head; 933 head = newnode; 934 } 935 936 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; 937 ctx->ClientAttribStackDepth++; 938} 939 940 941 942 943void 944_mesa_PopClientAttrib(void) 945{ 946 struct gl_attrib_node *attr, *next; 947 948 GET_CURRENT_CONTEXT(ctx); 949 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 950 951 if (ctx->ClientAttribStackDepth == 0) { 952 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); 953 return; 954 } 955 956 ctx->ClientAttribStackDepth--; 957 attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 958 959 while (attr) { 960 switch (attr->kind) { 961 case GL_CLIENT_PACK_BIT: 962 MEMCPY( &ctx->Pack, attr->data, 963 sizeof(struct gl_pixelstore_attrib) ); 964 ctx->NewState = _NEW_PACKUNPACK; 965 break; 966 case GL_CLIENT_UNPACK_BIT: 967 MEMCPY( &ctx->Unpack, attr->data, 968 sizeof(struct gl_pixelstore_attrib) ); 969 ctx->NewState = _NEW_PACKUNPACK; 970 break; 971 case GL_CLIENT_VERTEX_ARRAY_BIT: 972 MEMCPY( &ctx->Array, attr->data, 973 sizeof(struct gl_array_attrib) ); 974 ctx->NewState = _NEW_ARRAY; 975 break; 976 default: 977 _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); 978 break; 979 } 980 981 next = attr->next; 982 FREE( attr->data ); 983 FREE( attr ); 984 attr = next; 985 } 986} 987