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