attrib.c revision 33fa5e4bfad8005f09ad3c9fc92c40fa863935d1
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.3 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26#include "glheader.h" 27#include "imports.h" 28#include "accum.h" 29#include "arrayobj.h" 30#include "attrib.h" 31#include "blend.h" 32#include "buffers.h" 33#include "bufferobj.h" 34#include "clear.h" 35#include "colormac.h" 36#include "colortab.h" 37#include "context.h" 38#include "depth.h" 39#include "enable.h" 40#include "enums.h" 41#include "fog.h" 42#include "hint.h" 43#include "light.h" 44#include "lines.h" 45#include "matrix.h" 46#include "multisample.h" 47#include "points.h" 48#include "polygon.h" 49#include "scissor.h" 50#include "simple_list.h" 51#include "stencil.h" 52#include "texenv.h" 53#include "texgen.h" 54#include "texobj.h" 55#include "texparam.h" 56#include "texstate.h" 57#include "varray.h" 58#include "mtypes.h" 59#include "math/m_xform.h" 60 61/** 62 * Special struct for saving/restoring texture state (GL_TEXTURE_BIT) 63 */ 64struct texture_state 65{ 66 struct gl_texture_attrib Texture; /**< The usual context state */ 67 68 /** to save per texture object state (wrap modes, filters, etc): */ 69 struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; 70 71 /** 72 * To save references to texture objects (so they don't get accidentally 73 * deleted while saved in the attribute stack). 74 */ 75 struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; 76}; 77 78 79/** 80 * Allocate a new attribute state node. These nodes have a 81 * "kind" value and a pointer to a struct of state data. 82 */ 83static struct gl_attrib_node * 84new_attrib_node( GLbitfield kind ) 85{ 86 struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node); 87 if (an) { 88 an->kind = kind; 89 } 90 return an; 91} 92 93 94void GLAPIENTRY 95_mesa_PushAttrib(GLbitfield mask) 96{ 97 struct gl_attrib_node *newnode; 98 struct gl_attrib_node *head; 99 100 GET_CURRENT_CONTEXT(ctx); 101 ASSERT_OUTSIDE_BEGIN_END(ctx); 102 103 if (MESA_VERBOSE & VERBOSE_API) 104 _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask); 105 106 if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { 107 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); 108 return; 109 } 110 111 /* Build linked list of attribute nodes which save all attribute */ 112 /* groups specified by the mask. */ 113 head = NULL; 114 115 if (mask & GL_ACCUM_BUFFER_BIT) { 116 struct gl_accum_attrib *attr; 117 attr = MALLOC_STRUCT( gl_accum_attrib ); 118 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); 119 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT ); 120 newnode->data = attr; 121 newnode->next = head; 122 head = newnode; 123 } 124 125 if (mask & GL_COLOR_BUFFER_BIT) { 126 GLuint i; 127 struct gl_colorbuffer_attrib *attr; 128 attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); 129 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); 130 /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */ 131 for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++) 132 attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; 133 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT ); 134 newnode->data = attr; 135 newnode->next = head; 136 head = newnode; 137 } 138 139 if (mask & GL_CURRENT_BIT) { 140 struct gl_current_attrib *attr; 141 FLUSH_CURRENT( ctx, 0 ); 142 attr = MALLOC_STRUCT( gl_current_attrib ); 143 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); 144 newnode = new_attrib_node( GL_CURRENT_BIT ); 145 newnode->data = attr; 146 newnode->next = head; 147 head = newnode; 148 } 149 150 if (mask & GL_DEPTH_BUFFER_BIT) { 151 struct gl_depthbuffer_attrib *attr; 152 attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); 153 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); 154 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT ); 155 newnode->data = attr; 156 newnode->next = head; 157 head = newnode; 158 } 159 160 if (mask & GL_ENABLE_BIT) { 161 struct gl_enable_attrib *attr; 162 GLuint i; 163 attr = MALLOC_STRUCT( gl_enable_attrib ); 164 /* Copy enable flags from all other attributes into the enable struct. */ 165 attr->AlphaTest = ctx->Color.AlphaEnabled; 166 attr->AutoNormal = ctx->Eval.AutoNormal; 167 attr->Blend = ctx->Color.BlendEnabled; 168 attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; 169 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 170 for (i = 0; i < COLORTABLE_MAX; i++) { 171 attr->ColorTable[i] = ctx->Pixel.ColorTableEnabled[i]; 172 } 173 attr->Convolution1D = ctx->Pixel.Convolution1DEnabled; 174 attr->Convolution2D = ctx->Pixel.Convolution2DEnabled; 175 attr->Separable2D = ctx->Pixel.Separable2DEnabled; 176 attr->CullFace = ctx->Polygon.CullFlag; 177 attr->DepthTest = ctx->Depth.Test; 178 attr->Dither = ctx->Color.DitherFlag; 179 attr->Fog = ctx->Fog.Enabled; 180 for (i = 0; i < ctx->Const.MaxLights; i++) { 181 attr->Light[i] = ctx->Light.Light[i].Enabled; 182 } 183 attr->Lighting = ctx->Light.Enabled; 184 attr->LineSmooth = ctx->Line.SmoothFlag; 185 attr->LineStipple = ctx->Line.StippleFlag; 186 attr->Histogram = ctx->Pixel.HistogramEnabled; 187 attr->MinMax = ctx->Pixel.MinMaxEnabled; 188 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 189 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 190 attr->Map1Color4 = ctx->Eval.Map1Color4; 191 attr->Map1Index = ctx->Eval.Map1Index; 192 attr->Map1Normal = ctx->Eval.Map1Normal; 193 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 194 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 195 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 196 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 197 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 198 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 199 MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib)); 200 attr->Map2Color4 = ctx->Eval.Map2Color4; 201 attr->Map2Index = ctx->Eval.Map2Index; 202 attr->Map2Normal = ctx->Eval.Map2Normal; 203 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 204 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 205 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 206 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 207 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 208 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 209 MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib)); 210 attr->Normalize = ctx->Transform.Normalize; 211 attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped; 212 attr->PointSmooth = ctx->Point.SmoothFlag; 213 attr->PointSprite = ctx->Point.PointSprite; 214 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 215 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 216 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 217 attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 218 attr->PolygonStipple = ctx->Polygon.StippleFlag; 219 attr->RescaleNormals = ctx->Transform.RescaleNormals; 220 attr->Scissor = ctx->Scissor.Enabled; 221 attr->Stencil = ctx->Stencil.Enabled; 222 attr->StencilTwoSide = ctx->Stencil.TestTwoSide; 223 attr->MultisampleEnabled = ctx->Multisample.Enabled; 224 attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage; 225 attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; 226 attr->SampleCoverage = ctx->Multisample.SampleCoverage; 227 attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert; 228 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 229 attr->Texture[i] = ctx->Texture.Unit[i].Enabled; 230 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; 231 attr->TextureColorTable[i] = ctx->Texture.Unit[i].ColorTableEnabled; 232 } 233 /* GL_NV_vertex_program */ 234 attr->VertexProgram = ctx->VertexProgram.Enabled; 235 attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled; 236 attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled; 237 newnode = new_attrib_node( GL_ENABLE_BIT ); 238 newnode->data = attr; 239 newnode->next = head; 240 head = newnode; 241 } 242 243 if (mask & GL_EVAL_BIT) { 244 struct gl_eval_attrib *attr; 245 attr = MALLOC_STRUCT( gl_eval_attrib ); 246 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); 247 newnode = new_attrib_node( GL_EVAL_BIT ); 248 newnode->data = attr; 249 newnode->next = head; 250 head = newnode; 251 } 252 253 if (mask & GL_FOG_BIT) { 254 struct gl_fog_attrib *attr; 255 attr = MALLOC_STRUCT( gl_fog_attrib ); 256 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); 257 newnode = new_attrib_node( GL_FOG_BIT ); 258 newnode->data = attr; 259 newnode->next = head; 260 head = newnode; 261 } 262 263 if (mask & GL_HINT_BIT) { 264 struct gl_hint_attrib *attr; 265 attr = MALLOC_STRUCT( gl_hint_attrib ); 266 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); 267 newnode = new_attrib_node( GL_HINT_BIT ); 268 newnode->data = attr; 269 newnode->next = head; 270 head = newnode; 271 } 272 273 if (mask & GL_LIGHTING_BIT) { 274 struct gl_light_attrib *attr; 275 FLUSH_CURRENT(ctx, 0); /* flush material changes */ 276 attr = MALLOC_STRUCT( gl_light_attrib ); 277 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); 278 newnode = new_attrib_node( GL_LIGHTING_BIT ); 279 newnode->data = attr; 280 newnode->next = head; 281 head = newnode; 282 } 283 284 if (mask & GL_LINE_BIT) { 285 struct gl_line_attrib *attr; 286 attr = MALLOC_STRUCT( gl_line_attrib ); 287 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); 288 newnode = new_attrib_node( GL_LINE_BIT ); 289 newnode->data = attr; 290 newnode->next = head; 291 head = newnode; 292 } 293 294 if (mask & GL_LIST_BIT) { 295 struct gl_list_attrib *attr; 296 attr = MALLOC_STRUCT( gl_list_attrib ); 297 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) ); 298 newnode = new_attrib_node( GL_LIST_BIT ); 299 newnode->data = attr; 300 newnode->next = head; 301 head = newnode; 302 } 303 304 if (mask & GL_PIXEL_MODE_BIT) { 305 struct gl_pixel_attrib *attr; 306 attr = MALLOC_STRUCT( gl_pixel_attrib ); 307 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); 308 /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ 309 attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; 310 newnode = new_attrib_node( GL_PIXEL_MODE_BIT ); 311 newnode->data = attr; 312 newnode->next = head; 313 head = newnode; 314 } 315 316 if (mask & GL_POINT_BIT) { 317 struct gl_point_attrib *attr; 318 attr = MALLOC_STRUCT( gl_point_attrib ); 319 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); 320 newnode = new_attrib_node( GL_POINT_BIT ); 321 newnode->data = attr; 322 newnode->next = head; 323 head = newnode; 324 } 325 326 if (mask & GL_POLYGON_BIT) { 327 struct gl_polygon_attrib *attr; 328 attr = MALLOC_STRUCT( gl_polygon_attrib ); 329 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); 330 newnode = new_attrib_node( GL_POLYGON_BIT ); 331 newnode->data = attr; 332 newnode->next = head; 333 head = newnode; 334 } 335 336 if (mask & GL_POLYGON_STIPPLE_BIT) { 337 GLuint *stipple; 338 stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) ); 339 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); 340 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT ); 341 newnode->data = stipple; 342 newnode->next = head; 343 head = newnode; 344 } 345 346 if (mask & GL_SCISSOR_BIT) { 347 struct gl_scissor_attrib *attr; 348 attr = MALLOC_STRUCT( gl_scissor_attrib ); 349 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); 350 newnode = new_attrib_node( GL_SCISSOR_BIT ); 351 newnode->data = attr; 352 newnode->next = head; 353 head = newnode; 354 } 355 356 if (mask & GL_STENCIL_BUFFER_BIT) { 357 struct gl_stencil_attrib *attr; 358 attr = MALLOC_STRUCT( gl_stencil_attrib ); 359 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); 360 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT ); 361 newnode->data = attr; 362 newnode->next = head; 363 head = newnode; 364 } 365 366 if (mask & GL_TEXTURE_BIT) { 367 struct texture_state *texstate = CALLOC_STRUCT(texture_state); 368 GLuint u; 369 370 if (!texstate) { 371 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); 372 goto end; 373 } 374 375 _mesa_lock_context_textures(ctx); 376 377 /* copy/save the bulk of texture state here */ 378 _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture)); 379 380 /* Save references to the currently bound texture objects so they don't 381 * accidentally get deleted while referenced in the attribute stack. 382 */ 383 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 384 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_1D_INDEX], 385 ctx->Texture.Unit[u].Current1D); 386 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_2D_INDEX], 387 ctx->Texture.Unit[u].Current2D); 388 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_3D_INDEX], 389 ctx->Texture.Unit[u].Current3D); 390 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_CUBE_INDEX], 391 ctx->Texture.Unit[u].CurrentCubeMap); 392 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_RECT_INDEX], 393 ctx->Texture.Unit[u].CurrentRect); 394 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_1D_ARRAY_INDEX], 395 ctx->Texture.Unit[u].Current1DArray); 396 _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_2D_ARRAY_INDEX], 397 ctx->Texture.Unit[u].Current2DArray); 398 } 399 400 /* copy state/contents of the currently bound texture objects */ 401 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 402 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_1D_INDEX], 403 ctx->Texture.Unit[u].Current1D); 404 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_2D_INDEX], 405 ctx->Texture.Unit[u].Current2D); 406 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_3D_INDEX], 407 ctx->Texture.Unit[u].Current3D); 408 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_CUBE_INDEX], 409 ctx->Texture.Unit[u].CurrentCubeMap); 410 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_RECT_INDEX], 411 ctx->Texture.Unit[u].CurrentRect); 412 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_1D_ARRAY_INDEX], 413 ctx->Texture.Unit[u].Current1DArray); 414 _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_2D_ARRAY_INDEX], 415 ctx->Texture.Unit[u].Current2DArray); 416 } 417 418 _mesa_unlock_context_textures(ctx); 419 420 newnode = new_attrib_node( GL_TEXTURE_BIT ); 421 newnode->data = texstate; 422 newnode->next = head; 423 head = newnode; 424 } 425 426 if (mask & GL_TRANSFORM_BIT) { 427 struct gl_transform_attrib *attr; 428 attr = MALLOC_STRUCT( gl_transform_attrib ); 429 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); 430 newnode = new_attrib_node( GL_TRANSFORM_BIT ); 431 newnode->data = attr; 432 newnode->next = head; 433 head = newnode; 434 } 435 436 if (mask & GL_VIEWPORT_BIT) { 437 struct gl_viewport_attrib *attr; 438 attr = MALLOC_STRUCT( gl_viewport_attrib ); 439 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); 440 newnode = new_attrib_node( GL_VIEWPORT_BIT ); 441 newnode->data = attr; 442 newnode->next = head; 443 head = newnode; 444 } 445 446 /* GL_ARB_multisample */ 447 if (mask & GL_MULTISAMPLE_BIT_ARB) { 448 struct gl_multisample_attrib *attr; 449 attr = MALLOC_STRUCT( gl_multisample_attrib ); 450 MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) ); 451 newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB ); 452 newnode->data = attr; 453 newnode->next = head; 454 head = newnode; 455 } 456 457end: 458 ctx->AttribStack[ctx->AttribStackDepth] = head; 459 ctx->AttribStackDepth++; 460} 461 462 463 464static void 465pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) 466{ 467 GLuint i; 468 469#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ 470 if ((VALUE) != (NEWVALUE)) { \ 471 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ 472 } 473 474 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 475 TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); 476 477 for (i=0;i<MAX_CLIP_PLANES;i++) { 478 const GLuint mask = 1 << i; 479 if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask)) 480 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), 481 (GLboolean) ((enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE)); 482 } 483 484 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 485 GL_COLOR_MATERIAL); 486 TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION], 487 enable->ColorTable[COLORTABLE_PRECONVOLUTION], 488 GL_COLOR_TABLE); 489 TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION], 490 enable->ColorTable[COLORTABLE_POSTCONVOLUTION], 491 GL_POST_CONVOLUTION_COLOR_TABLE); 492 TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX], 493 enable->ColorTable[COLORTABLE_POSTCOLORMATRIX], 494 GL_POST_COLOR_MATRIX_COLOR_TABLE); 495 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 496 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 497 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 498 TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D, 499 GL_CONVOLUTION_1D); 500 TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D, 501 GL_CONVOLUTION_2D); 502 TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D, 503 GL_SEPARABLE_2D); 504 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 505 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 506 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 507 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 508 GL_LINE_STIPPLE); 509 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 510 GL_INDEX_LOGIC_OP); 511 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 512 GL_COLOR_LOGIC_OP); 513 514 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 515 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 516 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 517 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 518 GL_MAP1_TEXTURE_COORD_1); 519 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 520 GL_MAP1_TEXTURE_COORD_2); 521 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 522 GL_MAP1_TEXTURE_COORD_3); 523 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 524 GL_MAP1_TEXTURE_COORD_4); 525 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 526 GL_MAP1_VERTEX_3); 527 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 528 GL_MAP1_VERTEX_4); 529 for (i = 0; i < 16; i++) { 530 TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i], 531 GL_MAP1_VERTEX_ATTRIB0_4_NV + i); 532 } 533 534 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 535 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 536 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 537 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 538 GL_MAP2_TEXTURE_COORD_1); 539 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 540 GL_MAP2_TEXTURE_COORD_2); 541 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 542 GL_MAP2_TEXTURE_COORD_3); 543 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 544 GL_MAP2_TEXTURE_COORD_4); 545 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 546 GL_MAP2_VERTEX_3); 547 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 548 GL_MAP2_VERTEX_4); 549 for (i = 0; i < 16; i++) { 550 TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i], 551 GL_MAP2_VERTEX_ATTRIB0_4_NV + i); 552 } 553 554 TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL); 555 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 556 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 557 GL_RESCALE_NORMAL_EXT); 558 TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped, 559 enable->RasterPositionUnclipped, 560 GL_RASTER_POSITION_UNCLIPPED_IBM); 561 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 562 GL_POINT_SMOOTH); 563 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) { 564 TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, 565 GL_POINT_SPRITE_NV); 566 } 567 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 568 GL_POLYGON_OFFSET_POINT); 569 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 570 GL_POLYGON_OFFSET_LINE); 571 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 572 GL_POLYGON_OFFSET_FILL); 573 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 574 GL_POLYGON_SMOOTH); 575 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 576 GL_POLYGON_STIPPLE); 577 TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); 578 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 579 if (ctx->Extensions.EXT_stencil_two_side) { 580 TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT); 581 } 582 TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, 583 GL_MULTISAMPLE_ARB); 584 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 585 enable->SampleAlphaToCoverage, 586 GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 587 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 588 enable->SampleAlphaToOne, 589 GL_SAMPLE_ALPHA_TO_ONE_ARB); 590 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 591 enable->SampleCoverage, 592 GL_SAMPLE_COVERAGE_ARB); 593 TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert, 594 enable->SampleCoverageInvert, 595 GL_SAMPLE_COVERAGE_INVERT_ARB); 596 /* GL_ARB_vertex_program, GL_NV_vertex_program */ 597 TEST_AND_UPDATE(ctx->VertexProgram.Enabled, 598 enable->VertexProgram, 599 GL_VERTEX_PROGRAM_ARB); 600 TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled, 601 enable->VertexProgramPointSize, 602 GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 603 TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled, 604 enable->VertexProgramTwoSide, 605 GL_VERTEX_PROGRAM_TWO_SIDE_ARB); 606 607#undef TEST_AND_UPDATE 608 609 /* texture unit enables */ 610 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 611 if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) { 612 ctx->Texture.Unit[i].Enabled = enable->Texture[i]; 613 if (ctx->Driver.Enable) { 614 if (ctx->Driver.ActiveTexture) { 615 (*ctx->Driver.ActiveTexture)(ctx, i); 616 } 617 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, 618 (GLboolean) (enable->Texture[i] & TEXTURE_1D_BIT) ); 619 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, 620 (GLboolean) (enable->Texture[i] & TEXTURE_2D_BIT) ); 621 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, 622 (GLboolean) (enable->Texture[i] & TEXTURE_3D_BIT) ); 623 if (ctx->Extensions.ARB_texture_cube_map) 624 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_CUBE_MAP_ARB, 625 (GLboolean) (enable->Texture[i] & TEXTURE_CUBE_BIT) ); 626 if (ctx->Extensions.NV_texture_rectangle) 627 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, 628 (GLboolean) (enable->Texture[i] & TEXTURE_RECT_BIT) ); 629 } 630 } 631 632 if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) { 633 ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i]; 634 if (ctx->Driver.Enable) { 635 if (ctx->Driver.ActiveTexture) { 636 (*ctx->Driver.ActiveTexture)(ctx, i); 637 } 638 if (enable->TexGen[i] & S_BIT) 639 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE); 640 else 641 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE); 642 if (enable->TexGen[i] & T_BIT) 643 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE); 644 else 645 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE); 646 if (enable->TexGen[i] & R_BIT) 647 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE); 648 else 649 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE); 650 if (enable->TexGen[i] & Q_BIT) 651 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE); 652 else 653 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 654 } 655 } 656 657 /* GL_SGI_texture_color_table */ 658 ctx->Texture.Unit[i].ColorTableEnabled = enable->TextureColorTable[i]; 659 } 660 661 if (ctx->Driver.ActiveTexture) { 662 (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit); 663 } 664} 665 666 667/** 668 * Pop/restore texture attribute/group state. 669 */ 670static void 671pop_texture_group(GLcontext *ctx, struct texture_state *texstate) 672{ 673 GLuint u; 674 675 _mesa_lock_context_textures(ctx); 676 677 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 678 const struct gl_texture_unit *unit = &texstate->Texture.Unit[u]; 679 GLuint tgt; 680 681 _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u); 682 _mesa_set_enable(ctx, GL_TEXTURE_1D, 683 (unit->Enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE); 684 _mesa_set_enable(ctx, GL_TEXTURE_2D, 685 (unit->Enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE); 686 _mesa_set_enable(ctx, GL_TEXTURE_3D, 687 (unit->Enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE); 688 if (ctx->Extensions.ARB_texture_cube_map) { 689 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB, 690 (unit->Enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE); 691 } 692 if (ctx->Extensions.NV_texture_rectangle) { 693 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV, 694 (unit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE); 695 } 696 if (ctx->Extensions.SGI_texture_color_table) { 697 _mesa_set_enable(ctx, GL_TEXTURE_COLOR_TABLE_SGI, 698 unit->ColorTableEnabled); 699 } 700 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); 701 _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); 702 _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS); 703 _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT); 704 _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR); 705 _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ); 706 _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS); 707 _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT); 708 _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR); 709 _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ); 710 /* Eye plane done differently to avoid re-transformation */ 711 { 712 struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u]; 713 COPY_4FV(destUnit->EyePlaneS, unit->EyePlaneS); 714 COPY_4FV(destUnit->EyePlaneT, unit->EyePlaneT); 715 COPY_4FV(destUnit->EyePlaneR, unit->EyePlaneR); 716 COPY_4FV(destUnit->EyePlaneQ, unit->EyePlaneQ); 717 if (ctx->Driver.TexGen) { 718 ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->EyePlaneS); 719 ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->EyePlaneT); 720 ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->EyePlaneR); 721 ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->EyePlaneQ); 722 } 723 } 724 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, 725 ((unit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE)); 726 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, 727 ((unit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE)); 728 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, 729 ((unit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE)); 730 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, 731 ((unit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE)); 732 if (ctx->Extensions.EXT_texture_lod_bias) { 733 _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, 734 GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias); 735 } 736 if (ctx->Extensions.EXT_texture_env_combine || 737 ctx->Extensions.ARB_texture_env_combine) { 738 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, 739 unit->Combine.ModeRGB); 740 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 741 unit->Combine.ModeA); 742 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, 743 unit->Combine.SourceRGB[0]); 744 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, 745 unit->Combine.SourceRGB[1]); 746 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, 747 unit->Combine.SourceRGB[2]); 748 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, 749 unit->Combine.SourceA[0]); 750 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, 751 unit->Combine.SourceA[1]); 752 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, 753 unit->Combine.SourceA[2]); 754 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, 755 unit->Combine.OperandRGB[0]); 756 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, 757 unit->Combine.OperandRGB[1]); 758 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, 759 unit->Combine.OperandRGB[2]); 760 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, 761 unit->Combine.OperandA[0]); 762 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, 763 unit->Combine.OperandA[1]); 764 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, 765 unit->Combine.OperandA[2]); 766 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 767 1 << unit->Combine.ScaleShiftRGB); 768 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 769 1 << unit->Combine.ScaleShiftA); 770 } 771 772 /* Restore texture object state for each target */ 773 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 774 const struct gl_texture_object *obj = NULL; 775 GLfloat bordColor[4]; 776 GLenum target; 777 778 obj = &texstate->SavedObj[u][tgt]; 779 780 /* don't restore state for unsupported targets to prevent 781 * raising GL errors. 782 */ 783 if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB && 784 !ctx->Extensions.ARB_texture_cube_map) { 785 continue; 786 } 787 else if (obj->Target == GL_TEXTURE_RECTANGLE_NV && 788 !ctx->Extensions.NV_texture_rectangle) { 789 continue; 790 } 791 else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT || 792 obj->Target == GL_TEXTURE_2D_ARRAY_EXT) && 793 !ctx->Extensions.MESA_texture_array) { 794 continue; 795 } 796 797 target = obj->Target; 798 799 _mesa_BindTexture(target, obj->Name); 800 801 bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]); 802 bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]); 803 bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]); 804 bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]); 805 806 _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor); 807 _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); 808 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS); 809 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT); 810 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR); 811 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter); 812 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter); 813 _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod); 814 _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod); 815 _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, obj->LodBias); 816 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel); 817 if (target != GL_TEXTURE_RECTANGLE_ARB) 818 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel); 819 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 820 _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 821 obj->MaxAnisotropy); 822 } 823 if (ctx->Extensions.ARB_shadow_ambient) { 824 _mesa_TexParameterf(target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 825 obj->CompareFailValue); 826 } 827 } 828 829 /* remove saved references to the texture objects */ 830 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 831 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); 832 } 833 } 834 835 _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit); 836 837 _mesa_unlock_context_textures(ctx); 838} 839 840 841/* 842 * This function is kind of long just because we have to call a lot 843 * of device driver functions to update device driver state. 844 * 845 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions 846 * in order to restore GL state. This isn't terribly efficient but it 847 * ensures that dirty flags and any derived state gets updated correctly. 848 * We could at least check if the value to restore equals the current value 849 * and then skip the Mesa call. 850 */ 851void GLAPIENTRY 852_mesa_PopAttrib(void) 853{ 854 struct gl_attrib_node *attr, *next; 855 GET_CURRENT_CONTEXT(ctx); 856 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 857 858 if (ctx->AttribStackDepth == 0) { 859 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); 860 return; 861 } 862 863 ctx->AttribStackDepth--; 864 attr = ctx->AttribStack[ctx->AttribStackDepth]; 865 866 while (attr) { 867 868 if (MESA_VERBOSE & VERBOSE_API) { 869 _mesa_debug(ctx, "glPopAttrib %s\n", 870 _mesa_lookup_enum_by_nr(attr->kind)); 871 } 872 873 switch (attr->kind) { 874 case GL_ACCUM_BUFFER_BIT: 875 { 876 const struct gl_accum_attrib *accum; 877 accum = (const struct gl_accum_attrib *) attr->data; 878 _mesa_ClearAccum(accum->ClearColor[0], 879 accum->ClearColor[1], 880 accum->ClearColor[2], 881 accum->ClearColor[3]); 882 } 883 break; 884 case GL_COLOR_BUFFER_BIT: 885 { 886 const struct gl_colorbuffer_attrib *color; 887 color = (const struct gl_colorbuffer_attrib *) attr->data; 888 _mesa_ClearIndex((GLfloat) color->ClearIndex); 889 _mesa_ClearColor(color->ClearColor[0], 890 color->ClearColor[1], 891 color->ClearColor[2], 892 color->ClearColor[3]); 893 _mesa_IndexMask(color->IndexMask); 894 _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0), 895 (GLboolean) (color->ColorMask[1] != 0), 896 (GLboolean) (color->ColorMask[2] != 0), 897 (GLboolean) (color->ColorMask[3] != 0)); 898 { 899 /* Need to determine if more than one color output is 900 * specified. If so, call glDrawBuffersARB, else call 901 * glDrawBuffer(). This is a subtle, but essential point 902 * since GL_FRONT (for example) is illegal for the former 903 * function, but legal for the later. 904 */ 905 GLboolean multipleBuffers = GL_FALSE; 906 if (ctx->Extensions.ARB_draw_buffers) { 907 GLuint i; 908 for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { 909 if (color->DrawBuffer[i] != GL_NONE) { 910 multipleBuffers = GL_TRUE; 911 break; 912 } 913 } 914 } 915 /* Call the API_level functions, not _mesa_drawbuffers() 916 * since we need to do error checking on the pop'd 917 * GL_DRAW_BUFFER. 918 * Ex: if GL_FRONT were pushed, but we're popping with a 919 * user FBO bound, GL_FRONT will be illegal and we'll need 920 * to record that error. Per OpenGL ARB decision. 921 */ 922 if (multipleBuffers) 923 _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers, 924 color->DrawBuffer); 925 else 926 _mesa_DrawBuffer(color->DrawBuffer[0]); 927 } 928 _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); 929 _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef); 930 _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); 931 _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, 932 color->BlendDstRGB, 933 color->BlendSrcA, 934 color->BlendDstA); 935 /* This special case is because glBlendEquationSeparateEXT 936 * cannot take GL_LOGIC_OP as a parameter. 937 */ 938 if ( color->BlendEquationRGB == color->BlendEquationA ) { 939 _mesa_BlendEquation(color->BlendEquationRGB); 940 } 941 else { 942 _mesa_BlendEquationSeparateEXT(color->BlendEquationRGB, 943 color->BlendEquationA); 944 } 945 _mesa_BlendColor(color->BlendColor[0], 946 color->BlendColor[1], 947 color->BlendColor[2], 948 color->BlendColor[3]); 949 _mesa_LogicOp(color->LogicOp); 950 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, 951 color->ColorLogicOpEnabled); 952 _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, 953 color->IndexLogicOpEnabled); 954 _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); 955 } 956 break; 957 case GL_CURRENT_BIT: 958 FLUSH_CURRENT( ctx, 0 ); 959 MEMCPY( &ctx->Current, attr->data, 960 sizeof(struct gl_current_attrib) ); 961 break; 962 case GL_DEPTH_BUFFER_BIT: 963 { 964 const struct gl_depthbuffer_attrib *depth; 965 depth = (const struct gl_depthbuffer_attrib *) attr->data; 966 _mesa_DepthFunc(depth->Func); 967 _mesa_ClearDepth(depth->Clear); 968 _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); 969 _mesa_DepthMask(depth->Mask); 970 } 971 break; 972 case GL_ENABLE_BIT: 973 { 974 const struct gl_enable_attrib *enable; 975 enable = (const struct gl_enable_attrib *) attr->data; 976 pop_enable_group(ctx, enable); 977 ctx->NewState |= _NEW_ALL; 978 } 979 break; 980 case GL_EVAL_BIT: 981 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); 982 ctx->NewState |= _NEW_EVAL; 983 break; 984 case GL_FOG_BIT: 985 { 986 const struct gl_fog_attrib *fog; 987 fog = (const struct gl_fog_attrib *) attr->data; 988 _mesa_set_enable(ctx, GL_FOG, fog->Enabled); 989 _mesa_Fogfv(GL_FOG_COLOR, fog->Color); 990 _mesa_Fogf(GL_FOG_DENSITY, fog->Density); 991 _mesa_Fogf(GL_FOG_START, fog->Start); 992 _mesa_Fogf(GL_FOG_END, fog->End); 993 _mesa_Fogf(GL_FOG_INDEX, fog->Index); 994 _mesa_Fogi(GL_FOG_MODE, fog->Mode); 995 } 996 break; 997 case GL_HINT_BIT: 998 { 999 const struct gl_hint_attrib *hint; 1000 hint = (const struct gl_hint_attrib *) attr->data; 1001 _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, 1002 hint->PerspectiveCorrection ); 1003 _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); 1004 _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); 1005 _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); 1006 _mesa_Hint(GL_FOG_HINT, hint->Fog); 1007 _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, 1008 hint->ClipVolumeClipping); 1009 _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, 1010 hint->TextureCompression); 1011 } 1012 break; 1013 case GL_LIGHTING_BIT: 1014 { 1015 GLuint i; 1016 const struct gl_light_attrib *light; 1017 light = (const struct gl_light_attrib *) attr->data; 1018 /* lighting enable */ 1019 _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); 1020 /* per-light state */ 1021 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) 1022 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 1023 1024 for (i = 0; i < ctx->Const.MaxLights; i++) { 1025 const struct gl_light *l = &light->Light[i]; 1026 _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled); 1027 _mesa_light(ctx, i, GL_AMBIENT, l->Ambient); 1028 _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse); 1029 _mesa_light(ctx, i, GL_SPECULAR, l->Specular ); 1030 _mesa_light(ctx, i, GL_POSITION, l->EyePosition); 1031 _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->EyeDirection); 1032 _mesa_light(ctx, i, GL_SPOT_EXPONENT, &l->SpotExponent); 1033 _mesa_light(ctx, i, GL_SPOT_CUTOFF, &l->SpotCutoff); 1034 _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, 1035 &l->ConstantAttenuation); 1036 _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, 1037 &l->LinearAttenuation); 1038 _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, 1039 &l->QuadraticAttenuation); 1040 } 1041 /* light model */ 1042 _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, 1043 light->Model.Ambient); 1044 _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1045 (GLfloat) light->Model.LocalViewer); 1046 _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1047 (GLfloat) light->Model.TwoSide); 1048 _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, 1049 (GLfloat) light->Model.ColorControl); 1050 /* shade model */ 1051 _mesa_ShadeModel(light->ShadeModel); 1052 /* color material */ 1053 _mesa_ColorMaterial(light->ColorMaterialFace, 1054 light->ColorMaterialMode); 1055 _mesa_set_enable(ctx, GL_COLOR_MATERIAL, 1056 light->ColorMaterialEnabled); 1057 /* materials */ 1058 MEMCPY(&ctx->Light.Material, &light->Material, 1059 sizeof(struct gl_material)); 1060 } 1061 break; 1062 case GL_LINE_BIT: 1063 { 1064 const struct gl_line_attrib *line; 1065 line = (const struct gl_line_attrib *) attr->data; 1066 _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); 1067 _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); 1068 _mesa_LineStipple(line->StippleFactor, line->StipplePattern); 1069 _mesa_LineWidth(line->Width); 1070 } 1071 break; 1072 case GL_LIST_BIT: 1073 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); 1074 break; 1075 case GL_PIXEL_MODE_BIT: 1076 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); 1077 /* XXX what other pixel state needs to be set by function calls? */ 1078 _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); 1079 ctx->NewState |= _NEW_PIXEL; 1080 break; 1081 case GL_POINT_BIT: 1082 { 1083 const struct gl_point_attrib *point; 1084 point = (const struct gl_point_attrib *) attr->data; 1085 _mesa_PointSize(point->Size); 1086 _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); 1087 if (ctx->Extensions.EXT_point_parameters) { 1088 _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, 1089 point->Params); 1090 _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT, 1091 point->MinSize); 1092 _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT, 1093 point->MaxSize); 1094 _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1095 point->Threshold); 1096 } 1097 if (ctx->Extensions.NV_point_sprite 1098 || ctx->Extensions.ARB_point_sprite) { 1099 GLuint u; 1100 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 1101 _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, 1102 (GLint) point->CoordReplace[u]); 1103 } 1104 _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite); 1105 if (ctx->Extensions.NV_point_sprite) 1106 _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV, 1107 ctx->Point.SpriteRMode); 1108 _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, 1109 (GLfloat)ctx->Point.SpriteOrigin); 1110 } 1111 } 1112 break; 1113 case GL_POLYGON_BIT: 1114 { 1115 const struct gl_polygon_attrib *polygon; 1116 polygon = (const struct gl_polygon_attrib *) attr->data; 1117 _mesa_CullFace(polygon->CullFaceMode); 1118 _mesa_FrontFace(polygon->FrontFace); 1119 _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); 1120 _mesa_PolygonMode(GL_BACK, polygon->BackMode); 1121 _mesa_PolygonOffset(polygon->OffsetFactor, 1122 polygon->OffsetUnits); 1123 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); 1124 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); 1125 _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); 1126 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, 1127 polygon->OffsetPoint); 1128 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, 1129 polygon->OffsetLine); 1130 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, 1131 polygon->OffsetFill); 1132 } 1133 break; 1134 case GL_POLYGON_STIPPLE_BIT: 1135 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); 1136 ctx->NewState |= _NEW_POLYGONSTIPPLE; 1137 if (ctx->Driver.PolygonStipple) 1138 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); 1139 break; 1140 case GL_SCISSOR_BIT: 1141 { 1142 const struct gl_scissor_attrib *scissor; 1143 scissor = (const struct gl_scissor_attrib *) attr->data; 1144 _mesa_Scissor(scissor->X, scissor->Y, 1145 scissor->Width, scissor->Height); 1146 _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); 1147 } 1148 break; 1149 case GL_STENCIL_BUFFER_BIT: 1150 { 1151 const struct gl_stencil_attrib *stencil; 1152 stencil = (const struct gl_stencil_attrib *) attr->data; 1153 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 1154 _mesa_ClearStencil(stencil->Clear); 1155 if (ctx->Extensions.EXT_stencil_two_side) { 1156 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, 1157 stencil->TestTwoSide); 1158 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace 1159 ? GL_BACK : GL_FRONT); 1160 } 1161 /* front state */ 1162 _mesa_StencilFuncSeparate(GL_FRONT, 1163 stencil->Function[0], 1164 stencil->Ref[0], 1165 stencil->ValueMask[0]); 1166 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); 1167 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], 1168 stencil->ZFailFunc[0], 1169 stencil->ZPassFunc[0]); 1170 /* back state */ 1171 _mesa_StencilFuncSeparate(GL_BACK, 1172 stencil->Function[1], 1173 stencil->Ref[1], 1174 stencil->ValueMask[1]); 1175 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); 1176 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], 1177 stencil->ZFailFunc[1], 1178 stencil->ZPassFunc[1]); 1179 } 1180 break; 1181 case GL_TRANSFORM_BIT: 1182 { 1183 GLuint i; 1184 const struct gl_transform_attrib *xform; 1185 xform = (const struct gl_transform_attrib *) attr->data; 1186 _mesa_MatrixMode(xform->MatrixMode); 1187 if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) 1188 _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); 1189 1190 /* restore clip planes */ 1191 for (i = 0; i < MAX_CLIP_PLANES; i++) { 1192 const GLuint mask = 1 << 1; 1193 const GLfloat *eyePlane = xform->EyeUserPlane[i]; 1194 COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); 1195 if (xform->ClipPlanesEnabled & mask) { 1196 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); 1197 } 1198 else { 1199 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); 1200 } 1201 if (ctx->Driver.ClipPlane) 1202 ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane ); 1203 } 1204 1205 /* normalize/rescale */ 1206 if (xform->Normalize != ctx->Transform.Normalize) 1207 _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize); 1208 if (xform->RescaleNormals != ctx->Transform.RescaleNormals) 1209 _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, 1210 ctx->Transform.RescaleNormals); 1211 } 1212 break; 1213 case GL_TEXTURE_BIT: 1214 /* Take care of texture object reference counters */ 1215 { 1216 struct texture_state *texstate 1217 = (struct texture_state *) attr->data; 1218 pop_texture_group(ctx, texstate); 1219 ctx->NewState |= _NEW_TEXTURE; 1220 } 1221 break; 1222 case GL_VIEWPORT_BIT: 1223 { 1224 const struct gl_viewport_attrib *vp; 1225 vp = (const struct gl_viewport_attrib *) attr->data; 1226 _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); 1227 _mesa_DepthRange(vp->Near, vp->Far); 1228 } 1229 break; 1230 case GL_MULTISAMPLE_BIT_ARB: 1231 { 1232 const struct gl_multisample_attrib *ms; 1233 ms = (const struct gl_multisample_attrib *) attr->data; 1234 _mesa_SampleCoverageARB(ms->SampleCoverageValue, 1235 ms->SampleCoverageInvert); 1236 } 1237 break; 1238 1239 default: 1240 _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); 1241 break; 1242 } 1243 1244 next = attr->next; 1245 FREE( attr->data ); 1246 FREE( attr ); 1247 attr = next; 1248 } 1249} 1250 1251 1252/** 1253 * Helper for incrementing/decrementing vertex buffer object reference 1254 * counts when pushing/popping the GL_CLIENT_VERTEX_ARRAY_BIT attribute group. 1255 */ 1256static void 1257adjust_buffer_object_ref_counts(struct gl_array_attrib *array, GLint step) 1258{ 1259 GLuint i; 1260 array->ArrayObj->Vertex.BufferObj->RefCount += step; 1261 array->ArrayObj->Normal.BufferObj->RefCount += step; 1262 array->ArrayObj->Color.BufferObj->RefCount += step; 1263 array->ArrayObj->SecondaryColor.BufferObj->RefCount += step; 1264 array->ArrayObj->FogCoord.BufferObj->RefCount += step; 1265 array->ArrayObj->Index.BufferObj->RefCount += step; 1266 array->ArrayObj->EdgeFlag.BufferObj->RefCount += step; 1267 for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) 1268 array->ArrayObj->TexCoord[i].BufferObj->RefCount += step; 1269 for (i = 0; i < VERT_ATTRIB_MAX; i++) 1270 array->ArrayObj->VertexAttrib[i].BufferObj->RefCount += step; 1271 1272 array->ArrayBufferObj->RefCount += step; 1273 array->ElementArrayBufferObj->RefCount += step; 1274} 1275 1276 1277/** 1278 * Copy gl_pixelstore_attrib from src to dst, updating buffer 1279 * object refcounts. 1280 */ 1281static void 1282copy_pixelstore(GLcontext *ctx, 1283 struct gl_pixelstore_attrib *dst, 1284 const struct gl_pixelstore_attrib *src) 1285{ 1286 dst->Alignment = src->Alignment; 1287 dst->RowLength = src->RowLength; 1288 dst->SkipPixels = src->SkipPixels; 1289 dst->SkipRows = src->SkipRows; 1290 dst->ImageHeight = src->ImageHeight; 1291 dst->SkipImages = src->SkipImages; 1292 dst->SwapBytes = src->SwapBytes; 1293 dst->LsbFirst = src->LsbFirst; 1294 dst->ClientStorage = src->ClientStorage; 1295 dst->Invert = src->Invert; 1296 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1297} 1298 1299 1300#define GL_CLIENT_PACK_BIT (1<<20) 1301#define GL_CLIENT_UNPACK_BIT (1<<21) 1302 1303 1304void GLAPIENTRY 1305_mesa_PushClientAttrib(GLbitfield mask) 1306{ 1307 struct gl_attrib_node *newnode; 1308 struct gl_attrib_node *head; 1309 1310 GET_CURRENT_CONTEXT(ctx); 1311 ASSERT_OUTSIDE_BEGIN_END(ctx); 1312 1313 if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { 1314 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); 1315 return; 1316 } 1317 1318 /* Build linked list of attribute nodes which save all attribute 1319 * groups specified by the mask. 1320 */ 1321 head = NULL; 1322 1323 if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 1324 struct gl_pixelstore_attrib *attr; 1325 /* packing attribs */ 1326 attr = CALLOC_STRUCT( gl_pixelstore_attrib ); 1327 copy_pixelstore(ctx, attr, &ctx->Pack); 1328 newnode = new_attrib_node( GL_CLIENT_PACK_BIT ); 1329 newnode->data = attr; 1330 newnode->next = head; 1331 head = newnode; 1332 /* unpacking attribs */ 1333 attr = CALLOC_STRUCT( gl_pixelstore_attrib ); 1334 copy_pixelstore(ctx, attr, &ctx->Unpack); 1335 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT ); 1336 newnode->data = attr; 1337 newnode->next = head; 1338 head = newnode; 1339 } 1340 1341 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1342 struct gl_array_attrib *attr; 1343 struct gl_array_object *obj; 1344 1345 attr = MALLOC_STRUCT( gl_array_attrib ); 1346 obj = MALLOC_STRUCT( gl_array_object ); 1347 1348#if FEATURE_ARB_vertex_buffer_object 1349 /* increment ref counts since we're copying pointers to these objects */ 1350 ctx->Array.ArrayBufferObj->RefCount++; 1351 ctx->Array.ElementArrayBufferObj->RefCount++; 1352#endif 1353 1354 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); 1355 MEMCPY( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) ); 1356 1357 attr->ArrayObj = obj; 1358 1359 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT ); 1360 newnode->data = attr; 1361 newnode->next = head; 1362 head = newnode; 1363 /* bump reference counts on buffer objects */ 1364 adjust_buffer_object_ref_counts(&ctx->Array, 1); 1365 } 1366 1367 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; 1368 ctx->ClientAttribStackDepth++; 1369} 1370 1371 1372 1373 1374void GLAPIENTRY 1375_mesa_PopClientAttrib(void) 1376{ 1377 struct gl_attrib_node *node, *next; 1378 1379 GET_CURRENT_CONTEXT(ctx); 1380 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1381 1382 if (ctx->ClientAttribStackDepth == 0) { 1383 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); 1384 return; 1385 } 1386 1387 ctx->ClientAttribStackDepth--; 1388 node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 1389 1390 while (node) { 1391 switch (node->kind) { 1392 case GL_CLIENT_PACK_BIT: 1393 { 1394 struct gl_pixelstore_attrib *store = 1395 (struct gl_pixelstore_attrib *) node->data; 1396 copy_pixelstore(ctx, &ctx->Pack, store); 1397 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); 1398 } 1399 ctx->NewState |= _NEW_PACKUNPACK; 1400 break; 1401 case GL_CLIENT_UNPACK_BIT: 1402 { 1403 struct gl_pixelstore_attrib *store = 1404 (struct gl_pixelstore_attrib *) node->data; 1405 copy_pixelstore(ctx, &ctx->Unpack, store); 1406 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); 1407 } 1408 ctx->NewState |= _NEW_PACKUNPACK; 1409 break; 1410 case GL_CLIENT_VERTEX_ARRAY_BIT: { 1411 struct gl_array_attrib * data = 1412 (struct gl_array_attrib *) node->data; 1413 1414 adjust_buffer_object_ref_counts(&ctx->Array, -1); 1415 1416 ctx->Array.ActiveTexture = data->ActiveTexture; 1417 if (data->LockCount != 0) 1418 _mesa_LockArraysEXT(data->LockFirst, data->LockCount); 1419 else if (ctx->Array.LockCount) 1420 _mesa_UnlockArraysEXT(); 1421 1422 _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name ); 1423 1424#if FEATURE_ARB_vertex_buffer_object 1425 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 1426 data->ArrayBufferObj->Name); 1427 _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 1428 data->ElementArrayBufferObj->Name); 1429#endif 1430 1431 MEMCPY( ctx->Array.ArrayObj, data->ArrayObj, 1432 sizeof( struct gl_array_object ) ); 1433 1434 FREE( data->ArrayObj ); 1435 1436 /* FIXME: Should some bits in ctx->Array->NewState also be set 1437 * FIXME: here? It seems like it should be set to inclusive-or 1438 * FIXME: of the old ArrayObj->_Enabled and the new _Enabled. 1439 */ 1440 1441 ctx->NewState |= _NEW_ARRAY; 1442 break; 1443 } 1444 default: 1445 _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); 1446 break; 1447 } 1448 1449 next = node->next; 1450 FREE( node->data ); 1451 FREE( node ); 1452 node = next; 1453 } 1454} 1455 1456 1457/** 1458 * Free any attribute state data that might be attached to the context. 1459 */ 1460void 1461_mesa_free_attrib_data(GLcontext *ctx) 1462{ 1463 while (ctx->AttribStackDepth > 0) { 1464 struct gl_attrib_node *attr, *next; 1465 1466 ctx->AttribStackDepth--; 1467 attr = ctx->AttribStack[ctx->AttribStackDepth]; 1468 1469 while (attr) { 1470 if (attr->kind == GL_TEXTURE_BIT) { 1471 struct texture_state *texstate = (struct texture_state*)attr->data; 1472 GLuint u, tgt; 1473 /* clear references to the saved texture objects */ 1474 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 1475 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 1476 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); 1477 } 1478 } 1479 } 1480 else { 1481 /* any other chunks of state that requires special handling? */ 1482 } 1483 1484 next = attr->next; 1485 _mesa_free(attr->data); 1486 _mesa_free(attr); 1487 attr = next; 1488 } 1489 } 1490} 1491 1492 1493void _mesa_init_attrib( GLcontext *ctx ) 1494{ 1495 /* Renderer and client attribute stacks */ 1496 ctx->AttribStackDepth = 0; 1497 ctx->ClientAttribStackDepth = 0; 1498} 1499