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