attrib.c revision 848b8605
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. 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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * 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 "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 "macros.h" 45#include "matrix.h" 46#include "multisample.h" 47#include "points.h" 48#include "polygon.h" 49#include "shared.h" 50#include "scissor.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 "viewport.h" 59#include "mtypes.h" 60#include "main/dispatch.h" 61#include "hash.h" 62#include <stdbool.h> 63 64 65/** 66 * glEnable()/glDisable() attribute group (GL_ENABLE_BIT). 67 */ 68struct gl_enable_attrib 69{ 70 GLboolean AlphaTest; 71 GLboolean AutoNormal; 72 GLboolean Blend; 73 GLbitfield ClipPlanes; 74 GLboolean ColorMaterial; 75 GLboolean CullFace; 76 GLboolean DepthClamp; 77 GLboolean DepthTest; 78 GLboolean Dither; 79 GLboolean Fog; 80 GLboolean Light[MAX_LIGHTS]; 81 GLboolean Lighting; 82 GLboolean LineSmooth; 83 GLboolean LineStipple; 84 GLboolean IndexLogicOp; 85 GLboolean ColorLogicOp; 86 87 GLboolean Map1Color4; 88 GLboolean Map1Index; 89 GLboolean Map1Normal; 90 GLboolean Map1TextureCoord1; 91 GLboolean Map1TextureCoord2; 92 GLboolean Map1TextureCoord3; 93 GLboolean Map1TextureCoord4; 94 GLboolean Map1Vertex3; 95 GLboolean Map1Vertex4; 96 GLboolean Map2Color4; 97 GLboolean Map2Index; 98 GLboolean Map2Normal; 99 GLboolean Map2TextureCoord1; 100 GLboolean Map2TextureCoord2; 101 GLboolean Map2TextureCoord3; 102 GLboolean Map2TextureCoord4; 103 GLboolean Map2Vertex3; 104 GLboolean Map2Vertex4; 105 106 GLboolean Normalize; 107 GLboolean PixelTexture; 108 GLboolean PointSmooth; 109 GLboolean PolygonOffsetPoint; 110 GLboolean PolygonOffsetLine; 111 GLboolean PolygonOffsetFill; 112 GLboolean PolygonSmooth; 113 GLboolean PolygonStipple; 114 GLboolean RescaleNormals; 115 GLbitfield Scissor; 116 GLboolean Stencil; 117 GLboolean StencilTwoSide; /* GL_EXT_stencil_two_side */ 118 GLboolean MultisampleEnabled; /* GL_ARB_multisample */ 119 GLboolean SampleAlphaToCoverage; /* GL_ARB_multisample */ 120 GLboolean SampleAlphaToOne; /* GL_ARB_multisample */ 121 GLboolean SampleCoverage; /* GL_ARB_multisample */ 122 GLboolean RasterPositionUnclipped; /* GL_IBM_rasterpos_clip */ 123 124 GLbitfield Texture[MAX_TEXTURE_UNITS]; 125 GLbitfield TexGen[MAX_TEXTURE_UNITS]; 126 127 /* GL_ARB_vertex_program */ 128 GLboolean VertexProgram; 129 GLboolean VertexProgramPointSize; 130 GLboolean VertexProgramTwoSide; 131 132 /* GL_ARB_fragment_program */ 133 GLboolean FragmentProgram; 134 135 /* GL_ARB_point_sprite / GL_NV_point_sprite */ 136 GLboolean PointSprite; 137 GLboolean FragmentShaderATI; 138 139 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 140 GLboolean sRGBEnabled; 141}; 142 143 144/** 145 * Node for the attribute stack. 146 */ 147struct gl_attrib_node 148{ 149 GLbitfield kind; 150 void *data; 151 struct gl_attrib_node *next; 152}; 153 154 155 156/** 157 * Special struct for saving/restoring texture state (GL_TEXTURE_BIT) 158 */ 159struct texture_state 160{ 161 struct gl_texture_attrib Texture; /**< The usual context state */ 162 163 /** to save per texture object state (wrap modes, filters, etc): */ 164 struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; 165 166 /** 167 * To save references to texture objects (so they don't get accidentally 168 * deleted while saved in the attribute stack). 169 */ 170 struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; 171 172 /* We need to keep a reference to the shared state. That's where the 173 * default texture objects are kept. We don't want that state to be 174 * freed while the attribute stack contains pointers to any default 175 * texture objects. 176 */ 177 struct gl_shared_state *SharedRef; 178}; 179 180 181/** 182 * Allocate new attribute node of given type/kind. Attach payload data. 183 * Insert it into the linked list named by 'head'. 184 */ 185static bool 186save_attrib_data(struct gl_attrib_node **head, 187 GLbitfield kind, void *payload) 188{ 189 struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node); 190 if (n) { 191 n->kind = kind; 192 n->data = payload; 193 /* insert at head */ 194 n->next = *head; 195 *head = n; 196 } 197 else { 198 /* out of memory! */ 199 return false; 200 } 201 return true; 202} 203 204 205/** 206 * Helper function for_mesa_PushAttrib for simple attributes. 207 * Allocates memory for attribute data and copies the given attribute data. 208 * \param head head of linked list to insert attribute data into 209 * \param attr_bit one of the GL_<attrib>_BIT flags 210 * \param attr_size number of bytes to allocate for attribute data 211 * \param attr_data the attribute data to copy 212 * \return true for success, false for out of memory 213 */ 214static bool 215push_attrib(struct gl_context *ctx, struct gl_attrib_node **head, 216 GLbitfield attr_bit, GLuint attr_size, const void *attr_data) 217{ 218 void *attribute; 219 220 attribute = malloc(attr_size); 221 if (attribute == NULL) { 222 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 223 return false; 224 } 225 226 if (save_attrib_data(head, attr_bit, attribute)) { 227 memcpy(attribute, attr_data, attr_size); 228 } 229 else { 230 free(attribute); 231 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 232 return false; 233 } 234 return true; 235} 236 237 238void GLAPIENTRY 239_mesa_PushAttrib(GLbitfield mask) 240{ 241 struct gl_attrib_node *head; 242 243 GET_CURRENT_CONTEXT(ctx); 244 245 if (MESA_VERBOSE & VERBOSE_API) 246 _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask); 247 248 if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { 249 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); 250 return; 251 } 252 253 /* Build linked list of attribute nodes which save all attribute */ 254 /* groups specified by the mask. */ 255 head = NULL; 256 257 if (mask & GL_ACCUM_BUFFER_BIT) { 258 if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT, 259 sizeof(struct gl_accum_attrib), 260 (void*)&ctx->Accum)) 261 goto end; 262 } 263 264 if (mask & GL_COLOR_BUFFER_BIT) { 265 GLuint i; 266 struct gl_colorbuffer_attrib *attr; 267 attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); 268 if (attr == NULL) { 269 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 270 goto end; 271 } 272 273 if (save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr)) { 274 memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib)); 275 /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */ 276 for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++) 277 attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i]; 278 } 279 else { 280 free(attr); 281 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 282 goto end; 283 } 284 } 285 286 if (mask & GL_CURRENT_BIT) { 287 FLUSH_CURRENT(ctx, 0); 288 if (!push_attrib(ctx, &head, GL_CURRENT_BIT, 289 sizeof(struct gl_current_attrib), 290 (void*)&ctx->Current)) 291 goto end; 292 } 293 294 if (mask & GL_DEPTH_BUFFER_BIT) { 295 if (!push_attrib(ctx, &head, GL_DEPTH_BUFFER_BIT, 296 sizeof(struct gl_depthbuffer_attrib), 297 (void*)&ctx->Depth)) 298 goto end; 299 } 300 301 if (mask & GL_ENABLE_BIT) { 302 struct gl_enable_attrib *attr; 303 GLuint i; 304 attr = MALLOC_STRUCT( gl_enable_attrib ); 305 if (attr == NULL) { 306 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 307 goto end; 308 } 309 310 /* Copy enable flags from all other attributes into the enable struct. */ 311 attr->AlphaTest = ctx->Color.AlphaEnabled; 312 attr->AutoNormal = ctx->Eval.AutoNormal; 313 attr->Blend = ctx->Color.BlendEnabled; 314 attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; 315 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 316 attr->CullFace = ctx->Polygon.CullFlag; 317 attr->DepthClamp = ctx->Transform.DepthClamp; 318 attr->DepthTest = ctx->Depth.Test; 319 attr->Dither = ctx->Color.DitherFlag; 320 attr->Fog = ctx->Fog.Enabled; 321 for (i = 0; i < ctx->Const.MaxLights; i++) { 322 attr->Light[i] = ctx->Light.Light[i].Enabled; 323 } 324 attr->Lighting = ctx->Light.Enabled; 325 attr->LineSmooth = ctx->Line.SmoothFlag; 326 attr->LineStipple = ctx->Line.StippleFlag; 327 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 328 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 329 attr->Map1Color4 = ctx->Eval.Map1Color4; 330 attr->Map1Index = ctx->Eval.Map1Index; 331 attr->Map1Normal = ctx->Eval.Map1Normal; 332 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 333 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 334 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 335 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 336 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 337 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 338 attr->Map2Color4 = ctx->Eval.Map2Color4; 339 attr->Map2Index = ctx->Eval.Map2Index; 340 attr->Map2Normal = ctx->Eval.Map2Normal; 341 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 342 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 343 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 344 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 345 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 346 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 347 attr->Normalize = ctx->Transform.Normalize; 348 attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped; 349 attr->PointSmooth = ctx->Point.SmoothFlag; 350 attr->PointSprite = ctx->Point.PointSprite; 351 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 352 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 353 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 354 attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 355 attr->PolygonStipple = ctx->Polygon.StippleFlag; 356 attr->RescaleNormals = ctx->Transform.RescaleNormals; 357 attr->Scissor = ctx->Scissor.EnableFlags; 358 attr->Stencil = ctx->Stencil.Enabled; 359 attr->StencilTwoSide = ctx->Stencil.TestTwoSide; 360 attr->MultisampleEnabled = ctx->Multisample.Enabled; 361 attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage; 362 attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; 363 attr->SampleCoverage = ctx->Multisample.SampleCoverage; 364 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 365 attr->Texture[i] = ctx->Texture.Unit[i].Enabled; 366 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; 367 } 368 /* GL_ARB_vertex_program */ 369 attr->VertexProgram = ctx->VertexProgram.Enabled; 370 attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled; 371 attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled; 372 373 /* GL_ARB_fragment_program */ 374 attr->FragmentProgram = ctx->FragmentProgram.Enabled; 375 376 if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) { 377 free(attr); 378 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 379 goto end; 380 } 381 382 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 383 attr->sRGBEnabled = ctx->Color.sRGBEnabled; 384 } 385 386 if (mask & GL_EVAL_BIT) { 387 if (!push_attrib(ctx, &head, GL_EVAL_BIT, 388 sizeof(struct gl_eval_attrib), 389 (void*)&ctx->Eval)) 390 goto end; 391 } 392 393 if (mask & GL_FOG_BIT) { 394 if (!push_attrib(ctx, &head, GL_FOG_BIT, 395 sizeof(struct gl_fog_attrib), 396 (void*)&ctx->Fog)) 397 goto end; 398 } 399 400 if (mask & GL_HINT_BIT) { 401 if (!push_attrib(ctx, &head, GL_HINT_BIT, 402 sizeof(struct gl_hint_attrib), 403 (void*)&ctx->Hint)) 404 goto end; 405 } 406 407 if (mask & GL_LIGHTING_BIT) { 408 FLUSH_CURRENT(ctx, 0); /* flush material changes */ 409 if (!push_attrib(ctx, &head, GL_LIGHTING_BIT, 410 sizeof(struct gl_light_attrib), 411 (void*)&ctx->Light)) 412 goto end; 413 } 414 415 if (mask & GL_LINE_BIT) { 416 if (!push_attrib(ctx, &head, GL_LINE_BIT, 417 sizeof(struct gl_line_attrib), 418 (void*)&ctx->Line)) 419 goto end; 420 } 421 422 if (mask & GL_LIST_BIT) { 423 if (!push_attrib(ctx, &head, GL_LIST_BIT, 424 sizeof(struct gl_list_attrib), 425 (void*)&ctx->List)) 426 goto end; 427 } 428 429 if (mask & GL_PIXEL_MODE_BIT) { 430 struct gl_pixel_attrib *attr; 431 attr = MALLOC_STRUCT( gl_pixel_attrib ); 432 if (attr == NULL) { 433 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 434 goto end; 435 } 436 437 if (save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr)) { 438 memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib)); 439 /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */ 440 attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer; 441 } 442 else { 443 free(attr); 444 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib"); 445 goto end; 446 } 447 } 448 449 if (mask & GL_POINT_BIT) { 450 if (!push_attrib(ctx, &head, GL_POINT_BIT, 451 sizeof(struct gl_point_attrib), 452 (void*)&ctx->Point)) 453 goto end; 454 } 455 456 if (mask & GL_POLYGON_BIT) { 457 if (!push_attrib(ctx, &head, GL_POLYGON_BIT, 458 sizeof(struct gl_polygon_attrib), 459 (void*)&ctx->Polygon)) 460 goto end; 461 } 462 463 if (mask & GL_POLYGON_STIPPLE_BIT) { 464 if (!push_attrib(ctx, &head, GL_POLYGON_STIPPLE_BIT, 465 sizeof(ctx->PolygonStipple), 466 (void*)&ctx->PolygonStipple)) 467 goto end; 468 } 469 470 if (mask & GL_SCISSOR_BIT) { 471 if (!push_attrib(ctx, &head, GL_SCISSOR_BIT, 472 sizeof(struct gl_scissor_attrib), 473 (void*)&ctx->Scissor)) 474 goto end; 475 } 476 477 if (mask & GL_STENCIL_BUFFER_BIT) { 478 if (!push_attrib(ctx, &head, GL_STENCIL_BUFFER_BIT, 479 sizeof(struct gl_stencil_attrib), 480 (void*)&ctx->Stencil)) 481 goto end; 482 } 483 484 if (mask & GL_TEXTURE_BIT) { 485 struct texture_state *texstate = CALLOC_STRUCT(texture_state); 486 GLuint u, tex; 487 488 if (!texstate) { 489 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); 490 goto end; 491 } 492 493 if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) { 494 free(texstate); 495 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); 496 goto end; 497 } 498 499 _mesa_lock_context_textures(ctx); 500 501 /* copy/save the bulk of texture state here */ 502 memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture)); 503 504 /* Save references to the currently bound texture objects so they don't 505 * accidentally get deleted while referenced in the attribute stack. 506 */ 507 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 508 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 509 _mesa_reference_texobj(&texstate->SavedTexRef[u][tex], 510 ctx->Texture.Unit[u].CurrentTex[tex]); 511 } 512 } 513 514 /* copy state/contents of the currently bound texture objects */ 515 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 516 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 517 _mesa_copy_texture_object(&texstate->SavedObj[u][tex], 518 ctx->Texture.Unit[u].CurrentTex[tex]); 519 } 520 } 521 522 _mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared); 523 524 _mesa_unlock_context_textures(ctx); 525 } 526 527 if (mask & GL_TRANSFORM_BIT) { 528 if (!push_attrib(ctx, &head, GL_TRANSFORM_BIT, 529 sizeof(struct gl_transform_attrib), 530 (void*)&ctx->Transform)) 531 goto end; 532 } 533 534 if (mask & GL_VIEWPORT_BIT) { 535 if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT, 536 sizeof(struct gl_viewport_attrib) 537 * ctx->Const.MaxViewports, 538 (void*)&ctx->ViewportArray)) 539 goto end; 540 } 541 542 /* GL_ARB_multisample */ 543 if (mask & GL_MULTISAMPLE_BIT_ARB) { 544 if (!push_attrib(ctx, &head, GL_MULTISAMPLE_BIT_ARB, 545 sizeof(struct gl_multisample_attrib), 546 (void*)&ctx->Multisample)) 547 goto end; 548 } 549 550end: 551 if (head != NULL) { 552 ctx->AttribStack[ctx->AttribStackDepth] = head; 553 ctx->AttribStackDepth++; 554 } 555} 556 557 558 559static void 560pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) 561{ 562 const GLuint curTexUnitSave = ctx->Texture.CurrentUnit; 563 GLuint i; 564 565#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ 566 if ((VALUE) != (NEWVALUE)) { \ 567 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ 568 } 569 570 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 571 if (ctx->Color.BlendEnabled != enable->Blend) { 572 if (ctx->Extensions.EXT_draw_buffers2) { 573 GLuint i; 574 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 575 _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1); 576 } 577 } 578 else { 579 _mesa_set_enable(ctx, GL_BLEND, (enable->Blend & 1)); 580 } 581 } 582 583 for (i=0;i<ctx->Const.MaxClipPlanes;i++) { 584 const GLuint mask = 1 << i; 585 if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask)) 586 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), 587 !!(enable->ClipPlanes & mask)); 588 } 589 590 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 591 GL_COLOR_MATERIAL); 592 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 593 TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp, 594 GL_DEPTH_CLAMP); 595 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 596 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 597 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 598 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 599 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 600 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 601 GL_LINE_STIPPLE); 602 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 603 GL_INDEX_LOGIC_OP); 604 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 605 GL_COLOR_LOGIC_OP); 606 607 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 608 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 609 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 610 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 611 GL_MAP1_TEXTURE_COORD_1); 612 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 613 GL_MAP1_TEXTURE_COORD_2); 614 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 615 GL_MAP1_TEXTURE_COORD_3); 616 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 617 GL_MAP1_TEXTURE_COORD_4); 618 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 619 GL_MAP1_VERTEX_3); 620 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 621 GL_MAP1_VERTEX_4); 622 623 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 624 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 625 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 626 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 627 GL_MAP2_TEXTURE_COORD_1); 628 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 629 GL_MAP2_TEXTURE_COORD_2); 630 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 631 GL_MAP2_TEXTURE_COORD_3); 632 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 633 GL_MAP2_TEXTURE_COORD_4); 634 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 635 GL_MAP2_VERTEX_3); 636 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 637 GL_MAP2_VERTEX_4); 638 639 TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL); 640 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 641 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 642 GL_RESCALE_NORMAL_EXT); 643 TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped, 644 enable->RasterPositionUnclipped, 645 GL_RASTER_POSITION_UNCLIPPED_IBM); 646 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 647 GL_POINT_SMOOTH); 648 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) { 649 TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, 650 GL_POINT_SPRITE_NV); 651 } 652 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 653 GL_POLYGON_OFFSET_POINT); 654 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 655 GL_POLYGON_OFFSET_LINE); 656 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 657 GL_POLYGON_OFFSET_FILL); 658 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 659 GL_POLYGON_SMOOTH); 660 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 661 GL_POLYGON_STIPPLE); 662 if (ctx->Scissor.EnableFlags != enable->Scissor) { 663 unsigned i; 664 665 for (i = 0; i < ctx->Const.MaxViewports; i++) { 666 _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, (enable->Scissor >> i) & 1); 667 } 668 } 669 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 670 if (ctx->Extensions.EXT_stencil_two_side) { 671 TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT); 672 } 673 TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, 674 GL_MULTISAMPLE_ARB); 675 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 676 enable->SampleAlphaToCoverage, 677 GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 678 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 679 enable->SampleAlphaToOne, 680 GL_SAMPLE_ALPHA_TO_ONE_ARB); 681 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 682 enable->SampleCoverage, 683 GL_SAMPLE_COVERAGE_ARB); 684 /* GL_ARB_vertex_program */ 685 TEST_AND_UPDATE(ctx->VertexProgram.Enabled, 686 enable->VertexProgram, 687 GL_VERTEX_PROGRAM_ARB); 688 TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled, 689 enable->VertexProgramPointSize, 690 GL_VERTEX_PROGRAM_POINT_SIZE_ARB); 691 TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled, 692 enable->VertexProgramTwoSide, 693 GL_VERTEX_PROGRAM_TWO_SIDE_ARB); 694 695 /* GL_ARB_fragment_program */ 696 TEST_AND_UPDATE(ctx->FragmentProgram.Enabled, 697 enable->FragmentProgram, 698 GL_FRAGMENT_PROGRAM_ARB); 699 700 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 701 TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled, 702 GL_FRAMEBUFFER_SRGB); 703 704 /* texture unit enables */ 705 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 706 const GLbitfield enabled = enable->Texture[i]; 707 const GLbitfield genEnabled = enable->TexGen[i]; 708 709 if (ctx->Texture.Unit[i].Enabled != enabled) { 710 _mesa_ActiveTexture(GL_TEXTURE0 + i); 711 712 _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(enabled & TEXTURE_1D_BIT)); 713 _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(enabled & TEXTURE_2D_BIT)); 714 _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(enabled & TEXTURE_3D_BIT)); 715 if (ctx->Extensions.NV_texture_rectangle) { 716 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_ARB, 717 !!(enabled & TEXTURE_RECT_BIT)); 718 } 719 if (ctx->Extensions.ARB_texture_cube_map) { 720 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, 721 !!(enabled & TEXTURE_CUBE_BIT)); 722 } 723 } 724 725 if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) { 726 _mesa_ActiveTexture(GL_TEXTURE0 + i); 727 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(genEnabled & S_BIT)); 728 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(genEnabled & T_BIT)); 729 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(genEnabled & R_BIT)); 730 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(genEnabled & Q_BIT)); 731 } 732 } 733 734 _mesa_ActiveTexture(GL_TEXTURE0 + curTexUnitSave); 735} 736 737 738/** 739 * Pop/restore texture attribute/group state. 740 */ 741static void 742pop_texture_group(struct gl_context *ctx, struct texture_state *texstate) 743{ 744 GLuint u; 745 746 _mesa_lock_context_textures(ctx); 747 748 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 749 const struct gl_texture_unit *unit = &texstate->Texture.Unit[u]; 750 GLuint tgt; 751 752 _mesa_ActiveTexture(GL_TEXTURE0_ARB + u); 753 _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(unit->Enabled & TEXTURE_1D_BIT)); 754 _mesa_set_enable(ctx, GL_TEXTURE_2D, !!(unit->Enabled & TEXTURE_2D_BIT)); 755 _mesa_set_enable(ctx, GL_TEXTURE_3D, !!(unit->Enabled & TEXTURE_3D_BIT)); 756 if (ctx->Extensions.ARB_texture_cube_map) { 757 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB, 758 !!(unit->Enabled & TEXTURE_CUBE_BIT)); 759 } 760 if (ctx->Extensions.NV_texture_rectangle) { 761 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV, 762 !!(unit->Enabled & TEXTURE_RECT_BIT)); 763 } 764 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); 765 _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); 766 _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode); 767 _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenT.Mode); 768 _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenR.Mode); 769 _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenQ.Mode); 770 _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->GenS.ObjectPlane); 771 _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->GenT.ObjectPlane); 772 _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->GenR.ObjectPlane); 773 _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->GenQ.ObjectPlane); 774 /* Eye plane done differently to avoid re-transformation */ 775 { 776 struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u]; 777 COPY_4FV(destUnit->GenS.EyePlane, unit->GenS.EyePlane); 778 COPY_4FV(destUnit->GenT.EyePlane, unit->GenT.EyePlane); 779 COPY_4FV(destUnit->GenR.EyePlane, unit->GenR.EyePlane); 780 COPY_4FV(destUnit->GenQ.EyePlane, unit->GenQ.EyePlane); 781 if (ctx->Driver.TexGen) { 782 ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->GenS.EyePlane); 783 ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->GenT.EyePlane); 784 ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->GenR.EyePlane); 785 ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->GenQ.EyePlane); 786 } 787 } 788 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(unit->TexGenEnabled & S_BIT)); 789 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(unit->TexGenEnabled & T_BIT)); 790 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(unit->TexGenEnabled & R_BIT)); 791 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(unit->TexGenEnabled & Q_BIT)); 792 _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 793 unit->LodBias); 794 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, 795 unit->Combine.ModeRGB); 796 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, 797 unit->Combine.ModeA); 798 { 799 const GLuint n = ctx->Extensions.NV_texture_env_combine4 ? 4 : 3; 800 GLuint i; 801 for (i = 0; i < n; i++) { 802 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB + i, 803 unit->Combine.SourceRGB[i]); 804 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA + i, 805 unit->Combine.SourceA[i]); 806 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB + i, 807 unit->Combine.OperandRGB[i]); 808 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA + i, 809 unit->Combine.OperandA[i]); 810 } 811 } 812 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 813 1 << unit->Combine.ScaleShiftRGB); 814 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 815 1 << unit->Combine.ScaleShiftA); 816 817 /* Restore texture object state for each target */ 818 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 819 const struct gl_texture_object *obj = NULL; 820 const struct gl_sampler_object *samp; 821 GLenum target; 822 823 obj = &texstate->SavedObj[u][tgt]; 824 825 /* don't restore state for unsupported targets to prevent 826 * raising GL errors. 827 */ 828 if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB && 829 !ctx->Extensions.ARB_texture_cube_map) { 830 continue; 831 } 832 else if (obj->Target == GL_TEXTURE_RECTANGLE_NV && 833 !ctx->Extensions.NV_texture_rectangle) { 834 continue; 835 } 836 else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT || 837 obj->Target == GL_TEXTURE_2D_ARRAY_EXT) && 838 !ctx->Extensions.EXT_texture_array) { 839 continue; 840 } 841 else if (obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY && 842 !ctx->Extensions.ARB_texture_cube_map_array) { 843 continue; 844 } else if (obj->Target == GL_TEXTURE_BUFFER) 845 continue; 846 else if (obj->Target == GL_TEXTURE_EXTERNAL_OES) 847 continue; 848 else if (obj->Target == GL_TEXTURE_2D_MULTISAMPLE || 849 obj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) 850 continue; 851 852 target = obj->Target; 853 854 _mesa_BindTexture(target, obj->Name); 855 856 samp = &obj->Sampler; 857 858 _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, samp->BorderColor.f); 859 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, samp->WrapS); 860 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, samp->WrapT); 861 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, samp->WrapR); 862 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, samp->MinFilter); 863 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, samp->MagFilter); 864 _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, samp->MinLod); 865 _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, samp->MaxLod); 866 _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, samp->LodBias); 867 _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); 868 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel); 869 if (target != GL_TEXTURE_RECTANGLE_ARB) 870 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel); 871 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 872 _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 873 samp->MaxAnisotropy); 874 } 875 if (ctx->Extensions.ARB_shadow) { 876 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_MODE, 877 samp->CompareMode); 878 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_FUNC, 879 samp->CompareFunc); 880 } 881 if (ctx->Extensions.ARB_depth_texture) 882 _mesa_TexParameteri(target, GL_DEPTH_TEXTURE_MODE, obj->DepthMode); 883 } 884 885 /* remove saved references to the texture objects */ 886 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 887 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); 888 } 889 } 890 891 _mesa_ActiveTexture(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit); 892 893 _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL); 894 895 _mesa_unlock_context_textures(ctx); 896} 897 898 899/* 900 * This function is kind of long just because we have to call a lot 901 * of device driver functions to update device driver state. 902 * 903 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions 904 * in order to restore GL state. This isn't terribly efficient but it 905 * ensures that dirty flags and any derived state gets updated correctly. 906 * We could at least check if the value to restore equals the current value 907 * and then skip the Mesa call. 908 */ 909void GLAPIENTRY 910_mesa_PopAttrib(void) 911{ 912 struct gl_attrib_node *attr, *next; 913 GET_CURRENT_CONTEXT(ctx); 914 FLUSH_VERTICES(ctx, 0); 915 916 if (ctx->AttribStackDepth == 0) { 917 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); 918 return; 919 } 920 921 ctx->AttribStackDepth--; 922 attr = ctx->AttribStack[ctx->AttribStackDepth]; 923 924 while (attr) { 925 926 if (MESA_VERBOSE & VERBOSE_API) { 927 _mesa_debug(ctx, "glPopAttrib %s\n", 928 _mesa_lookup_enum_by_nr(attr->kind)); 929 } 930 931 switch (attr->kind) { 932 case GL_ACCUM_BUFFER_BIT: 933 { 934 const struct gl_accum_attrib *accum; 935 accum = (const struct gl_accum_attrib *) attr->data; 936 _mesa_ClearAccum(accum->ClearColor[0], 937 accum->ClearColor[1], 938 accum->ClearColor[2], 939 accum->ClearColor[3]); 940 } 941 break; 942 case GL_COLOR_BUFFER_BIT: 943 { 944 const struct gl_colorbuffer_attrib *color; 945 946 color = (const struct gl_colorbuffer_attrib *) attr->data; 947 _mesa_ClearIndex((GLfloat) color->ClearIndex); 948 _mesa_ClearColor(color->ClearColor.f[0], 949 color->ClearColor.f[1], 950 color->ClearColor.f[2], 951 color->ClearColor.f[3]); 952 _mesa_IndexMask(color->IndexMask); 953 if (!ctx->Extensions.EXT_draw_buffers2) { 954 _mesa_ColorMask((GLboolean) (color->ColorMask[0][0] != 0), 955 (GLboolean) (color->ColorMask[0][1] != 0), 956 (GLboolean) (color->ColorMask[0][2] != 0), 957 (GLboolean) (color->ColorMask[0][3] != 0)); 958 } 959 else { 960 GLuint i; 961 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 962 _mesa_ColorMaski(i, 963 (GLboolean) (color->ColorMask[i][0] != 0), 964 (GLboolean) (color->ColorMask[i][1] != 0), 965 (GLboolean) (color->ColorMask[i][2] != 0), 966 (GLboolean) (color->ColorMask[i][3] != 0)); 967 } 968 } 969 { 970 /* Need to determine if more than one color output is 971 * specified. If so, call glDrawBuffersARB, else call 972 * glDrawBuffer(). This is a subtle, but essential point 973 * since GL_FRONT (for example) is illegal for the former 974 * function, but legal for the later. 975 */ 976 GLboolean multipleBuffers = GL_FALSE; 977 GLuint i; 978 979 for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { 980 if (color->DrawBuffer[i] != GL_NONE) { 981 multipleBuffers = GL_TRUE; 982 break; 983 } 984 } 985 /* Call the API_level functions, not _mesa_drawbuffers() 986 * since we need to do error checking on the pop'd 987 * GL_DRAW_BUFFER. 988 * Ex: if GL_FRONT were pushed, but we're popping with a 989 * user FBO bound, GL_FRONT will be illegal and we'll need 990 * to record that error. Per OpenGL ARB decision. 991 */ 992 if (multipleBuffers) 993 _mesa_DrawBuffers(ctx->Const.MaxDrawBuffers, 994 color->DrawBuffer); 995 else 996 _mesa_DrawBuffer(color->DrawBuffer[0]); 997 } 998 _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); 999 _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRefUnclamped); 1000 if (ctx->Color.BlendEnabled != color->BlendEnabled) { 1001 if (ctx->Extensions.EXT_draw_buffers2) { 1002 GLuint i; 1003 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 1004 _mesa_set_enablei(ctx, GL_BLEND, i, 1005 (color->BlendEnabled >> i) & 1); 1006 } 1007 } 1008 else { 1009 _mesa_set_enable(ctx, GL_BLEND, (color->BlendEnabled & 1)); 1010 } 1011 } 1012 if (ctx->Color._BlendFuncPerBuffer || 1013 ctx->Color._BlendEquationPerBuffer) { 1014 /* set blend per buffer */ 1015 GLuint buf; 1016 for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { 1017 _mesa_BlendFuncSeparateiARB(buf, color->Blend[buf].SrcRGB, 1018 color->Blend[buf].DstRGB, 1019 color->Blend[buf].SrcA, 1020 color->Blend[buf].DstA); 1021 _mesa_BlendEquationSeparateiARB(buf, 1022 color->Blend[buf].EquationRGB, 1023 color->Blend[buf].EquationA); 1024 } 1025 } 1026 else { 1027 /* set same blend modes for all buffers */ 1028 _mesa_BlendFuncSeparate(color->Blend[0].SrcRGB, 1029 color->Blend[0].DstRGB, 1030 color->Blend[0].SrcA, 1031 color->Blend[0].DstA); 1032 /* This special case is because glBlendEquationSeparateEXT 1033 * cannot take GL_LOGIC_OP as a parameter. 1034 */ 1035 if (color->Blend[0].EquationRGB == 1036 color->Blend[0].EquationA) { 1037 _mesa_BlendEquation(color->Blend[0].EquationRGB); 1038 } 1039 else { 1040 _mesa_BlendEquationSeparate( 1041 color->Blend[0].EquationRGB, 1042 color->Blend[0].EquationA); 1043 } 1044 } 1045 _mesa_BlendColor(color->BlendColorUnclamped[0], 1046 color->BlendColorUnclamped[1], 1047 color->BlendColorUnclamped[2], 1048 color->BlendColorUnclamped[3]); 1049 _mesa_LogicOp(color->LogicOp); 1050 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, 1051 color->ColorLogicOpEnabled); 1052 _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, 1053 color->IndexLogicOpEnabled); 1054 _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); 1055 if (ctx->Extensions.ARB_color_buffer_float) 1056 _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, 1057 color->ClampFragmentColor); 1058 _mesa_ClampColor(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor); 1059 1060 /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ 1061 if (ctx->Extensions.EXT_framebuffer_sRGB) 1062 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB, color->sRGBEnabled); 1063 } 1064 break; 1065 case GL_CURRENT_BIT: 1066 FLUSH_CURRENT( ctx, 0 ); 1067 memcpy( &ctx->Current, attr->data, 1068 sizeof(struct gl_current_attrib) ); 1069 break; 1070 case GL_DEPTH_BUFFER_BIT: 1071 { 1072 const struct gl_depthbuffer_attrib *depth; 1073 depth = (const struct gl_depthbuffer_attrib *) attr->data; 1074 _mesa_DepthFunc(depth->Func); 1075 _mesa_ClearDepth(depth->Clear); 1076 _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); 1077 _mesa_DepthMask(depth->Mask); 1078 } 1079 break; 1080 case GL_ENABLE_BIT: 1081 { 1082 const struct gl_enable_attrib *enable; 1083 enable = (const struct gl_enable_attrib *) attr->data; 1084 pop_enable_group(ctx, enable); 1085 ctx->NewState |= _NEW_ALL; 1086 } 1087 break; 1088 case GL_EVAL_BIT: 1089 memcpy( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); 1090 ctx->NewState |= _NEW_EVAL; 1091 break; 1092 case GL_FOG_BIT: 1093 { 1094 const struct gl_fog_attrib *fog; 1095 fog = (const struct gl_fog_attrib *) attr->data; 1096 _mesa_set_enable(ctx, GL_FOG, fog->Enabled); 1097 _mesa_Fogfv(GL_FOG_COLOR, fog->Color); 1098 _mesa_Fogf(GL_FOG_DENSITY, fog->Density); 1099 _mesa_Fogf(GL_FOG_START, fog->Start); 1100 _mesa_Fogf(GL_FOG_END, fog->End); 1101 _mesa_Fogf(GL_FOG_INDEX, fog->Index); 1102 _mesa_Fogi(GL_FOG_MODE, fog->Mode); 1103 } 1104 break; 1105 case GL_HINT_BIT: 1106 { 1107 const struct gl_hint_attrib *hint; 1108 hint = (const struct gl_hint_attrib *) attr->data; 1109 _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, 1110 hint->PerspectiveCorrection ); 1111 _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); 1112 _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); 1113 _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); 1114 _mesa_Hint(GL_FOG_HINT, hint->Fog); 1115 _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, 1116 hint->TextureCompression); 1117 } 1118 break; 1119 case GL_LIGHTING_BIT: 1120 { 1121 GLuint i; 1122 const struct gl_light_attrib *light; 1123 light = (const struct gl_light_attrib *) attr->data; 1124 /* lighting enable */ 1125 _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); 1126 /* per-light state */ 1127 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) 1128 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 1129 1130 for (i = 0; i < ctx->Const.MaxLights; i++) { 1131 const struct gl_light *l = &light->Light[i]; 1132 _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled); 1133 _mesa_light(ctx, i, GL_AMBIENT, l->Ambient); 1134 _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse); 1135 _mesa_light(ctx, i, GL_SPECULAR, l->Specular ); 1136 _mesa_light(ctx, i, GL_POSITION, l->EyePosition); 1137 _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->SpotDirection); 1138 { 1139 GLfloat p[4] = { 0 }; 1140 p[0] = l->SpotExponent; 1141 _mesa_light(ctx, i, GL_SPOT_EXPONENT, p); 1142 } 1143 { 1144 GLfloat p[4] = { 0 }; 1145 p[0] = l->SpotCutoff; 1146 _mesa_light(ctx, i, GL_SPOT_CUTOFF, p); 1147 } 1148 { 1149 GLfloat p[4] = { 0 }; 1150 p[0] = l->ConstantAttenuation; 1151 _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, p); 1152 } 1153 { 1154 GLfloat p[4] = { 0 }; 1155 p[0] = l->LinearAttenuation; 1156 _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, p); 1157 } 1158 { 1159 GLfloat p[4] = { 0 }; 1160 p[0] = l->QuadraticAttenuation; 1161 _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, p); 1162 } 1163 } 1164 /* light model */ 1165 _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, 1166 light->Model.Ambient); 1167 _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1168 (GLfloat) light->Model.LocalViewer); 1169 _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1170 (GLfloat) light->Model.TwoSide); 1171 _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, 1172 (GLfloat) light->Model.ColorControl); 1173 /* shade model */ 1174 _mesa_ShadeModel(light->ShadeModel); 1175 /* color material */ 1176 _mesa_ColorMaterial(light->ColorMaterialFace, 1177 light->ColorMaterialMode); 1178 _mesa_set_enable(ctx, GL_COLOR_MATERIAL, 1179 light->ColorMaterialEnabled); 1180 /* materials */ 1181 memcpy(&ctx->Light.Material, &light->Material, 1182 sizeof(struct gl_material)); 1183 if (ctx->Extensions.ARB_color_buffer_float) { 1184 _mesa_ClampColor(GL_CLAMP_VERTEX_COLOR_ARB, 1185 light->ClampVertexColor); 1186 } 1187 } 1188 break; 1189 case GL_LINE_BIT: 1190 { 1191 const struct gl_line_attrib *line; 1192 line = (const struct gl_line_attrib *) attr->data; 1193 _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); 1194 _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); 1195 _mesa_LineStipple(line->StippleFactor, line->StipplePattern); 1196 _mesa_LineWidth(line->Width); 1197 } 1198 break; 1199 case GL_LIST_BIT: 1200 memcpy( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); 1201 break; 1202 case GL_PIXEL_MODE_BIT: 1203 memcpy( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); 1204 /* XXX what other pixel state needs to be set by function calls? */ 1205 _mesa_ReadBuffer(ctx->Pixel.ReadBuffer); 1206 ctx->NewState |= _NEW_PIXEL; 1207 break; 1208 case GL_POINT_BIT: 1209 { 1210 const struct gl_point_attrib *point; 1211 point = (const struct gl_point_attrib *) attr->data; 1212 _mesa_PointSize(point->Size); 1213 _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); 1214 if (ctx->Extensions.EXT_point_parameters) { 1215 _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, 1216 point->Params); 1217 _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT, 1218 point->MinSize); 1219 _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT, 1220 point->MaxSize); 1221 _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 1222 point->Threshold); 1223 } 1224 if (ctx->Extensions.NV_point_sprite 1225 || ctx->Extensions.ARB_point_sprite) { 1226 GLuint u; 1227 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 1228 _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, 1229 (GLint) point->CoordReplace[u]); 1230 } 1231 _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite); 1232 if (ctx->Extensions.NV_point_sprite) 1233 _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV, 1234 ctx->Point.SpriteRMode); 1235 1236 if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20) 1237 || ctx->API == API_OPENGL_CORE) 1238 _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, 1239 (GLfloat)ctx->Point.SpriteOrigin); 1240 } 1241 } 1242 break; 1243 case GL_POLYGON_BIT: 1244 { 1245 const struct gl_polygon_attrib *polygon; 1246 polygon = (const struct gl_polygon_attrib *) attr->data; 1247 _mesa_CullFace(polygon->CullFaceMode); 1248 _mesa_FrontFace(polygon->FrontFace); 1249 _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); 1250 _mesa_PolygonMode(GL_BACK, polygon->BackMode); 1251 _mesa_PolygonOffset(polygon->OffsetFactor, 1252 polygon->OffsetUnits); 1253 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); 1254 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); 1255 _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); 1256 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, 1257 polygon->OffsetPoint); 1258 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, 1259 polygon->OffsetLine); 1260 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, 1261 polygon->OffsetFill); 1262 } 1263 break; 1264 case GL_POLYGON_STIPPLE_BIT: 1265 memcpy( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); 1266 ctx->NewState |= _NEW_POLYGONSTIPPLE; 1267 if (ctx->Driver.PolygonStipple) 1268 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); 1269 break; 1270 case GL_SCISSOR_BIT: 1271 { 1272 unsigned i; 1273 const struct gl_scissor_attrib *scissor; 1274 scissor = (const struct gl_scissor_attrib *) attr->data; 1275 1276 for (i = 0; i < ctx->Const.MaxViewports; i++) { 1277 _mesa_set_scissor(ctx, i, 1278 scissor->ScissorArray[i].X, 1279 scissor->ScissorArray[i].Y, 1280 scissor->ScissorArray[i].Width, 1281 scissor->ScissorArray[i].Height); 1282 _mesa_set_enablei(ctx, GL_SCISSOR_TEST, i, 1283 (scissor->EnableFlags >> i) & 1); 1284 } 1285 } 1286 break; 1287 case GL_STENCIL_BUFFER_BIT: 1288 { 1289 const struct gl_stencil_attrib *stencil; 1290 stencil = (const struct gl_stencil_attrib *) attr->data; 1291 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 1292 _mesa_ClearStencil(stencil->Clear); 1293 if (ctx->Extensions.EXT_stencil_two_side) { 1294 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, 1295 stencil->TestTwoSide); 1296 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace 1297 ? GL_BACK : GL_FRONT); 1298 } 1299 /* front state */ 1300 _mesa_StencilFuncSeparate(GL_FRONT, 1301 stencil->Function[0], 1302 stencil->Ref[0], 1303 stencil->ValueMask[0]); 1304 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); 1305 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], 1306 stencil->ZFailFunc[0], 1307 stencil->ZPassFunc[0]); 1308 /* back state */ 1309 _mesa_StencilFuncSeparate(GL_BACK, 1310 stencil->Function[1], 1311 stencil->Ref[1], 1312 stencil->ValueMask[1]); 1313 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); 1314 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], 1315 stencil->ZFailFunc[1], 1316 stencil->ZPassFunc[1]); 1317 } 1318 break; 1319 case GL_TRANSFORM_BIT: 1320 { 1321 GLuint i; 1322 const struct gl_transform_attrib *xform; 1323 xform = (const struct gl_transform_attrib *) attr->data; 1324 _mesa_MatrixMode(xform->MatrixMode); 1325 if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) 1326 _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); 1327 1328 /* restore clip planes */ 1329 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 1330 const GLuint mask = 1 << i; 1331 const GLfloat *eyePlane = xform->EyeUserPlane[i]; 1332 COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); 1333 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, 1334 !!(xform->ClipPlanesEnabled & mask)); 1335 if (ctx->Driver.ClipPlane) 1336 ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane ); 1337 } 1338 1339 /* normalize/rescale */ 1340 if (xform->Normalize != ctx->Transform.Normalize) 1341 _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize); 1342 if (xform->RescaleNormals != ctx->Transform.RescaleNormals) 1343 _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, 1344 ctx->Transform.RescaleNormals); 1345 if (xform->DepthClamp != ctx->Transform.DepthClamp) 1346 _mesa_set_enable(ctx, GL_DEPTH_CLAMP, 1347 ctx->Transform.DepthClamp); 1348 } 1349 break; 1350 case GL_TEXTURE_BIT: 1351 { 1352 struct texture_state *texstate 1353 = (struct texture_state *) attr->data; 1354 pop_texture_group(ctx, texstate); 1355 ctx->NewState |= _NEW_TEXTURE; 1356 } 1357 break; 1358 case GL_VIEWPORT_BIT: 1359 { 1360 unsigned i; 1361 const struct gl_viewport_attrib *vp; 1362 vp = (const struct gl_viewport_attrib *) attr->data; 1363 1364 for (i = 0; i < ctx->Const.MaxViewports; i++) { 1365 _mesa_set_viewport(ctx, i, vp[i].X, vp[i].Y, vp[i].Width, 1366 vp[i].Height); 1367 _mesa_set_depth_range(ctx, i, vp[i].Near, vp[i].Far); 1368 } 1369 } 1370 break; 1371 case GL_MULTISAMPLE_BIT_ARB: 1372 { 1373 const struct gl_multisample_attrib *ms; 1374 ms = (const struct gl_multisample_attrib *) attr->data; 1375 1376 TEST_AND_UPDATE(ctx->Multisample.Enabled, 1377 ms->Enabled, 1378 GL_MULTISAMPLE); 1379 1380 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 1381 ms->SampleCoverage, 1382 GL_SAMPLE_COVERAGE); 1383 1384 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 1385 ms->SampleAlphaToCoverage, 1386 GL_SAMPLE_ALPHA_TO_COVERAGE); 1387 1388 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 1389 ms->SampleAlphaToOne, 1390 GL_SAMPLE_ALPHA_TO_ONE); 1391 1392 _mesa_SampleCoverage(ms->SampleCoverageValue, 1393 ms->SampleCoverageInvert); 1394 } 1395 break; 1396 1397 default: 1398 _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); 1399 break; 1400 } 1401 1402 next = attr->next; 1403 free(attr->data); 1404 free(attr); 1405 attr = next; 1406 } 1407} 1408 1409 1410/** 1411 * Copy gl_pixelstore_attrib from src to dst, updating buffer 1412 * object refcounts. 1413 */ 1414static void 1415copy_pixelstore(struct gl_context *ctx, 1416 struct gl_pixelstore_attrib *dst, 1417 const struct gl_pixelstore_attrib *src) 1418{ 1419 dst->Alignment = src->Alignment; 1420 dst->RowLength = src->RowLength; 1421 dst->SkipPixels = src->SkipPixels; 1422 dst->SkipRows = src->SkipRows; 1423 dst->ImageHeight = src->ImageHeight; 1424 dst->SkipImages = src->SkipImages; 1425 dst->SwapBytes = src->SwapBytes; 1426 dst->LsbFirst = src->LsbFirst; 1427 dst->Invert = src->Invert; 1428 _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); 1429} 1430 1431 1432#define GL_CLIENT_PACK_BIT (1<<20) 1433#define GL_CLIENT_UNPACK_BIT (1<<21) 1434 1435/** 1436 * Copy gl_vertex_array_object from src to dest. 1437 * 'dest' must be in an initialized state. 1438 */ 1439static void 1440copy_array_object(struct gl_context *ctx, 1441 struct gl_vertex_array_object *dest, 1442 struct gl_vertex_array_object *src) 1443{ 1444 GLuint i; 1445 1446 /* skip Name */ 1447 /* skip RefCount */ 1448 1449 /* In theory must be the same anyway, but on recreate make sure it matches */ 1450 dest->ARBsemantics = src->ARBsemantics; 1451 1452 for (i = 0; i < Elements(src->_VertexAttrib); i++) { 1453 _mesa_copy_client_array(ctx, &dest->_VertexAttrib[i], &src->_VertexAttrib[i]); 1454 _mesa_copy_vertex_attrib_array(ctx, &dest->VertexAttrib[i], &src->VertexAttrib[i]); 1455 _mesa_copy_vertex_buffer_binding(ctx, &dest->VertexBinding[i], &src->VertexBinding[i]); 1456 } 1457 1458 /* _Enabled must be the same than on push */ 1459 dest->_Enabled = src->_Enabled; 1460 dest->NewArrays = src->NewArrays; 1461 dest->_MaxElement = src->_MaxElement; 1462} 1463 1464/** 1465 * Copy gl_array_attrib from src to dest. 1466 * 'dest' must be in an initialized state. 1467 */ 1468static void 1469copy_array_attrib(struct gl_context *ctx, 1470 struct gl_array_attrib *dest, 1471 struct gl_array_attrib *src, 1472 bool vbo_deleted) 1473{ 1474 /* skip ArrayObj */ 1475 /* skip DefaultArrayObj, Objects */ 1476 dest->ActiveTexture = src->ActiveTexture; 1477 dest->LockFirst = src->LockFirst; 1478 dest->LockCount = src->LockCount; 1479 dest->PrimitiveRestart = src->PrimitiveRestart; 1480 dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex; 1481 dest->_PrimitiveRestart = src->_PrimitiveRestart; 1482 dest->RestartIndex = src->RestartIndex; 1483 /* skip NewState */ 1484 /* skip RebindArrays */ 1485 1486 if (!vbo_deleted) 1487 copy_array_object(ctx, dest->VAO, src->VAO); 1488 1489 /* skip ArrayBufferObj */ 1490 /* skip IndexBufferObj */ 1491 1492 /* Invalidate draw state. It will be updated during the next draw. */ 1493 dest->DrawMethod = DRAW_NONE; 1494 dest->_DrawArrays = NULL; 1495} 1496 1497/** 1498 * Save the content of src to dest. 1499 */ 1500static void 1501save_array_attrib(struct gl_context *ctx, 1502 struct gl_array_attrib *dest, 1503 struct gl_array_attrib *src) 1504{ 1505 /* Set the Name, needed for restore, but do never overwrite. 1506 * Needs to match value in the object hash. */ 1507 dest->VAO->Name = src->VAO->Name; 1508 /* And copy all of the rest. */ 1509 copy_array_attrib(ctx, dest, src, false); 1510 1511 /* Just reference them here */ 1512 _mesa_reference_buffer_object(ctx, &dest->ArrayBufferObj, 1513 src->ArrayBufferObj); 1514 _mesa_reference_buffer_object(ctx, &dest->VAO->IndexBufferObj, 1515 src->VAO->IndexBufferObj); 1516} 1517 1518/** 1519 * Restore the content of src to dest. 1520 */ 1521static void 1522restore_array_attrib(struct gl_context *ctx, 1523 struct gl_array_attrib *dest, 1524 struct gl_array_attrib *src) 1525{ 1526 /* The ARB_vertex_array_object spec says: 1527 * 1528 * "BindVertexArray fails and an INVALID_OPERATION error is generated 1529 * if array is not a name returned from a previous call to 1530 * GenVertexArrays, or if such a name has since been deleted with 1531 * DeleteVertexArrays." 1532 * 1533 * Therefore popping a deleted VAO cannot magically recreate it. 1534 * 1535 * The semantics of objects created using APPLE_vertex_array_objects behave 1536 * differently. These objects expect to be recreated by pop. Alas. 1537 */ 1538 const bool arb_vao = (src->VAO->Name != 0 1539 && src->VAO->ARBsemantics); 1540 1541 if (arb_vao && !_mesa_IsVertexArray(src->VAO->Name)) 1542 return; 1543 1544 _mesa_BindVertexArrayAPPLE(src->VAO->Name); 1545 1546 /* Restore or recreate the buffer objects by the names ... */ 1547 if (!arb_vao 1548 || src->ArrayBufferObj->Name == 0 1549 || _mesa_IsBuffer(src->ArrayBufferObj->Name)) { 1550 /* ... and restore its content */ 1551 copy_array_attrib(ctx, dest, src, false); 1552 1553 _mesa_BindBuffer(GL_ARRAY_BUFFER_ARB, 1554 src->ArrayBufferObj->Name); 1555 } else { 1556 copy_array_attrib(ctx, dest, src, true); 1557 } 1558 1559 if (!arb_vao 1560 || src->VAO->IndexBufferObj->Name == 0 1561 || _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) 1562 _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 1563 src->VAO->IndexBufferObj->Name); 1564} 1565 1566/** 1567 * init/alloc the fields of 'attrib'. 1568 * Needs to the init part matching free_array_attrib_data below. 1569 */ 1570static bool 1571init_array_attrib_data(struct gl_context *ctx, 1572 struct gl_array_attrib *attrib) 1573{ 1574 /* Get a non driver gl_vertex_array_object. */ 1575 attrib->VAO = CALLOC_STRUCT( gl_vertex_array_object ); 1576 1577 if (attrib->VAO == NULL) { 1578 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); 1579 return false; 1580 } 1581 1582 _mesa_initialize_vao(ctx, attrib->VAO, 0); 1583 return true; 1584} 1585 1586/** 1587 * Free/unreference the fields of 'attrib' but don't delete it (that's 1588 * done later in the calling code). 1589 * Needs to the cleanup part matching init_array_attrib_data above. 1590 */ 1591static void 1592free_array_attrib_data(struct gl_context *ctx, 1593 struct gl_array_attrib *attrib) 1594{ 1595 /* We use a non driver array object, so don't just unref since we would 1596 * end up using the drivers DeleteArrayObject function for deletion. */ 1597 _mesa_delete_vao(ctx, attrib->VAO); 1598 attrib->VAO = 0; 1599 _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL); 1600} 1601 1602 1603void GLAPIENTRY 1604_mesa_PushClientAttrib(GLbitfield mask) 1605{ 1606 struct gl_attrib_node *head; 1607 1608 GET_CURRENT_CONTEXT(ctx); 1609 1610 if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { 1611 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); 1612 return; 1613 } 1614 1615 /* Build linked list of attribute nodes which save all attribute 1616 * groups specified by the mask. 1617 */ 1618 head = NULL; 1619 1620 if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 1621 struct gl_pixelstore_attrib *attr; 1622 /* packing attribs */ 1623 attr = CALLOC_STRUCT( gl_pixelstore_attrib ); 1624 if (attr == NULL) { 1625 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); 1626 goto end; 1627 } 1628 if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) { 1629 copy_pixelstore(ctx, attr, &ctx->Pack); 1630 } 1631 else { 1632 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); 1633 free(attr); 1634 goto end; 1635 } 1636 1637 /* unpacking attribs */ 1638 attr = CALLOC_STRUCT( gl_pixelstore_attrib ); 1639 if (attr == NULL) { 1640 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); 1641 goto end; 1642 } 1643 1644 if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) { 1645 copy_pixelstore(ctx, attr, &ctx->Unpack); 1646 } 1647 else { 1648 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" ); 1649 free(attr); 1650 goto end; 1651 } 1652 } 1653 1654 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1655 struct gl_array_attrib *attr; 1656 attr = CALLOC_STRUCT( gl_array_attrib ); 1657 if (attr == NULL) { 1658 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); 1659 goto end; 1660 } 1661 1662 if (!init_array_attrib_data(ctx, attr)) { 1663 free(attr); 1664 goto end; 1665 } 1666 1667 if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) { 1668 save_array_attrib(ctx, attr, &ctx->Array); 1669 } 1670 else { 1671 free_array_attrib_data(ctx, attr); 1672 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); 1673 free(attr); 1674 /* goto to keep safe from possible later changes */ 1675 goto end; 1676 } 1677 } 1678end: 1679 if (head != NULL) { 1680 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; 1681 ctx->ClientAttribStackDepth++; 1682 } 1683} 1684 1685 1686 1687 1688void GLAPIENTRY 1689_mesa_PopClientAttrib(void) 1690{ 1691 struct gl_attrib_node *node, *next; 1692 1693 GET_CURRENT_CONTEXT(ctx); 1694 FLUSH_VERTICES(ctx, 0); 1695 1696 if (ctx->ClientAttribStackDepth == 0) { 1697 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); 1698 return; 1699 } 1700 1701 ctx->ClientAttribStackDepth--; 1702 node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 1703 1704 while (node) { 1705 switch (node->kind) { 1706 case GL_CLIENT_PACK_BIT: 1707 { 1708 struct gl_pixelstore_attrib *store = 1709 (struct gl_pixelstore_attrib *) node->data; 1710 copy_pixelstore(ctx, &ctx->Pack, store); 1711 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); 1712 } 1713 break; 1714 case GL_CLIENT_UNPACK_BIT: 1715 { 1716 struct gl_pixelstore_attrib *store = 1717 (struct gl_pixelstore_attrib *) node->data; 1718 copy_pixelstore(ctx, &ctx->Unpack, store); 1719 _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); 1720 } 1721 break; 1722 case GL_CLIENT_VERTEX_ARRAY_BIT: { 1723 struct gl_array_attrib * attr = 1724 (struct gl_array_attrib *) node->data; 1725 restore_array_attrib(ctx, &ctx->Array, attr); 1726 free_array_attrib_data(ctx, attr); 1727 ctx->NewState |= _NEW_ARRAY; 1728 break; 1729 } 1730 default: 1731 _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); 1732 break; 1733 } 1734 1735 next = node->next; 1736 free(node->data); 1737 free(node); 1738 node = next; 1739 } 1740} 1741 1742 1743/** 1744 * Free any attribute state data that might be attached to the context. 1745 */ 1746void 1747_mesa_free_attrib_data(struct gl_context *ctx) 1748{ 1749 while (ctx->AttribStackDepth > 0) { 1750 struct gl_attrib_node *attr, *next; 1751 1752 ctx->AttribStackDepth--; 1753 attr = ctx->AttribStack[ctx->AttribStackDepth]; 1754 1755 while (attr) { 1756 if (attr->kind == GL_TEXTURE_BIT) { 1757 struct texture_state *texstate = (struct texture_state*)attr->data; 1758 GLuint u, tgt; 1759 /* clear references to the saved texture objects */ 1760 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 1761 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 1762 _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); 1763 } 1764 } 1765 _mesa_reference_shared_state(ctx, &texstate->SharedRef, NULL); 1766 } 1767 else { 1768 /* any other chunks of state that requires special handling? */ 1769 } 1770 1771 next = attr->next; 1772 free(attr->data); 1773 free(attr); 1774 attr = next; 1775 } 1776 } 1777} 1778 1779 1780void _mesa_init_attrib( struct gl_context *ctx ) 1781{ 1782 /* Renderer and client attribute stacks */ 1783 ctx->AttribStackDepth = 0; 1784 ctx->ClientAttribStackDepth = 0; 1785} 1786