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