ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

attrib.c
Go to the documentation of this file.
00001 /*
00002  * Mesa 3-D graphics library
00003  * Version:  7.3
00004  *
00005  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
00006  * Copyright (C) 2009  VMware, Inc.   All Rights Reserved.
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a
00009  * copy of this software and associated documentation files (the "Software"),
00010  * to deal in the Software without restriction, including without limitation
00011  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00012  * and/or sell copies of the Software, and to permit persons to whom the
00013  * Software is furnished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included
00016  * in all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00021  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00022  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00023  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00024  */
00025 
00026 #include "glheader.h"
00027 #include "imports.h"
00028 #include "accum.h"
00029 #include "arrayobj.h"
00030 #include "attrib.h"
00031 #include "blend.h"
00032 #include "buffers.h"
00033 #include "bufferobj.h"
00034 #include "clear.h"
00035 #include "colormac.h"
00036 #include "colortab.h"
00037 #include "context.h"
00038 #include "depth.h"
00039 #include "enable.h"
00040 #include "enums.h"
00041 #include "fog.h"
00042 #include "hint.h"
00043 #include "light.h"
00044 #include "lines.h"
00045 #include "matrix.h"
00046 #include "multisample.h"
00047 #include "points.h"
00048 #include "polygon.h"
00049 #include "scissor.h"
00050 #include "simple_list.h"
00051 #include "stencil.h"
00052 #include "texenv.h"
00053 #include "texgen.h"
00054 #include "texobj.h"
00055 #include "texparam.h"
00056 #include "texstate.h"
00057 #include "varray.h"
00058 #include "mtypes.h"
00059 #include "math/m_xform.h"
00060 
00064 struct texture_state
00065 {
00066    struct gl_texture_attrib Texture;  
00069    struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
00070 
00075    struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS];
00076 };
00077 
00078 
00083 static struct gl_attrib_node *
00084 new_attrib_node( GLbitfield kind )
00085 {
00086    struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
00087    if (an) {
00088       an->kind = kind;
00089    }
00090    return an;
00091 }
00092 
00093 
00094 void GLAPIENTRY
00095 _mesa_PushAttrib(GLbitfield mask)
00096 {
00097    struct gl_attrib_node *newnode;
00098    struct gl_attrib_node *head;
00099 
00100    GET_CURRENT_CONTEXT(ctx);
00101    ASSERT_OUTSIDE_BEGIN_END(ctx);
00102 
00103    if (MESA_VERBOSE & VERBOSE_API)
00104       _mesa_debug(ctx, "glPushAttrib %x\n", (int) mask);
00105 
00106    if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) {
00107       _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
00108       return;
00109    }
00110 
00111    /* Build linked list of attribute nodes which save all attribute */
00112    /* groups specified by the mask. */
00113    head = NULL;
00114 
00115    if (mask & GL_ACCUM_BUFFER_BIT) {
00116       struct gl_accum_attrib *attr;
00117       attr = MALLOC_STRUCT( gl_accum_attrib );
00118       MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
00119       newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
00120       newnode->data = attr;
00121       newnode->next = head;
00122       head = newnode;
00123    }
00124 
00125    if (mask & GL_COLOR_BUFFER_BIT) {
00126       GLuint i;
00127       struct gl_colorbuffer_attrib *attr;
00128       attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
00129       MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
00130       /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
00131       for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
00132          attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
00133       newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
00134       newnode->data = attr;
00135       newnode->next = head;
00136       head = newnode;
00137    }
00138 
00139    if (mask & GL_CURRENT_BIT) {
00140       struct gl_current_attrib *attr;
00141       FLUSH_CURRENT( ctx, 0 );
00142       attr = MALLOC_STRUCT( gl_current_attrib );
00143       MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
00144       newnode = new_attrib_node( GL_CURRENT_BIT );
00145       newnode->data = attr;
00146       newnode->next = head;
00147       head = newnode;
00148    }
00149 
00150    if (mask & GL_DEPTH_BUFFER_BIT) {
00151       struct gl_depthbuffer_attrib *attr;
00152       attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
00153       MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
00154       newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
00155       newnode->data = attr;
00156       newnode->next = head;
00157       head = newnode;
00158    }
00159 
00160    if (mask & GL_ENABLE_BIT) {
00161       struct gl_enable_attrib *attr;
00162       GLuint i;
00163       attr = MALLOC_STRUCT( gl_enable_attrib );
00164       /* Copy enable flags from all other attributes into the enable struct. */
00165       attr->AlphaTest = ctx->Color.AlphaEnabled;
00166       attr->AutoNormal = ctx->Eval.AutoNormal;
00167       attr->Blend = ctx->Color.BlendEnabled;
00168       attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled;
00169       attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
00170       for (i = 0; i < COLORTABLE_MAX; i++) {
00171          attr->ColorTable[i] = ctx->Pixel.ColorTableEnabled[i];
00172       }
00173       attr->Convolution1D = ctx->Pixel.Convolution1DEnabled;
00174       attr->Convolution2D = ctx->Pixel.Convolution2DEnabled;
00175       attr->Separable2D = ctx->Pixel.Separable2DEnabled;
00176       attr->CullFace = ctx->Polygon.CullFlag;
00177       attr->DepthTest = ctx->Depth.Test;
00178       attr->Dither = ctx->Color.DitherFlag;
00179       attr->Fog = ctx->Fog.Enabled;
00180       for (i = 0; i < ctx->Const.MaxLights; i++) {
00181          attr->Light[i] = ctx->Light.Light[i].Enabled;
00182       }
00183       attr->Lighting = ctx->Light.Enabled;
00184       attr->LineSmooth = ctx->Line.SmoothFlag;
00185       attr->LineStipple = ctx->Line.StippleFlag;
00186       attr->Histogram = ctx->Pixel.HistogramEnabled;
00187       attr->MinMax = ctx->Pixel.MinMaxEnabled;
00188       attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
00189       attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
00190       attr->Map1Color4 = ctx->Eval.Map1Color4;
00191       attr->Map1Index = ctx->Eval.Map1Index;
00192       attr->Map1Normal = ctx->Eval.Map1Normal;
00193       attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
00194       attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
00195       attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
00196       attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
00197       attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
00198       attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
00199       MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib));
00200       attr->Map2Color4 = ctx->Eval.Map2Color4;
00201       attr->Map2Index = ctx->Eval.Map2Index;
00202       attr->Map2Normal = ctx->Eval.Map2Normal;
00203       attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
00204       attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
00205       attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
00206       attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
00207       attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
00208       attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
00209       MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib));
00210       attr->Normalize = ctx->Transform.Normalize;
00211       attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped;
00212       attr->PointSmooth = ctx->Point.SmoothFlag;
00213       attr->PointSprite = ctx->Point.PointSprite;
00214       attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
00215       attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
00216       attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
00217       attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
00218       attr->PolygonStipple = ctx->Polygon.StippleFlag;
00219       attr->RescaleNormals = ctx->Transform.RescaleNormals;
00220       attr->Scissor = ctx->Scissor.Enabled;
00221       attr->Stencil = ctx->Stencil.Enabled;
00222       attr->StencilTwoSide = ctx->Stencil.TestTwoSide;
00223       attr->MultisampleEnabled = ctx->Multisample.Enabled;
00224       attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage;
00225       attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne;
00226       attr->SampleCoverage = ctx->Multisample.SampleCoverage;
00227       attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert;
00228       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
00229          attr->Texture[i] = ctx->Texture.Unit[i].Enabled;
00230          attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
00231          attr->TextureColorTable[i] = ctx->Texture.Unit[i].ColorTableEnabled;
00232       }
00233       /* GL_NV_vertex_program */
00234       attr->VertexProgram = ctx->VertexProgram.Enabled;
00235       attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
00236       attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
00237       newnode = new_attrib_node( GL_ENABLE_BIT );
00238       newnode->data = attr;
00239       newnode->next = head;
00240       head = newnode;
00241    }
00242 
00243    if (mask & GL_EVAL_BIT) {
00244       struct gl_eval_attrib *attr;
00245       attr = MALLOC_STRUCT( gl_eval_attrib );
00246       MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
00247       newnode = new_attrib_node( GL_EVAL_BIT );
00248       newnode->data = attr;
00249       newnode->next = head;
00250       head = newnode;
00251    }
00252 
00253    if (mask & GL_FOG_BIT) {
00254       struct gl_fog_attrib *attr;
00255       attr = MALLOC_STRUCT( gl_fog_attrib );
00256       MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
00257       newnode = new_attrib_node( GL_FOG_BIT );
00258       newnode->data = attr;
00259       newnode->next = head;
00260       head = newnode;
00261    }
00262 
00263    if (mask & GL_HINT_BIT) {
00264       struct gl_hint_attrib *attr;
00265       attr = MALLOC_STRUCT( gl_hint_attrib );
00266       MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
00267       newnode = new_attrib_node( GL_HINT_BIT );
00268       newnode->data = attr;
00269       newnode->next = head;
00270       head = newnode;
00271    }
00272 
00273    if (mask & GL_LIGHTING_BIT) {
00274       struct gl_light_attrib *attr;
00275       FLUSH_CURRENT(ctx, 0);    /* flush material changes */
00276       attr = MALLOC_STRUCT( gl_light_attrib );
00277       MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
00278       newnode = new_attrib_node( GL_LIGHTING_BIT );
00279       newnode->data = attr;
00280       newnode->next = head;
00281       head = newnode;
00282    }
00283 
00284    if (mask & GL_LINE_BIT) {
00285       struct gl_line_attrib *attr;
00286       attr = MALLOC_STRUCT( gl_line_attrib );
00287       MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
00288       newnode = new_attrib_node( GL_LINE_BIT );
00289       newnode->data = attr;
00290       newnode->next = head;
00291       head = newnode;
00292    }
00293 
00294    if (mask & GL_LIST_BIT) {
00295       struct gl_list_attrib *attr;
00296       attr = MALLOC_STRUCT( gl_list_attrib );
00297       MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
00298       newnode = new_attrib_node( GL_LIST_BIT );
00299       newnode->data = attr;
00300       newnode->next = head;
00301       head = newnode;
00302    }
00303 
00304    if (mask & GL_PIXEL_MODE_BIT) {
00305       struct gl_pixel_attrib *attr;
00306       attr = MALLOC_STRUCT( gl_pixel_attrib );
00307       MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
00308       /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
00309       attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
00310       newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
00311       newnode->data = attr;
00312       newnode->next = head;
00313       head = newnode;
00314    }
00315 
00316    if (mask & GL_POINT_BIT) {
00317       struct gl_point_attrib *attr;
00318       attr = MALLOC_STRUCT( gl_point_attrib );
00319       MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
00320       newnode = new_attrib_node( GL_POINT_BIT );
00321       newnode->data = attr;
00322       newnode->next = head;
00323       head = newnode;
00324    }
00325 
00326    if (mask & GL_POLYGON_BIT) {
00327       struct gl_polygon_attrib *attr;
00328       attr = MALLOC_STRUCT( gl_polygon_attrib );
00329       MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
00330       newnode = new_attrib_node( GL_POLYGON_BIT );
00331       newnode->data = attr;
00332       newnode->next = head;
00333       head = newnode;
00334    }
00335 
00336    if (mask & GL_POLYGON_STIPPLE_BIT) {
00337       GLuint *stipple;
00338       stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
00339       MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
00340       newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
00341       newnode->data = stipple;
00342       newnode->next = head;
00343       head = newnode;
00344    }
00345 
00346    if (mask & GL_SCISSOR_BIT) {
00347       struct gl_scissor_attrib *attr;
00348       attr = MALLOC_STRUCT( gl_scissor_attrib );
00349       MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
00350       newnode = new_attrib_node( GL_SCISSOR_BIT );
00351       newnode->data = attr;
00352       newnode->next = head;
00353       head = newnode;
00354    }
00355 
00356    if (mask & GL_STENCIL_BUFFER_BIT) {
00357       struct gl_stencil_attrib *attr;
00358       attr = MALLOC_STRUCT( gl_stencil_attrib );
00359       MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
00360       newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
00361       newnode->data = attr;
00362       newnode->next = head;
00363       head = newnode;
00364    }
00365 
00366    if (mask & GL_TEXTURE_BIT) {
00367       struct texture_state *texstate = CALLOC_STRUCT(texture_state);
00368       GLuint u, tex;
00369 
00370       if (!texstate) {
00371          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
00372          goto end;
00373       }
00374 
00375       _mesa_lock_context_textures(ctx);
00376 
00377       /* copy/save the bulk of texture state here */
00378       _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture));
00379 
00380       /* Save references to the currently bound texture objects so they don't
00381        * accidentally get deleted while referenced in the attribute stack.
00382        */
00383       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
00384          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
00385             _mesa_reference_texobj(&texstate->SavedTexRef[u][tex],
00386                                    ctx->Texture.Unit[u].CurrentTex[tex]);
00387          }
00388       }
00389 
00390       /* copy state/contents of the currently bound texture objects */
00391       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
00392          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
00393             _mesa_copy_texture_object(&texstate->SavedObj[u][tex],
00394                                       ctx->Texture.Unit[u].CurrentTex[tex]);
00395          }
00396       }
00397 
00398       _mesa_unlock_context_textures(ctx);
00399 
00400       newnode = new_attrib_node( GL_TEXTURE_BIT );
00401       newnode->data = texstate;
00402       newnode->next = head;
00403       head = newnode;
00404    }
00405 
00406    if (mask & GL_TRANSFORM_BIT) {
00407       struct gl_transform_attrib *attr;
00408       attr = MALLOC_STRUCT( gl_transform_attrib );
00409       MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
00410       newnode = new_attrib_node( GL_TRANSFORM_BIT );
00411       newnode->data = attr;
00412       newnode->next = head;
00413       head = newnode;
00414    }
00415 
00416    if (mask & GL_VIEWPORT_BIT) {
00417       struct gl_viewport_attrib *attr;
00418       attr = MALLOC_STRUCT( gl_viewport_attrib );
00419       MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
00420       newnode = new_attrib_node( GL_VIEWPORT_BIT );
00421       newnode->data = attr;
00422       newnode->next = head;
00423       head = newnode;
00424    }
00425 
00426    /* GL_ARB_multisample */
00427    if (mask & GL_MULTISAMPLE_BIT_ARB) {
00428       struct gl_multisample_attrib *attr;
00429       attr = MALLOC_STRUCT( gl_multisample_attrib );
00430       MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
00431       newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
00432       newnode->data = attr;
00433       newnode->next = head;
00434       head = newnode;
00435    }
00436 
00437 end:
00438    ctx->AttribStack[ctx->AttribStackDepth] = head;
00439    ctx->AttribStackDepth++;
00440 }
00441 
00442 
00443 
00444 static void
00445 pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
00446 {
00447    GLuint i;
00448 
00449 #define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM)      \
00450     if ((VALUE) != (NEWVALUE)) {            \
00451        _mesa_set_enable( ctx, ENUM, (NEWVALUE) );   \
00452     }
00453 
00454    TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
00455    TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
00456 
00457    for (i=0;i<MAX_CLIP_PLANES;i++) {
00458       const GLuint mask = 1 << i;
00459       if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask))
00460       _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i),
00461                (GLboolean) ((enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE));
00462    }
00463 
00464    TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial,
00465                    GL_COLOR_MATERIAL);
00466    TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION],
00467                    enable->ColorTable[COLORTABLE_PRECONVOLUTION],
00468                    GL_COLOR_TABLE);
00469    TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION],
00470                    enable->ColorTable[COLORTABLE_POSTCONVOLUTION],
00471                    GL_POST_CONVOLUTION_COLOR_TABLE);
00472    TEST_AND_UPDATE(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX],
00473                    enable->ColorTable[COLORTABLE_POSTCOLORMATRIX],
00474                    GL_POST_COLOR_MATRIX_COLOR_TABLE);
00475    TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
00476    TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
00477    TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
00478    TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
00479                    GL_CONVOLUTION_1D);
00480    TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D,
00481                    GL_CONVOLUTION_2D);
00482    TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D,
00483                    GL_SEPARABLE_2D);
00484    TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
00485    TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
00486    TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
00487    TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple,
00488                    GL_LINE_STIPPLE);
00489    TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp,
00490                    GL_INDEX_LOGIC_OP);
00491    TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp,
00492                    GL_COLOR_LOGIC_OP);
00493 
00494    TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
00495    TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
00496    TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
00497    TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1,
00498                    GL_MAP1_TEXTURE_COORD_1);
00499    TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2,
00500                    GL_MAP1_TEXTURE_COORD_2);
00501    TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3,
00502                    GL_MAP1_TEXTURE_COORD_3);
00503    TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4,
00504                    GL_MAP1_TEXTURE_COORD_4);
00505    TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3,
00506                    GL_MAP1_VERTEX_3);
00507    TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4,
00508                    GL_MAP1_VERTEX_4);
00509    for (i = 0; i < 16; i++) {
00510       TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i],
00511                       GL_MAP1_VERTEX_ATTRIB0_4_NV + i);
00512    }
00513 
00514    TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
00515    TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
00516    TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
00517    TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1,
00518                    GL_MAP2_TEXTURE_COORD_1);
00519    TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2,
00520                    GL_MAP2_TEXTURE_COORD_2);
00521    TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3,
00522                    GL_MAP2_TEXTURE_COORD_3);
00523    TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4,
00524                    GL_MAP2_TEXTURE_COORD_4);
00525    TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3,
00526                    GL_MAP2_VERTEX_3);
00527    TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4,
00528                    GL_MAP2_VERTEX_4);
00529    for (i = 0; i < 16; i++) {
00530       TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i],
00531                       GL_MAP2_VERTEX_ATTRIB0_4_NV + i);
00532    }
00533 
00534    TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL);
00535    TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
00536    TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals,
00537                    GL_RESCALE_NORMAL_EXT);
00538    TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped,
00539                    enable->RasterPositionUnclipped,
00540                    GL_RASTER_POSITION_UNCLIPPED_IBM);
00541    TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth,
00542                    GL_POINT_SMOOTH);
00543    if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) {
00544       TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite,
00545                       GL_POINT_SPRITE_NV);
00546    }
00547    TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint,
00548                    GL_POLYGON_OFFSET_POINT);
00549    TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine,
00550                    GL_POLYGON_OFFSET_LINE);
00551    TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill,
00552                    GL_POLYGON_OFFSET_FILL);
00553    TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth,
00554                    GL_POLYGON_SMOOTH);
00555    TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple,
00556                    GL_POLYGON_STIPPLE);
00557    TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
00558    TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
00559    if (ctx->Extensions.EXT_stencil_two_side) {
00560       TEST_AND_UPDATE(ctx->Stencil.TestTwoSide, enable->StencilTwoSide, GL_STENCIL_TEST_TWO_SIDE_EXT);
00561    }
00562    TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled,
00563                    GL_MULTISAMPLE_ARB);
00564    TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage,
00565                    enable->SampleAlphaToCoverage,
00566                    GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
00567    TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne,
00568                    enable->SampleAlphaToOne,
00569                    GL_SAMPLE_ALPHA_TO_ONE_ARB);
00570    TEST_AND_UPDATE(ctx->Multisample.SampleCoverage,
00571                    enable->SampleCoverage,
00572                    GL_SAMPLE_COVERAGE_ARB);
00573    TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert,
00574                    enable->SampleCoverageInvert,
00575                    GL_SAMPLE_COVERAGE_INVERT_ARB);
00576    /* GL_ARB_vertex_program, GL_NV_vertex_program */
00577    TEST_AND_UPDATE(ctx->VertexProgram.Enabled,
00578                    enable->VertexProgram,
00579                    GL_VERTEX_PROGRAM_ARB);
00580    TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled,
00581                    enable->VertexProgramPointSize,
00582                    GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
00583    TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled,
00584                    enable->VertexProgramTwoSide,
00585                    GL_VERTEX_PROGRAM_TWO_SIDE_ARB);
00586 
00587 #undef TEST_AND_UPDATE
00588 
00589    /* texture unit enables */
00590    for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
00591       if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) {
00592          ctx->Texture.Unit[i].Enabled = enable->Texture[i];
00593          if (ctx->Driver.Enable) {
00594             if (ctx->Driver.ActiveTexture) {
00595                (*ctx->Driver.ActiveTexture)(ctx, i);
00596             }
00597             (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D,
00598                              (GLboolean) (enable->Texture[i] & TEXTURE_1D_BIT) );
00599             (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D,
00600                              (GLboolean) (enable->Texture[i] & TEXTURE_2D_BIT) );
00601             (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D,
00602                              (GLboolean) (enable->Texture[i] & TEXTURE_3D_BIT) );
00603             if (ctx->Extensions.ARB_texture_cube_map)
00604                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_CUBE_MAP_ARB,
00605                           (GLboolean) (enable->Texture[i] & TEXTURE_CUBE_BIT) );
00606             if (ctx->Extensions.NV_texture_rectangle)
00607                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_RECTANGLE_NV,
00608                           (GLboolean) (enable->Texture[i] & TEXTURE_RECT_BIT) );
00609          }
00610       }
00611 
00612       if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) {
00613          ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i];
00614          if (ctx->Driver.Enable) {
00615             if (ctx->Driver.ActiveTexture) {
00616                (*ctx->Driver.ActiveTexture)(ctx, i);
00617             }
00618             if (enable->TexGen[i] & S_BIT)
00619                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE);
00620             else
00621                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE);
00622             if (enable->TexGen[i] & T_BIT)
00623                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE);
00624             else
00625                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE);
00626             if (enable->TexGen[i] & R_BIT)
00627                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE);
00628             else
00629                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE);
00630             if (enable->TexGen[i] & Q_BIT)
00631                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
00632             else
00633                (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
00634          }
00635       }
00636 
00637       /* GL_SGI_texture_color_table */
00638       ctx->Texture.Unit[i].ColorTableEnabled = enable->TextureColorTable[i];
00639    }
00640 
00641    if (ctx->Driver.ActiveTexture) {
00642       (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit);
00643    }
00644 }
00645 
00646 
00650 static void
00651 pop_texture_group(GLcontext *ctx, struct texture_state *texstate)
00652 {
00653    GLuint u;
00654 
00655    _mesa_lock_context_textures(ctx);
00656 
00657    for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
00658       const struct gl_texture_unit *unit = &texstate->Texture.Unit[u];
00659       GLuint tgt;
00660 
00661       _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u);
00662       _mesa_set_enable(ctx, GL_TEXTURE_1D,
00663                        (unit->Enabled & TEXTURE_1D_BIT) ? GL_TRUE : GL_FALSE);
00664       _mesa_set_enable(ctx, GL_TEXTURE_2D,
00665                        (unit->Enabled & TEXTURE_2D_BIT) ? GL_TRUE : GL_FALSE);
00666       _mesa_set_enable(ctx, GL_TEXTURE_3D,
00667                        (unit->Enabled & TEXTURE_3D_BIT) ? GL_TRUE : GL_FALSE);
00668       if (ctx->Extensions.ARB_texture_cube_map) {
00669          _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB,
00670                      (unit->Enabled & TEXTURE_CUBE_BIT) ? GL_TRUE : GL_FALSE);
00671       }
00672       if (ctx->Extensions.NV_texture_rectangle) {
00673          _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
00674                      (unit->Enabled & TEXTURE_RECT_BIT) ? GL_TRUE : GL_FALSE);
00675       }
00676       if (ctx->Extensions.SGI_texture_color_table) {
00677          _mesa_set_enable(ctx, GL_TEXTURE_COLOR_TABLE_SGI,
00678                           unit->ColorTableEnabled);
00679       }
00680       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
00681       _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
00682       _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS);
00683       _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT);
00684       _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR);
00685       _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ);
00686       _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS);
00687       _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT);
00688       _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR);
00689       _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ);
00690       /* Eye plane done differently to avoid re-transformation */
00691       {
00692          struct gl_texture_unit *destUnit = &ctx->Texture.Unit[u];
00693          COPY_4FV(destUnit->EyePlaneS, unit->EyePlaneS);
00694          COPY_4FV(destUnit->EyePlaneT, unit->EyePlaneT);
00695          COPY_4FV(destUnit->EyePlaneR, unit->EyePlaneR);
00696          COPY_4FV(destUnit->EyePlaneQ, unit->EyePlaneQ);
00697          if (ctx->Driver.TexGen) {
00698             ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->EyePlaneS);
00699             ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->EyePlaneT);
00700             ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->EyePlaneR);
00701             ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->EyePlaneQ);
00702          }
00703       }
00704       _mesa_set_enable(ctx, GL_TEXTURE_GEN_S,
00705                        ((unit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE));
00706       _mesa_set_enable(ctx, GL_TEXTURE_GEN_T,
00707                        ((unit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE));
00708       _mesa_set_enable(ctx, GL_TEXTURE_GEN_R,
00709                        ((unit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE));
00710       _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q,
00711                        ((unit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE));
00712       if (ctx->Extensions.EXT_texture_lod_bias) {
00713          _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
00714                        GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias);
00715       }
00716       if (ctx->Extensions.EXT_texture_env_combine ||
00717           ctx->Extensions.ARB_texture_env_combine) {
00718          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
00719                        unit->Combine.ModeRGB);
00720          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
00721                        unit->Combine.ModeA);
00722          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB,
00723                        unit->Combine.SourceRGB[0]);
00724          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB,
00725                        unit->Combine.SourceRGB[1]);
00726          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB,
00727                        unit->Combine.SourceRGB[2]);
00728          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA,
00729                        unit->Combine.SourceA[0]);
00730          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA,
00731                        unit->Combine.SourceA[1]);
00732          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA,
00733                        unit->Combine.SourceA[2]);
00734          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
00735                        unit->Combine.OperandRGB[0]);
00736          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
00737                        unit->Combine.OperandRGB[1]);
00738          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
00739                        unit->Combine.OperandRGB[2]);
00740          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
00741                        unit->Combine.OperandA[0]);
00742          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
00743                        unit->Combine.OperandA[1]);
00744          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
00745                        unit->Combine.OperandA[2]);
00746          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,
00747                        1 << unit->Combine.ScaleShiftRGB);
00748          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE,
00749                        1 << unit->Combine.ScaleShiftA);
00750       }
00751 
00752       /* Restore texture object state for each target */
00753       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
00754          const struct gl_texture_object *obj = NULL;
00755          GLfloat bordColor[4];
00756          GLenum target;
00757 
00758          obj = &texstate->SavedObj[u][tgt];
00759 
00760          /* don't restore state for unsupported targets to prevent
00761           * raising GL errors.
00762           */
00763          if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB &&
00764              !ctx->Extensions.ARB_texture_cube_map) {
00765             continue;
00766          }
00767          else if (obj->Target == GL_TEXTURE_RECTANGLE_NV &&
00768                   !ctx->Extensions.NV_texture_rectangle) {
00769             continue;
00770          }
00771          else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
00772                    obj->Target == GL_TEXTURE_2D_ARRAY_EXT) &&
00773                   !ctx->Extensions.MESA_texture_array) {
00774             continue;
00775          }
00776 
00777          target = obj->Target;
00778 
00779          _mesa_BindTexture(target, obj->Name);
00780 
00781          bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]);
00782          bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]);
00783          bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]);
00784          bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]);
00785 
00786          _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor);
00787          _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority);
00788          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS);
00789          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT);
00790          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR);
00791          _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter);
00792          _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter);
00793          _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod);
00794          _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod);
00795          _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, obj->LodBias);
00796          _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel);
00797          if (target != GL_TEXTURE_RECTANGLE_ARB)
00798             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel);
00799          if (ctx->Extensions.EXT_texture_filter_anisotropic) {
00800             _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
00801                                 obj->MaxAnisotropy);
00802          }
00803          if (ctx->Extensions.SGIX_shadow) {
00804             _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX,
00805                                 obj->CompareFlag);
00806             _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX,
00807                                 obj->CompareOperator);
00808          }
00809          if (ctx->Extensions.SGIX_shadow_ambient) {
00810             _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX,
00811                                 obj->ShadowAmbient);
00812          }
00813       }
00814 
00815       /* remove saved references to the texture objects */
00816       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
00817          _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
00818       }
00819    }
00820 
00821    _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit);
00822 
00823    _mesa_unlock_context_textures(ctx);
00824 }
00825 
00826 
00827 /*
00828  * This function is kind of long just because we have to call a lot
00829  * of device driver functions to update device driver state.
00830  *
00831  * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions
00832  * in order to restore GL state.  This isn't terribly efficient but it
00833  * ensures that dirty flags and any derived state gets updated correctly.
00834  * We could at least check if the value to restore equals the current value
00835  * and then skip the Mesa call.
00836  */
00837 void GLAPIENTRY
00838 _mesa_PopAttrib(void)
00839 {
00840    struct gl_attrib_node *attr, *next;
00841    GET_CURRENT_CONTEXT(ctx);
00842    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
00843 
00844    if (ctx->AttribStackDepth == 0) {
00845       _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
00846       return;
00847    }
00848 
00849    ctx->AttribStackDepth--;
00850    attr = ctx->AttribStack[ctx->AttribStackDepth];
00851 
00852    while (attr) {
00853 
00854       if (MESA_VERBOSE & VERBOSE_API) {
00855          _mesa_debug(ctx, "glPopAttrib %s\n",
00856                      _mesa_lookup_enum_by_nr(attr->kind));
00857       }
00858 
00859       switch (attr->kind) {
00860          case GL_ACCUM_BUFFER_BIT:
00861             {
00862                const struct gl_accum_attrib *accum;
00863                accum = (const struct gl_accum_attrib *) attr->data;
00864                _mesa_ClearAccum(accum->ClearColor[0],
00865                                 accum->ClearColor[1],
00866                                 accum->ClearColor[2],
00867                                 accum->ClearColor[3]);
00868             }
00869             break;
00870          case GL_COLOR_BUFFER_BIT:
00871             {
00872                const struct gl_colorbuffer_attrib *color;
00873                color = (const struct gl_colorbuffer_attrib *) attr->data;
00874                _mesa_ClearIndex((GLfloat) color->ClearIndex);
00875                _mesa_ClearColor(color->ClearColor[0],
00876                                 color->ClearColor[1],
00877                                 color->ClearColor[2],
00878                                 color->ClearColor[3]);
00879                _mesa_IndexMask(color->IndexMask);
00880                _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0),
00881                                (GLboolean) (color->ColorMask[1] != 0),
00882                                (GLboolean) (color->ColorMask[2] != 0),
00883                                (GLboolean) (color->ColorMask[3] != 0));
00884                {
00885                   /* Need to determine if more than one color output is
00886                    * specified.  If so, call glDrawBuffersARB, else call
00887                    * glDrawBuffer().  This is a subtle, but essential point
00888                    * since GL_FRONT (for example) is illegal for the former
00889                    * function, but legal for the later.
00890                    */
00891                   GLboolean multipleBuffers = GL_FALSE;
00892                   if (ctx->Extensions.ARB_draw_buffers) {
00893                      GLuint i;
00894                      for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) {
00895                         if (color->DrawBuffer[i] != GL_NONE) {
00896                            multipleBuffers = GL_TRUE;
00897                            break;
00898                         }
00899                      }
00900                   }
00901                   /* Call the API_level functions, not _mesa_drawbuffers()
00902                    * since we need to do error checking on the pop'd
00903                    * GL_DRAW_BUFFER.
00904                    * Ex: if GL_FRONT were pushed, but we're popping with a
00905                    * user FBO bound, GL_FRONT will be illegal and we'll need
00906                    * to record that error.  Per OpenGL ARB decision.
00907                    */
00908                   if (multipleBuffers)
00909                      _mesa_DrawBuffersARB(ctx->Const.MaxDrawBuffers,
00910                                           color->DrawBuffer);
00911                   else
00912                      _mesa_DrawBuffer(color->DrawBuffer[0]);
00913                }
00914                _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled);
00915                _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef);
00916                _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled);
00917                _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB,
00918                                           color->BlendDstRGB,
00919                                           color->BlendSrcA,
00920                                           color->BlendDstA);
00921            /* This special case is because glBlendEquationSeparateEXT
00922         * cannot take GL_LOGIC_OP as a parameter.
00923         */
00924            if ( color->BlendEquationRGB == color->BlendEquationA ) {
00925           _mesa_BlendEquation(color->BlendEquationRGB);
00926            }
00927            else {
00928           _mesa_BlendEquationSeparateEXT(color->BlendEquationRGB,
00929                          color->BlendEquationA);
00930            }
00931                _mesa_BlendColor(color->BlendColor[0],
00932                                 color->BlendColor[1],
00933                                 color->BlendColor[2],
00934                                 color->BlendColor[3]);
00935                _mesa_LogicOp(color->LogicOp);
00936                _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP,
00937                                 color->ColorLogicOpEnabled);
00938                _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP,
00939                                 color->IndexLogicOpEnabled);
00940                _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag);
00941             }
00942             break;
00943          case GL_CURRENT_BIT:
00944         FLUSH_CURRENT( ctx, 0 );
00945             MEMCPY( &ctx->Current, attr->data,
00946             sizeof(struct gl_current_attrib) );
00947             break;
00948          case GL_DEPTH_BUFFER_BIT:
00949             {
00950                const struct gl_depthbuffer_attrib *depth;
00951                depth = (const struct gl_depthbuffer_attrib *) attr->data;
00952                _mesa_DepthFunc(depth->Func);
00953                _mesa_ClearDepth(depth->Clear);
00954                _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test);
00955                _mesa_DepthMask(depth->Mask);
00956             }
00957             break;
00958          case GL_ENABLE_BIT:
00959             {
00960                const struct gl_enable_attrib *enable;
00961                enable = (const struct gl_enable_attrib *) attr->data;
00962                pop_enable_group(ctx, enable);
00963            ctx->NewState |= _NEW_ALL;
00964             }
00965             break;
00966          case GL_EVAL_BIT:
00967             MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
00968         ctx->NewState |= _NEW_EVAL;
00969             break;
00970          case GL_FOG_BIT:
00971             {
00972                const struct gl_fog_attrib *fog;
00973                fog = (const struct gl_fog_attrib *) attr->data;
00974                _mesa_set_enable(ctx, GL_FOG, fog->Enabled);
00975                _mesa_Fogfv(GL_FOG_COLOR, fog->Color);
00976                _mesa_Fogf(GL_FOG_DENSITY, fog->Density);
00977                _mesa_Fogf(GL_FOG_START, fog->Start);
00978                _mesa_Fogf(GL_FOG_END, fog->End);
00979                _mesa_Fogf(GL_FOG_INDEX, fog->Index);
00980                _mesa_Fogi(GL_FOG_MODE, fog->Mode);
00981             }
00982             break;
00983          case GL_HINT_BIT:
00984             {
00985                const struct gl_hint_attrib *hint;
00986                hint = (const struct gl_hint_attrib *) attr->data;
00987                _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT,
00988                           hint->PerspectiveCorrection );
00989                _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth);
00990                _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth);
00991                _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth);
00992                _mesa_Hint(GL_FOG_HINT, hint->Fog);
00993                _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT,
00994                           hint->ClipVolumeClipping);
00995                if (ctx->Extensions.ARB_texture_compression)
00996                   _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB,
00997                              hint->TextureCompression);
00998             }
00999             break;
01000          case GL_LIGHTING_BIT:
01001             {
01002                GLuint i;
01003                const struct gl_light_attrib *light;
01004                light = (const struct gl_light_attrib *) attr->data;
01005                /* lighting enable */
01006                _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled);
01007                /* per-light state */
01008                if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
01009                   _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
01010            
01011                for (i = 0; i < ctx->Const.MaxLights; i++) {
01012           const struct gl_light *l = &light->Light[i];
01013                   _mesa_set_enable(ctx, GL_LIGHT0 + i, l->Enabled);
01014           _mesa_light(ctx, i, GL_AMBIENT, l->Ambient);
01015           _mesa_light(ctx, i, GL_DIFFUSE, l->Diffuse);
01016           _mesa_light(ctx, i, GL_SPECULAR, l->Specular );
01017           _mesa_light(ctx, i, GL_POSITION, l->EyePosition);
01018           _mesa_light(ctx, i, GL_SPOT_DIRECTION, l->EyeDirection);
01019           _mesa_light(ctx, i, GL_SPOT_EXPONENT, &l->SpotExponent);
01020           _mesa_light(ctx, i, GL_SPOT_CUTOFF, &l->SpotCutoff);
01021           _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION,
01022                               &l->ConstantAttenuation);
01023           _mesa_light(ctx, i, GL_LINEAR_ATTENUATION,
01024                               &l->LinearAttenuation);
01025           _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION,
01026                               &l->QuadraticAttenuation);
01027                }
01028                /* light model */
01029                _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT,
01030                                   light->Model.Ambient);
01031                _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER,
01032                                  (GLfloat) light->Model.LocalViewer);
01033                _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE,
01034                                  (GLfloat) light->Model.TwoSide);
01035                _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL,
01036                                  (GLfloat) light->Model.ColorControl);
01037                /* shade model */
01038                _mesa_ShadeModel(light->ShadeModel);
01039                /* color material */
01040                _mesa_ColorMaterial(light->ColorMaterialFace,
01041                                    light->ColorMaterialMode);
01042                _mesa_set_enable(ctx, GL_COLOR_MATERIAL,
01043                                 light->ColorMaterialEnabled);
01044                /* materials */
01045                MEMCPY(&ctx->Light.Material, &light->Material,
01046                       sizeof(struct gl_material));
01047             }
01048             break;
01049          case GL_LINE_BIT:
01050             {
01051                const struct gl_line_attrib *line;
01052                line = (const struct gl_line_attrib *) attr->data;
01053                _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag);
01054                _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag);
01055                _mesa_LineStipple(line->StippleFactor, line->StipplePattern);
01056                _mesa_LineWidth(line->Width);
01057             }
01058             break;
01059          case GL_LIST_BIT:
01060             MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
01061             break;
01062          case GL_PIXEL_MODE_BIT:
01063             MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
01064             /* XXX what other pixel state needs to be set by function calls? */
01065             _mesa_ReadBuffer(ctx->Pixel.ReadBuffer);
01066         ctx->NewState |= _NEW_PIXEL;
01067             break;
01068          case GL_POINT_BIT:
01069             {
01070                const struct gl_point_attrib *point;
01071                point = (const struct gl_point_attrib *) attr->data;
01072                _mesa_PointSize(point->Size);
01073                _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag);
01074                if (ctx->Extensions.EXT_point_parameters) {
01075                   _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT,
01076                                          point->Params);
01077                   _mesa_PointParameterf(GL_POINT_SIZE_MIN_EXT,
01078                                         point->MinSize);
01079                   _mesa_PointParameterf(GL_POINT_SIZE_MAX_EXT,
01080                                         point->MaxSize);
01081                   _mesa_PointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_EXT,
01082                                         point->Threshold);
01083                }
01084                if (ctx->Extensions.NV_point_sprite
01085            || ctx->Extensions.ARB_point_sprite) {
01086                   GLuint u;
01087                   for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
01088                      _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV,
01089                                    (GLint) point->CoordReplace[u]);
01090                   }
01091                   _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite);
01092                   if (ctx->Extensions.NV_point_sprite)
01093                      _mesa_PointParameteri(GL_POINT_SPRITE_R_MODE_NV,
01094                                            ctx->Point.SpriteRMode);
01095                   _mesa_PointParameterf(GL_POINT_SPRITE_COORD_ORIGIN,
01096                                         (GLfloat)ctx->Point.SpriteOrigin);
01097                }
01098             }
01099             break;
01100          case GL_POLYGON_BIT:
01101             {
01102                const struct gl_polygon_attrib *polygon;
01103                polygon = (const struct gl_polygon_attrib *) attr->data;
01104                _mesa_CullFace(polygon->CullFaceMode);
01105                _mesa_FrontFace(polygon->FrontFace);
01106                _mesa_PolygonMode(GL_FRONT, polygon->FrontMode);
01107                _mesa_PolygonMode(GL_BACK, polygon->BackMode);
01108                _mesa_PolygonOffset(polygon->OffsetFactor,
01109                                    polygon->OffsetUnits);
01110                _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag);
01111                _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag);
01112                _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag);
01113                _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT,
01114                                 polygon->OffsetPoint);
01115                _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE,
01116                                 polygon->OffsetLine);
01117                _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL,
01118                                 polygon->OffsetFill);
01119             }
01120             break;
01121      case GL_POLYGON_STIPPLE_BIT:
01122         MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
01123         ctx->NewState |= _NEW_POLYGONSTIPPLE;
01124         if (ctx->Driver.PolygonStipple)
01125            ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
01126         break;
01127          case GL_SCISSOR_BIT:
01128             {
01129                const struct gl_scissor_attrib *scissor;
01130                scissor = (const struct gl_scissor_attrib *) attr->data;
01131                _mesa_Scissor(scissor->X, scissor->Y,
01132                              scissor->Width, scissor->Height);
01133                _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled);
01134             }
01135             break;
01136          case GL_STENCIL_BUFFER_BIT:
01137             {
01138                const struct gl_stencil_attrib *stencil;
01139                stencil = (const struct gl_stencil_attrib *) attr->data;
01140                _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
01141                _mesa_ClearStencil(stencil->Clear);
01142                if (ctx->Extensions.EXT_stencil_two_side) {
01143                   _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
01144                                    stencil->TestTwoSide);
01145                   _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
01146                                              ? GL_BACK : GL_FRONT);
01147                }
01148                /* front state */
01149                _mesa_StencilFuncSeparate(GL_FRONT,
01150                                          stencil->Function[0],
01151                                          stencil->Ref[0],
01152                                          stencil->ValueMask[0]);
01153                _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
01154                _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
01155                                        stencil->ZFailFunc[0],
01156                                        stencil->ZPassFunc[0]);
01157                /* back state */
01158                _mesa_StencilFuncSeparate(GL_BACK,
01159                                          stencil->Function[1],
01160                                          stencil->Ref[1],
01161                                          stencil->ValueMask[1]);
01162                _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
01163                _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
01164                                        stencil->ZFailFunc[1],
01165                                        stencil->ZPassFunc[1]);
01166             }
01167             break;
01168          case GL_TRANSFORM_BIT:
01169             {
01170                GLuint i;
01171                const struct gl_transform_attrib *xform;
01172                xform = (const struct gl_transform_attrib *) attr->data;
01173                _mesa_MatrixMode(xform->MatrixMode);
01174                if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
01175                   _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
01176 
01177                /* restore clip planes */
01178                for (i = 0; i < MAX_CLIP_PLANES; i++) {
01179                   const GLuint mask = 1 << 1;
01180                   const GLfloat *eyePlane = xform->EyeUserPlane[i];
01181                   COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane);
01182                   if (xform->ClipPlanesEnabled & mask) {
01183                      _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
01184                   }
01185                   else {
01186                      _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
01187                   }
01188                   if (ctx->Driver.ClipPlane)
01189                      ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane );
01190                }
01191 
01192                /* normalize/rescale */
01193                if (xform->Normalize != ctx->Transform.Normalize)
01194                   _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize);
01195                if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
01196                   _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
01197                                    ctx->Transform.RescaleNormals);
01198             }
01199             break;
01200          case GL_TEXTURE_BIT:
01201             /* Take care of texture object reference counters */
01202             {
01203                struct texture_state *texstate
01204                   = (struct texture_state *) attr->data;
01205                pop_texture_group(ctx, texstate);
01206            ctx->NewState |= _NEW_TEXTURE;
01207             }
01208             break;
01209          case GL_VIEWPORT_BIT:
01210             {
01211                const struct gl_viewport_attrib *vp;
01212                vp = (const struct gl_viewport_attrib *) attr->data;
01213                _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height);
01214                _mesa_DepthRange(vp->Near, vp->Far);
01215             }
01216             break;
01217          case GL_MULTISAMPLE_BIT_ARB:
01218             {
01219                const struct gl_multisample_attrib *ms;
01220                ms = (const struct gl_multisample_attrib *) attr->data;
01221                _mesa_SampleCoverageARB(ms->SampleCoverageValue,
01222                                        ms->SampleCoverageInvert);
01223             }
01224             break;
01225 
01226          default:
01227             _mesa_problem( ctx, "Bad attrib flag in PopAttrib");
01228             break;
01229       }
01230 
01231       next = attr->next;
01232       FREE( attr->data );
01233       FREE( attr );
01234       attr = next;
01235    }
01236 }
01237 
01238 
01243 static void
01244 adjust_buffer_object_ref_counts(struct gl_array_attrib *array, GLint step)
01245 {
01246    GLuint i;
01247    array->ArrayObj->Vertex.BufferObj->RefCount += step;
01248    array->ArrayObj->Normal.BufferObj->RefCount += step;
01249    array->ArrayObj->Color.BufferObj->RefCount += step;
01250    array->ArrayObj->SecondaryColor.BufferObj->RefCount += step;
01251    array->ArrayObj->FogCoord.BufferObj->RefCount += step;
01252    array->ArrayObj->Index.BufferObj->RefCount += step;
01253    array->ArrayObj->EdgeFlag.BufferObj->RefCount += step;
01254    for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++)
01255       array->ArrayObj->TexCoord[i].BufferObj->RefCount += step;
01256    for (i = 0; i < VERT_ATTRIB_MAX; i++)
01257       array->ArrayObj->VertexAttrib[i].BufferObj->RefCount += step;
01258 }
01259 
01260 
01265 static void
01266 copy_pixelstore(GLcontext *ctx,
01267                 struct gl_pixelstore_attrib *dst,
01268                 const struct gl_pixelstore_attrib *src)
01269 {
01270    dst->Alignment = src->Alignment;
01271    dst->RowLength = src->RowLength;
01272    dst->SkipPixels = src->SkipPixels;
01273    dst->SkipRows = src->SkipRows;
01274    dst->ImageHeight = src->ImageHeight;
01275    dst->SkipImages = src->SkipImages;
01276    dst->SwapBytes = src->SwapBytes;
01277    dst->LsbFirst = src->LsbFirst;
01278    dst->ClientStorage = src->ClientStorage;
01279    dst->Invert = src->Invert;
01280    _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
01281 }
01282 
01283 
01284 #define GL_CLIENT_PACK_BIT (1<<20)
01285 #define GL_CLIENT_UNPACK_BIT (1<<21)
01286 
01287 
01288 void GLAPIENTRY
01289 _mesa_PushClientAttrib(GLbitfield mask)
01290 {
01291    struct gl_attrib_node *newnode;
01292    struct gl_attrib_node *head;
01293 
01294    GET_CURRENT_CONTEXT(ctx);
01295    ASSERT_OUTSIDE_BEGIN_END(ctx);
01296 
01297    if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) {
01298       _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
01299       return;
01300    }
01301 
01302    /* Build linked list of attribute nodes which save all attribute
01303     * groups specified by the mask.
01304     */
01305    head = NULL;
01306 
01307    if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
01308       struct gl_pixelstore_attrib *attr;
01309       /* packing attribs */
01310       attr = CALLOC_STRUCT( gl_pixelstore_attrib );
01311       copy_pixelstore(ctx, attr, &ctx->Pack);
01312       newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
01313       newnode->data = attr;
01314       newnode->next = head;
01315       head = newnode;
01316       /* unpacking attribs */
01317       attr = CALLOC_STRUCT( gl_pixelstore_attrib );
01318       copy_pixelstore(ctx, attr, &ctx->Unpack);
01319       newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
01320       newnode->data = attr;
01321       newnode->next = head;
01322       head = newnode;
01323    }
01324 
01325    if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
01326       struct gl_array_attrib *attr;
01327       struct gl_array_object *obj;
01328 
01329       attr = MALLOC_STRUCT( gl_array_attrib );
01330       obj = MALLOC_STRUCT( gl_array_object );
01331 
01332 #if FEATURE_ARB_vertex_buffer_object
01333       /* increment ref counts since we're copying pointers to these objects */
01334       ctx->Array.ArrayBufferObj->RefCount++;
01335       ctx->Array.ElementArrayBufferObj->RefCount++;
01336 #endif
01337 
01338       MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
01339       MEMCPY( obj, ctx->Array.ArrayObj, sizeof(struct gl_array_object) );
01340 
01341       attr->ArrayObj = obj;
01342 
01343       newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
01344       newnode->data = attr;
01345       newnode->next = head;
01346       head = newnode;
01347       /* bump reference counts on buffer objects */
01348       adjust_buffer_object_ref_counts(&ctx->Array, 1);
01349    }
01350 
01351    ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
01352    ctx->ClientAttribStackDepth++;
01353 }
01354 
01355 
01356 
01357 
01358 void GLAPIENTRY
01359 _mesa_PopClientAttrib(void)
01360 {
01361    struct gl_attrib_node *node, *next;
01362 
01363    GET_CURRENT_CONTEXT(ctx);
01364    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
01365 
01366    if (ctx->ClientAttribStackDepth == 0) {
01367       _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
01368       return;
01369    }
01370 
01371    ctx->ClientAttribStackDepth--;
01372    node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
01373 
01374    while (node) {
01375       switch (node->kind) {
01376          case GL_CLIENT_PACK_BIT:
01377             {
01378                struct gl_pixelstore_attrib *store =
01379                   (struct gl_pixelstore_attrib *) node->data;
01380                copy_pixelstore(ctx, &ctx->Pack, store);
01381                _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
01382             }
01383         ctx->NewState |= _NEW_PACKUNPACK;
01384             break;
01385          case GL_CLIENT_UNPACK_BIT:
01386             {
01387                struct gl_pixelstore_attrib *store =
01388                   (struct gl_pixelstore_attrib *) node->data;
01389                copy_pixelstore(ctx, &ctx->Unpack, store);
01390                _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL);
01391             }
01392         ctx->NewState |= _NEW_PACKUNPACK;
01393             break;
01394          case GL_CLIENT_VERTEX_ARRAY_BIT: {
01395         struct gl_array_attrib * data =
01396           (struct gl_array_attrib *) node->data;
01397 
01398             adjust_buffer_object_ref_counts(&ctx->Array, -1);
01399      
01400             ctx->Array.ActiveTexture = data->ActiveTexture;
01401         if (data->LockCount != 0)
01402            _mesa_LockArraysEXT(data->LockFirst, data->LockCount);
01403         else if (ctx->Array.LockCount)
01404            _mesa_UnlockArraysEXT();
01405 
01406         _mesa_BindVertexArrayAPPLE( data->ArrayObj->Name );
01407         
01408 #if FEATURE_ARB_vertex_buffer_object
01409             _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB,
01410                                 data->ArrayBufferObj->Name);
01411             _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
01412                                 data->ElementArrayBufferObj->Name);
01413 #endif
01414 
01415         MEMCPY( ctx->Array.ArrayObj, data->ArrayObj,
01416             sizeof( struct gl_array_object ) );
01417 
01418         FREE( data->ArrayObj );
01419         
01420         /* FIXME: Should some bits in ctx->Array->NewState also be set
01421          * FIXME: here?  It seems like it should be set to inclusive-or
01422          * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
01423          */
01424 
01425         ctx->NewState |= _NEW_ARRAY;
01426             break;
01427      }
01428          default:
01429             _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib");
01430             break;
01431       }
01432 
01433       next = node->next;
01434       FREE( node->data );
01435       FREE( node );
01436       node = next;
01437    }
01438 }
01439 
01440 
01444 void
01445 _mesa_free_attrib_data(GLcontext *ctx)
01446 {
01447    while (ctx->AttribStackDepth > 0) {
01448       struct gl_attrib_node *attr, *next;
01449 
01450       ctx->AttribStackDepth--;
01451       attr = ctx->AttribStack[ctx->AttribStackDepth];
01452 
01453       while (attr) {
01454          if (attr->kind == GL_TEXTURE_BIT) {
01455             struct texture_state *texstate = (struct texture_state*)attr->data;
01456             GLuint u, tgt;
01457             /* clear references to the saved texture objects */
01458             for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
01459                for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
01460                   _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL);
01461                }
01462             }
01463          }
01464          else {
01465             /* any other chunks of state that requires special handling? */
01466          }
01467 
01468          next = attr->next;
01469          _mesa_free(attr->data);
01470          _mesa_free(attr);
01471          attr = next;
01472       }
01473    }
01474 }
01475 
01476 
01477 void _mesa_init_attrib( GLcontext *ctx )
01478 {
01479    /* Renderer and client attribute stacks */
01480    ctx->AttribStackDepth = 0;
01481    ctx->ClientAttribStackDepth = 0;
01482 }

Generated on Sun May 27 2012 04:18:09 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.