attrib.c revision eb6c6439ae23e47b79b72f3737b6d0d14e1f9f26
1/* $Id: attrib.c,v 1.28 2000/09/28 22:44:30 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.3 6 * 7 * Copyright (C) 1999-2000 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 "attrib.h" 33#include "buffers.h" 34#include "context.h" 35#include "enable.h" 36#include "enums.h" 37#include "mem.h" 38#include "simple_list.h" 39#include "texstate.h" 40#include "types.h" 41#endif 42 43 44 45 46/* 47 * Allocate a new attribute state node. These nodes have a 48 * "kind" value and a pointer to a struct of state data. 49 */ 50static struct gl_attrib_node * 51new_attrib_node( GLbitfield kind ) 52{ 53 struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node); 54 if (an) { 55 an->kind = kind; 56 } 57 return an; 58} 59 60 61 62/* 63 * Copy texture object state from one texture object to another. 64 */ 65static void 66copy_texobj_state( struct gl_texture_object *dest, 67 const struct gl_texture_object *src ) 68{ 69 /* 70 dest->Name = src->Name; 71 dest->Dimensions = src->Dimensions; 72 */ 73 dest->Priority = src->Priority; 74 dest->BorderColor[0] = src->BorderColor[0]; 75 dest->BorderColor[1] = src->BorderColor[1]; 76 dest->BorderColor[2] = src->BorderColor[2]; 77 dest->BorderColor[3] = src->BorderColor[3]; 78 dest->WrapS = src->WrapS; 79 dest->WrapT = src->WrapT; 80 dest->WrapR = src->WrapR; 81 dest->MinFilter = src->MinFilter; 82 dest->MagFilter = src->MagFilter; 83 dest->MinLod = src->MinLod; 84 dest->MaxLod = src->MaxLod; 85 dest->BaseLevel = src->BaseLevel; 86 dest->MaxLevel = src->MaxLevel; 87 dest->P = src->P; 88 dest->M = src->M; 89 dest->MinMagThresh = src->MinMagThresh; 90 dest->Palette = src->Palette; 91 dest->Complete = src->Complete; 92 dest->SampleFunc = src->SampleFunc; 93} 94 95 96 97void 98_mesa_PushAttrib(GLbitfield mask) 99{ 100 struct gl_attrib_node *newnode; 101 struct gl_attrib_node *head; 102 103 GET_CURRENT_CONTEXT(ctx); 104 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushAttrib"); 105 106 if (MESA_VERBOSE&VERBOSE_API) 107 fprintf(stderr, "glPushAttrib %x\n", (int)mask); 108 109 if (ctx->AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) { 110 gl_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); 111 return; 112 } 113 114 /* Build linked list of attribute nodes which save all attribute */ 115 /* groups specified by the mask. */ 116 head = NULL; 117 118 if (mask & GL_ACCUM_BUFFER_BIT) { 119 struct gl_accum_attrib *attr; 120 attr = MALLOC_STRUCT( gl_accum_attrib ); 121 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); 122 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT ); 123 newnode->data = attr; 124 newnode->next = head; 125 head = newnode; 126 } 127 128 if (mask & GL_COLOR_BUFFER_BIT) { 129 struct gl_colorbuffer_attrib *attr; 130 attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); 131 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); 132 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT ); 133 newnode->data = attr; 134 newnode->next = head; 135 head = newnode; 136 } 137 138 if (mask & GL_CURRENT_BIT) { 139 struct gl_current_attrib *attr; 140 attr = MALLOC_STRUCT( gl_current_attrib ); 141 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); 142 newnode = new_attrib_node( GL_CURRENT_BIT ); 143 newnode->data = attr; 144 newnode->next = head; 145 head = newnode; 146 } 147 148 if (mask & GL_DEPTH_BUFFER_BIT) { 149 struct gl_depthbuffer_attrib *attr; 150 attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); 151 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); 152 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT ); 153 newnode->data = attr; 154 newnode->next = head; 155 head = newnode; 156 } 157 158 if (mask & GL_ENABLE_BIT) { 159 struct gl_enable_attrib *attr; 160 GLuint i; 161 attr = MALLOC_STRUCT( gl_enable_attrib ); 162 /* Copy enable flags from all other attributes into the enable struct. */ 163 attr->AlphaTest = ctx->Color.AlphaEnabled; 164 attr->AutoNormal = ctx->Eval.AutoNormal; 165 attr->Blend = ctx->Color.BlendEnabled; 166 for (i=0;i<MAX_CLIP_PLANES;i++) { 167 attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i]; 168 } 169 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 170 attr->Convolution1D = ctx->Pixel.Convolution1DEnabled; 171 attr->Convolution2D = ctx->Pixel.Convolution2DEnabled; 172 attr->Separable2D = ctx->Pixel.Separable2DEnabled; 173 attr->CullFace = ctx->Polygon.CullFlag; 174 attr->DepthTest = ctx->Depth.Test; 175 attr->Dither = ctx->Color.DitherFlag; 176 attr->Fog = ctx->Fog.Enabled; 177 for (i=0;i<MAX_LIGHTS;i++) { 178 attr->Light[i] = ctx->Light.Light[i].Enabled; 179 } 180 attr->Lighting = ctx->Light.Enabled; 181 attr->LineSmooth = ctx->Line.SmoothFlag; 182 attr->LineStipple = ctx->Line.StippleFlag; 183 attr->Histogram = ctx->Pixel.HistogramEnabled; 184 attr->MinMax = ctx->Pixel.MinMaxEnabled; 185 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 186 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 187 attr->Map1Color4 = ctx->Eval.Map1Color4; 188 attr->Map1Index = ctx->Eval.Map1Index; 189 attr->Map1Normal = ctx->Eval.Map1Normal; 190 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 191 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 192 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 193 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 194 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 195 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 196 attr->Map2Color4 = ctx->Eval.Map2Color4; 197 attr->Map2Index = ctx->Eval.Map2Index; 198 attr->Map2Normal = ctx->Eval.Map2Normal; 199 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 200 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 201 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 202 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 203 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 204 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 205 attr->Normalize = ctx->Transform.Normalize; 206 attr->PixelTexture = ctx->Pixel.PixelTextureEnabled; 207 attr->PointSmooth = ctx->Point.SmoothFlag; 208 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 209 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 210 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 211 attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 212 attr->PolygonStipple = ctx->Polygon.StippleFlag; 213 attr->RescaleNormals = ctx->Transform.RescaleNormals; 214 attr->Scissor = ctx->Scissor.Enabled; 215 attr->Stencil = ctx->Stencil.Enabled; 216 for (i=0; i<MAX_TEXTURE_UNITS; i++) { 217 attr->Texture[i] = ctx->Texture.Unit[i].Enabled; 218 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; 219 } 220 newnode = new_attrib_node( GL_ENABLE_BIT ); 221 newnode->data = attr; 222 newnode->next = head; 223 head = newnode; 224 } 225 226 if (mask & GL_EVAL_BIT) { 227 struct gl_eval_attrib *attr; 228 attr = MALLOC_STRUCT( gl_eval_attrib ); 229 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); 230 newnode = new_attrib_node( GL_EVAL_BIT ); 231 newnode->data = attr; 232 newnode->next = head; 233 head = newnode; 234 } 235 236 if (mask & GL_FOG_BIT) { 237 struct gl_fog_attrib *attr; 238 attr = MALLOC_STRUCT( gl_fog_attrib ); 239 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); 240 newnode = new_attrib_node( GL_FOG_BIT ); 241 newnode->data = attr; 242 newnode->next = head; 243 head = newnode; 244 } 245 246 if (mask & GL_HINT_BIT) { 247 struct gl_hint_attrib *attr; 248 attr = MALLOC_STRUCT( gl_hint_attrib ); 249 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); 250 newnode = new_attrib_node( GL_HINT_BIT ); 251 newnode->data = attr; 252 newnode->next = head; 253 head = newnode; 254 } 255 256 if (mask & GL_LIGHTING_BIT) { 257 struct gl_light_attrib *attr; 258 attr = MALLOC_STRUCT( gl_light_attrib ); 259 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); 260 newnode = new_attrib_node( GL_LIGHTING_BIT ); 261 newnode->data = attr; 262 newnode->next = head; 263 head = newnode; 264 } 265 266 if (mask & GL_LINE_BIT) { 267 struct gl_line_attrib *attr; 268 attr = MALLOC_STRUCT( gl_line_attrib ); 269 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); 270 newnode = new_attrib_node( GL_LINE_BIT ); 271 newnode->data = attr; 272 newnode->next = head; 273 head = newnode; 274 } 275 276 if (mask & GL_LIST_BIT) { 277 struct gl_list_attrib *attr; 278 attr = MALLOC_STRUCT( gl_list_attrib ); 279 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) ); 280 newnode = new_attrib_node( GL_LIST_BIT ); 281 newnode->data = attr; 282 newnode->next = head; 283 head = newnode; 284 } 285 286 if (mask & GL_PIXEL_MODE_BIT) { 287 struct gl_pixel_attrib *attr; 288 attr = MALLOC_STRUCT( gl_pixel_attrib ); 289 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); 290 newnode = new_attrib_node( GL_PIXEL_MODE_BIT ); 291 newnode->data = attr; 292 newnode->next = head; 293 head = newnode; 294 } 295 296 if (mask & GL_POINT_BIT) { 297 struct gl_point_attrib *attr; 298 attr = MALLOC_STRUCT( gl_point_attrib ); 299 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); 300 newnode = new_attrib_node( GL_POINT_BIT ); 301 newnode->data = attr; 302 newnode->next = head; 303 head = newnode; 304 } 305 306 if (mask & GL_POLYGON_BIT) { 307 struct gl_polygon_attrib *attr; 308 attr = MALLOC_STRUCT( gl_polygon_attrib ); 309 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); 310 newnode = new_attrib_node( GL_POLYGON_BIT ); 311 newnode->data = attr; 312 newnode->next = head; 313 head = newnode; 314 } 315 316 if (mask & GL_POLYGON_STIPPLE_BIT) { 317 GLuint *stipple; 318 stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) ); 319 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); 320 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT ); 321 newnode->data = stipple; 322 newnode->next = head; 323 head = newnode; 324 } 325 326 if (mask & GL_SCISSOR_BIT) { 327 struct gl_scissor_attrib *attr; 328 attr = MALLOC_STRUCT( gl_scissor_attrib ); 329 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); 330 newnode = new_attrib_node( GL_SCISSOR_BIT ); 331 newnode->data = attr; 332 newnode->next = head; 333 head = newnode; 334 } 335 336 if (mask & GL_STENCIL_BUFFER_BIT) { 337 struct gl_stencil_attrib *attr; 338 attr = MALLOC_STRUCT( gl_stencil_attrib ); 339 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); 340 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT ); 341 newnode->data = attr; 342 newnode->next = head; 343 head = newnode; 344 } 345 346 if (mask & GL_TEXTURE_BIT) { 347 struct gl_texture_attrib *attr; 348 GLuint u; 349 /* Take care of texture object reference counters */ 350 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 351 ctx->Texture.Unit[u].CurrentD[1]->RefCount++; 352 ctx->Texture.Unit[u].CurrentD[2]->RefCount++; 353 ctx->Texture.Unit[u].CurrentD[3]->RefCount++; 354 } 355 attr = MALLOC_STRUCT( gl_texture_attrib ); 356 MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); 357 /* copy state of the currently bound texture objects */ 358 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 359 copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].CurrentD[1]); 360 copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].CurrentD[2]); 361 copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].CurrentD[3]); 362 copy_texobj_state(&attr->Unit[u].SavedCubeMap, attr->Unit[u].CurrentCubeMap); 363 } 364 newnode = new_attrib_node( GL_TEXTURE_BIT ); 365 newnode->data = attr; 366 newnode->next = head; 367 head = newnode; 368 } 369 370 if (mask & GL_TRANSFORM_BIT) { 371 struct gl_transform_attrib *attr; 372 attr = MALLOC_STRUCT( gl_transform_attrib ); 373 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); 374 newnode = new_attrib_node( GL_TRANSFORM_BIT ); 375 newnode->data = attr; 376 newnode->next = head; 377 head = newnode; 378 } 379 380 if (mask & GL_VIEWPORT_BIT) { 381 struct gl_viewport_attrib *attr; 382 attr = MALLOC_STRUCT( gl_viewport_attrib ); 383 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); 384 newnode = new_attrib_node( GL_VIEWPORT_BIT ); 385 newnode->data = attr; 386 newnode->next = head; 387 head = newnode; 388 } 389 390 ctx->AttribStack[ctx->AttribStackDepth] = head; 391 ctx->AttribStackDepth++; 392} 393 394 395 396static void 397pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) 398{ 399 GLuint i; 400 401#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ 402 if ((VALUE) != (NEWVALUE)) { \ 403 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ 404 } 405 406 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 407 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->AutoNormal, GL_NORMALIZE); 408 TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); 409 410 for (i=0;i<MAX_CLIP_PLANES;i++) { 411 if (ctx->Transform.ClipEnabled[i] != enable->ClipPlane[i]) 412 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), 413 enable->ClipPlane[i]); 414 } 415 416 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 417 GL_COLOR_MATERIAL); 418 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 419 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 420 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 421 TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D, 422 GL_CONVOLUTION_1D); 423 TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D, 424 GL_CONVOLUTION_2D); 425 TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D, 426 GL_SEPARABLE_2D); 427 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 428 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 429 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 430 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 431 GL_LINE_STIPPLE); 432 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 433 GL_INDEX_LOGIC_OP); 434 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 435 GL_COLOR_LOGIC_OP); 436 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 437 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 438 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 439 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 440 GL_MAP1_TEXTURE_COORD_1); 441 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 442 GL_MAP1_TEXTURE_COORD_2); 443 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 444 GL_MAP1_TEXTURE_COORD_3); 445 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 446 GL_MAP1_TEXTURE_COORD_4); 447 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 448 GL_MAP1_VERTEX_3); 449 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 450 GL_MAP1_VERTEX_4); 451 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 452 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 453 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 454 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 455 GL_MAP2_TEXTURE_COORD_1); 456 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 457 GL_MAP2_TEXTURE_COORD_2); 458 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 459 GL_MAP2_TEXTURE_COORD_3); 460 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 461 GL_MAP2_TEXTURE_COORD_4); 462 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 463 GL_MAP2_VERTEX_3); 464 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 465 GL_MAP2_VERTEX_4); 466 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 467 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 468 GL_RESCALE_NORMAL_EXT); 469 TEST_AND_UPDATE(ctx->Pixel.PixelTextureEnabled, enable->PixelTexture, 470 GL_POINT_SMOOTH); 471 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 472 GL_POINT_SMOOTH); 473 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 474 GL_POLYGON_OFFSET_POINT); 475 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 476 GL_POLYGON_OFFSET_LINE); 477 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 478 GL_POLYGON_OFFSET_FILL); 479 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 480 GL_POLYGON_SMOOTH); 481 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 482 GL_POLYGON_STIPPLE); 483 TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); 484 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 485#undef TEST_AND_UPDATE 486 487 /* texture unit enables */ 488 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 489 if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) { 490 ctx->Texture.Unit[i].Enabled = enable->Texture[i]; 491 if (ctx->Driver.Enable) { 492 if (ctx->Driver.ActiveTexture) { 493 (*ctx->Driver.ActiveTexture)(ctx, i); 494 } 495 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, 496 (GLboolean) (enable->Texture[i] & TEXTURE0_1D) ); 497 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, 498 (GLboolean) (enable->Texture[i] & TEXTURE0_2D) ); 499 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, 500 (GLboolean) (enable->Texture[i] & TEXTURE0_3D) ); 501 } 502 } 503 504 if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) { 505 ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i]; 506 if (ctx->Driver.Enable) { 507 if (ctx->Driver.ActiveTexture) { 508 (*ctx->Driver.ActiveTexture)(ctx, i); 509 } 510 if (enable->TexGen[i] & S_BIT) 511 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE); 512 else 513 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE); 514 if (enable->TexGen[i] & T_BIT) 515 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE); 516 else 517 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE); 518 if (enable->TexGen[i] & R_BIT) 519 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE); 520 else 521 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE); 522 if (enable->TexGen[i] & Q_BIT) 523 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE); 524 else 525 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 526 } 527 } 528 } 529 530 if (ctx->Driver.ActiveTexture) { 531 (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit); 532 } 533} 534 535 536 537/* 538 * This function is kind of long just because we have to call a lot 539 * of device driver functions to update device driver state. 540 */ 541void 542_mesa_PopAttrib(void) 543{ 544 struct gl_attrib_node *attr, *next; 545 GET_CURRENT_CONTEXT(ctx); 546 547 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopAttrib"); 548 549 550 if (ctx->AttribStackDepth==0) { 551 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); 552 return; 553 } 554 555 ctx->AttribStackDepth--; 556 attr = ctx->AttribStack[ctx->AttribStackDepth]; 557 558 while (attr) { 559 560 if (MESA_VERBOSE&VERBOSE_API) 561 fprintf(stderr, "glPopAttrib %s\n", gl_lookup_enum_by_nr(attr->kind)); 562 563 switch (attr->kind) { 564 case GL_ACCUM_BUFFER_BIT: 565 MEMCPY( &ctx->Accum, attr->data, sizeof(struct gl_accum_attrib) ); 566 break; 567 case GL_COLOR_BUFFER_BIT: 568 { 569 GLenum oldDrawBuffer = ctx->Color.DrawBuffer; 570 GLenum oldAlphaFunc = ctx->Color.AlphaFunc; 571 GLubyte oldAlphaRef = ctx->Color.AlphaRef; 572 GLenum oldBlendSrc = ctx->Color.BlendSrcRGB; 573 GLenum oldBlendDst = ctx->Color.BlendDstRGB; 574 GLenum oldLogicOp = ctx->Color.LogicOp; 575 MEMCPY( &ctx->Color, attr->data, 576 sizeof(struct gl_colorbuffer_attrib) ); 577 if (ctx->Color.DrawBuffer != oldDrawBuffer) { 578 _mesa_DrawBuffer( ctx->Color.DrawBuffer); 579 } 580 if ((ctx->Color.BlendSrcRGB != oldBlendSrc || 581 ctx->Color.BlendDstRGB != oldBlendDst) && 582 ctx->Driver.BlendFunc) 583 (*ctx->Driver.BlendFunc)( ctx, ctx->Color.BlendSrcRGB, 584 ctx->Color.BlendDstRGB); 585 if (ctx->Color.LogicOp != oldLogicOp && 586 ctx->Driver.LogicOpcode) { 587 ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); 588 } 589 if (ctx->Visual.RGBAflag) { 590 GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F); 591 GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F); 592 GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F); 593 GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F); 594 (*ctx->Driver.ClearColor)( ctx, r, g, b, a ); 595 if ((ctx->Color.AlphaFunc != oldAlphaFunc || 596 ctx->Color.AlphaRef != oldAlphaRef) && 597 ctx->Driver.AlphaFunc) 598 (*ctx->Driver.AlphaFunc)( ctx, ctx->Color.AlphaFunc, 599 ctx->Color.AlphaRef / 255.0F); 600 if (ctx->Driver.ColorMask) { 601 (*ctx->Driver.ColorMask)(ctx, 602 ctx->Color.ColorMask[0], 603 ctx->Color.ColorMask[1], 604 ctx->Color.ColorMask[2], 605 ctx->Color.ColorMask[3]); 606 } 607 } 608 else { 609 (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex); 610 } 611 } 612 break; 613 case GL_CURRENT_BIT: 614 MEMCPY( &ctx->Current, attr->data, 615 sizeof(struct gl_current_attrib) ); 616 break; 617 case GL_DEPTH_BUFFER_BIT: 618 { 619 GLboolean oldDepthTest = ctx->Depth.Test; 620 GLenum oldDepthFunc = ctx->Depth.Func; 621 GLboolean oldDepthMask = ctx->Depth.Mask; 622 GLfloat oldDepthClear = ctx->Depth.Clear; 623 MEMCPY( &ctx->Depth, attr->data, 624 sizeof(struct gl_depthbuffer_attrib) ); 625 if (ctx->Depth.Test != oldDepthTest && ctx->Driver.Enable) 626 (*ctx->Driver.Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test); 627 if (ctx->Depth.Func != oldDepthFunc && ctx->Driver.DepthFunc) 628 (*ctx->Driver.DepthFunc)( ctx, ctx->Depth.Func ); 629 if (ctx->Depth.Mask != oldDepthMask && ctx->Driver.DepthMask) 630 (*ctx->Driver.DepthMask)( ctx, ctx->Depth.Mask ); 631 if (ctx->Depth.Clear != oldDepthClear && ctx->Driver.ClearDepth) 632 (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear ); 633 } 634 break; 635 case GL_ENABLE_BIT: 636 { 637 const struct gl_enable_attrib *enable; 638 enable = (const struct gl_enable_attrib *) attr->data; 639 pop_enable_group(ctx, enable); 640 } 641 break; 642 case GL_EVAL_BIT: 643 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); 644 break; 645 case GL_FOG_BIT: 646 { 647 GLboolean anyChange = (GLboolean) (memcmp( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) ) != 0); 648 MEMCPY( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) ); 649 if (anyChange && ctx->Driver.Fogfv) { 650 const GLfloat mode = (GLfloat) ctx->Fog.Mode; 651 const GLfloat density = ctx->Fog.Density; 652 const GLfloat start = ctx->Fog.Start; 653 const GLfloat end = ctx->Fog.End; 654 const GLfloat index = ctx->Fog.Index; 655 (*ctx->Driver.Fogfv)( ctx, GL_FOG_MODE, &mode); 656 (*ctx->Driver.Fogfv)( ctx, GL_FOG_DENSITY, &density ); 657 (*ctx->Driver.Fogfv)( ctx, GL_FOG_START, &start ); 658 (*ctx->Driver.Fogfv)( ctx, GL_FOG_END, &end ); 659 (*ctx->Driver.Fogfv)( ctx, GL_FOG_INDEX, &index ); 660 (*ctx->Driver.Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color ); 661 } 662 ctx->Enabled &= ~ENABLE_FOG; 663 if (ctx->Fog.Enabled) ctx->Enabled |= ENABLE_FOG; 664 } 665 break; 666 case GL_HINT_BIT: 667 MEMCPY( &ctx->Hint, attr->data, sizeof(struct gl_hint_attrib) ); 668 if (ctx->Driver.Hint) { 669 (*ctx->Driver.Hint)( ctx, GL_PERSPECTIVE_CORRECTION_HINT, 670 ctx->Hint.PerspectiveCorrection ); 671 (*ctx->Driver.Hint)( ctx, GL_POINT_SMOOTH_HINT, 672 ctx->Hint.PointSmooth); 673 (*ctx->Driver.Hint)( ctx, GL_LINE_SMOOTH_HINT, 674 ctx->Hint.LineSmooth ); 675 (*ctx->Driver.Hint)( ctx, GL_POLYGON_SMOOTH_HINT, 676 ctx->Hint.PolygonSmooth ); 677 (*ctx->Driver.Hint)( ctx, GL_FOG_HINT, ctx->Hint.Fog ); 678 } 679 break; 680 case GL_LIGHTING_BIT: 681 MEMCPY( &ctx->Light, attr->data, sizeof(struct gl_light_attrib) ); 682 if (ctx->Driver.Enable) { 683 GLuint i; 684 for (i = 0; i < MAX_LIGHTS; i++) { 685 GLenum light = (GLenum) (GL_LIGHT0 + i); 686 (*ctx->Driver.Enable)( ctx, light, ctx->Light.Light[i].Enabled ); 687 } 688 (*ctx->Driver.Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled ); 689 } 690 if (ctx->Light.ShadeModel == GL_FLAT) 691 ctx->TriangleCaps |= DD_FLATSHADE; 692 else 693 ctx->TriangleCaps &= ~DD_FLATSHADE; 694 if (ctx->Driver.ShadeModel) 695 (*ctx->Driver.ShadeModel)(ctx, ctx->Light.ShadeModel); 696 ctx->Enabled &= ~ENABLE_LIGHT; 697 if (ctx->Light.Enabled && !is_empty_list(&ctx->Light.EnabledList)) 698 ctx->Enabled |= ENABLE_LIGHT; 699 break; 700 case GL_LINE_BIT: 701 MEMCPY( &ctx->Line, attr->data, sizeof(struct gl_line_attrib) ); 702 if (ctx->Driver.Enable) { 703 (*ctx->Driver.Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); 704 (*ctx->Driver.Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag ); 705 } 706 if (ctx->Driver.LineStipple) 707 (*ctx->Driver.LineStipple)(ctx, ctx->Line.StippleFactor, 708 ctx->Line.StipplePattern); 709 if (ctx->Driver.LineWidth) 710 (*ctx->Driver.LineWidth)(ctx, ctx->Line.Width); 711 break; 712 case GL_LIST_BIT: 713 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); 714 break; 715 case GL_PIXEL_MODE_BIT: 716 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); 717 break; 718 case GL_POINT_BIT: 719 MEMCPY( &ctx->Point, attr->data, sizeof(struct gl_point_attrib) ); 720 if (ctx->Driver.Enable) 721 (*ctx->Driver.Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag ); 722 break; 723 case GL_POLYGON_BIT: 724 { 725 GLenum oldFrontMode = ctx->Polygon.FrontMode; 726 GLenum oldBackMode = ctx->Polygon.BackMode; 727 MEMCPY( &ctx->Polygon, attr->data, 728 sizeof(struct gl_polygon_attrib) ); 729 if ((ctx->Polygon.FrontMode != oldFrontMode || 730 ctx->Polygon.BackMode != oldBackMode) && 731 ctx->Driver.PolygonMode) { 732 (*ctx->Driver.PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode); 733 (*ctx->Driver.PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode); 734 } 735 if (ctx->Driver.CullFace) 736 ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); 737 738 if (ctx->Driver.FrontFace) 739 ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); 740 741 if (ctx->Driver.Enable) 742 (*ctx->Driver.Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag ); 743 } 744 break; 745 case GL_POLYGON_STIPPLE_BIT: 746 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); 747 if (ctx->Driver.PolygonStipple) 748 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); 749 break; 750 case GL_SCISSOR_BIT: 751 MEMCPY( &ctx->Scissor, attr->data, 752 sizeof(struct gl_scissor_attrib) ); 753 if (ctx->Driver.Enable) 754 (*ctx->Driver.Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); 755 if (ctx->Driver.Scissor) 756 ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, 757 ctx->Scissor.Width, ctx->Scissor.Height ); 758 break; 759 case GL_STENCIL_BUFFER_BIT: 760 MEMCPY( &ctx->Stencil, attr->data, 761 sizeof(struct gl_stencil_attrib) ); 762 if (ctx->Driver.StencilFunc) 763 (*ctx->Driver.StencilFunc)( ctx, ctx->Stencil.Function, 764 ctx->Stencil.Ref, ctx->Stencil.ValueMask); 765 if (ctx->Driver.StencilMask) 766 (*ctx->Driver.StencilMask)( ctx, ctx->Stencil.WriteMask ); 767 if (ctx->Driver.StencilOp) 768 (*ctx->Driver.StencilOp)( ctx, ctx->Stencil.FailFunc, 769 ctx->Stencil.ZFailFunc, ctx->Stencil.ZPassFunc); 770 if (ctx->Driver.ClearStencil) 771 (*ctx->Driver.ClearStencil)( ctx, ctx->Stencil.Clear ); 772 if (ctx->Driver.Enable) 773 (*ctx->Driver.Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); 774 ctx->TriangleCaps &= ~DD_STENCIL; 775 if (ctx->Stencil.Enabled) 776 ctx->TriangleCaps |= DD_STENCIL; 777 778 break; 779 case GL_TRANSFORM_BIT: 780 MEMCPY( &ctx->Transform, attr->data, 781 sizeof(struct gl_transform_attrib) ); 782 if (ctx->Driver.Enable) { 783 (*ctx->Driver.Enable)( ctx, GL_NORMALIZE, ctx->Transform.Normalize ); 784 (*ctx->Driver.Enable)( ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals ); 785 } 786 ctx->Enabled &= ~(ENABLE_NORMALIZE|ENABLE_RESCALE); 787 if (ctx->Transform.Normalize) ctx->Enabled |= ENABLE_NORMALIZE; 788 if (ctx->Transform.RescaleNormals) ctx->Enabled |= ENABLE_RESCALE; 789 break; 790 case GL_TEXTURE_BIT: 791 /* Take care of texture object reference counters */ 792 { 793 GLuint u; 794 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 795 ctx->Texture.Unit[u].CurrentD[1]->RefCount--; 796 ctx->Texture.Unit[u].CurrentD[2]->RefCount--; 797 ctx->Texture.Unit[u].CurrentD[3]->RefCount--; 798 } 799 MEMCPY( &ctx->Texture, attr->data, 800 sizeof(struct gl_texture_attrib) ); 801 /* restore state of the currently bound texture objects */ 802 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 803 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[1], 804 &(ctx->Texture.Unit[u].Saved1D) ); 805 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[2], 806 &(ctx->Texture.Unit[u].Saved2D) ); 807 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[3], 808 &(ctx->Texture.Unit[u].Saved3D) ); 809 copy_texobj_state( ctx->Texture.Unit[u].CurrentCubeMap, 810 &(ctx->Texture.Unit[u].SavedCubeMap) ); 811 812 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[1] ); 813 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[2] ); 814 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[3] ); 815 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentCubeMap ); 816 817 } 818 } 819 break; 820 case GL_VIEWPORT_BIT: 821 { 822 struct gl_viewport_attrib *v = 823 (struct gl_viewport_attrib *)attr->data; 824 825 _mesa_Viewport( v->X, v->Y, v->Width, v->Height ); 826 _mesa_DepthRange( v->Near, v->Far ); 827 break; 828 } 829 default: 830 gl_problem( ctx, "Bad attrib flag in PopAttrib"); 831 break; 832 } 833 834 next = attr->next; 835 FREE( attr->data ); 836 FREE( attr ); 837 attr = next; 838 } 839 840 ctx->NewState = NEW_ALL; 841 ctx->ImageTransferState = UPDATE_IMAGE_TRANSFER_STATE; 842} 843 844 845#define GL_CLIENT_PACK_BIT (1<<20) 846#define GL_CLIENT_UNPACK_BIT (1<<21) 847 848 849void 850_mesa_PushClientAttrib(GLbitfield mask) 851{ 852 struct gl_attrib_node *newnode; 853 struct gl_attrib_node *head; 854 855 GET_CURRENT_CONTEXT(ctx); 856 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushClientAttrib"); 857 858 if (ctx->ClientAttribStackDepth>=MAX_CLIENT_ATTRIB_STACK_DEPTH) { 859 gl_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); 860 return; 861 } 862 863 /* Build linked list of attribute nodes which save all attribute */ 864 /* groups specified by the mask. */ 865 head = NULL; 866 867 if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 868 struct gl_pixelstore_attrib *attr; 869 /* packing attribs */ 870 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 871 MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) ); 872 newnode = new_attrib_node( GL_CLIENT_PACK_BIT ); 873 newnode->data = attr; 874 newnode->next = head; 875 head = newnode; 876 /* unpacking attribs */ 877 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 878 MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) ); 879 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT ); 880 newnode->data = attr; 881 newnode->next = head; 882 head = newnode; 883 } 884 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 885 struct gl_array_attrib *attr; 886 attr = MALLOC_STRUCT( gl_array_attrib ); 887 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); 888 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT ); 889 newnode->data = attr; 890 newnode->next = head; 891 head = newnode; 892 } 893 894 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; 895 ctx->ClientAttribStackDepth++; 896} 897 898 899 900 901void 902_mesa_PopClientAttrib(void) 903{ 904 struct gl_attrib_node *attr, *next; 905 906 GET_CURRENT_CONTEXT(ctx); 907 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopClientAttrib"); 908 909 if (ctx->ClientAttribStackDepth==0) { 910 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); 911 return; 912 } 913 914 ctx->ClientAttribStackDepth--; 915 attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 916 917 while (attr) { 918 switch (attr->kind) { 919 case GL_CLIENT_PACK_BIT: 920 MEMCPY( &ctx->Pack, attr->data, 921 sizeof(struct gl_pixelstore_attrib) ); 922 break; 923 case GL_CLIENT_UNPACK_BIT: 924 MEMCPY( &ctx->Unpack, attr->data, 925 sizeof(struct gl_pixelstore_attrib) ); 926 break; 927 case GL_CLIENT_VERTEX_ARRAY_BIT: 928 MEMCPY( &ctx->Array, attr->data, 929 sizeof(struct gl_array_attrib) ); 930 break; 931 default: 932 gl_problem( ctx, "Bad attrib flag in PopClientAttrib"); 933 break; 934 } 935 936 next = attr->next; 937 FREE( attr->data ); 938 FREE( attr ); 939 attr = next; 940 } 941 942 ctx->NewState = NEW_ALL; 943} 944 945 946 947