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