VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_attrib.c@ 36300

Last change on this file since 36300 was 31808, checked in by vboxsync, 14 years ago

crOpenGL: resource sharing between contexts

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 58.3 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include <stdio.h>
8#include "state.h"
9#include "state/cr_statetypes.h"
10#include "state_internals.h"
11#include "cr_error.h"
12#include "cr_mem.h"
13
14/**
15 * \mainpage state_tracker
16 *
17 * \section StateTrackerIntroduction Introduction
18 *
19 * Chromium consists of all the top-level files in the cr
20 * directory. The state_tracker module basically takes care of API dispatch,
21 * and OpenGL state management.
22 *
23 *
24 */
25void crStateAttribInit (CRAttribState *a)
26{
27 int i;
28 a->attribStackDepth = 0;
29 a->accumBufferStackDepth = 0;
30 a->colorBufferStackDepth = 0;
31 a->currentStackDepth = 0;
32 a->depthBufferStackDepth = 0;
33 a->enableStackDepth = 0;
34 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
35 {
36 a->enableStack[i].clip = NULL;
37 a->enableStack[i].light = NULL;
38 a->lightingStack[i].light = NULL;
39 a->transformStack[i].clip = NULL;
40 a->transformStack[i].clipPlane = NULL;
41 }
42 a->evalStackDepth = 0;
43 a->fogStackDepth = 0;
44 a->lightingStackDepth = 0;
45 a->lineStackDepth = 0;
46 a->listStackDepth = 0;
47 a->pixelModeStackDepth = 0;
48 a->pointStackDepth = 0;
49 a->polygonStackDepth = 0;
50 a->polygonStippleStackDepth = 0;
51 a->scissorStackDepth = 0;
52 a->stencilBufferStackDepth = 0;
53 a->textureStackDepth = 0;
54 a->transformStackDepth = 0;
55 a->viewportStackDepth = 0;
56}
57
58/*@todo check if NV rect needed too*/
59static void
60copy_texunit(CRTextureUnit *dest, const CRTextureUnit *src)
61{
62 dest->enabled1D = src->enabled1D;
63 dest->enabled2D = src->enabled2D;
64 dest->enabled3D = src->enabled3D;
65 dest->enabledCubeMap = src->enabledCubeMap;
66 dest->envMode = src->envMode;
67 dest->envColor = src->envColor;
68 dest->textureGen = src->textureGen;
69 dest->objSCoeff = src->objSCoeff;
70 dest->objTCoeff = src->objTCoeff;
71 dest->objRCoeff = src->objRCoeff;
72 dest->objQCoeff = src->objQCoeff;
73 dest->eyeSCoeff = src->eyeSCoeff;
74 dest->eyeTCoeff = src->eyeTCoeff;
75 dest->eyeRCoeff = src->eyeRCoeff;
76 dest->eyeQCoeff = src->eyeQCoeff;
77 dest->gen = src->gen;
78 dest->currentTexture1D = src->currentTexture1D;
79 dest->currentTexture2D = src->currentTexture2D;
80 dest->currentTexture3D = src->currentTexture3D;
81 dest->currentTextureCubeMap = src->currentTextureCubeMap;
82}
83
84static void
85copy_texobj(CRTextureObj *dest, CRTextureObj *src, GLboolean copyName)
86{
87 if (copyName)
88 {
89 dest->id = src->id;
90 dest->hwid = crStateGetTextureObjHWID(src);
91 }
92
93 dest->borderColor = src->borderColor;
94 dest->wrapS = src->wrapS;
95 dest->wrapT = src->wrapT;
96 dest->minFilter = src->minFilter;
97 dest->magFilter = src->magFilter;
98#ifdef CR_OPENGL_VERSION_1_2
99 dest->priority = src->priority;
100 dest->wrapR = src->wrapR;
101 dest->minLod = src->minLod;
102 dest->maxLod = src->maxLod;
103 dest->baseLevel = src->baseLevel;
104 dest->maxLevel = src->maxLevel;
105#endif
106#ifdef CR_EXT_texture_filter_anisotropic
107 dest->maxAnisotropy = src->maxAnisotropy;
108#endif
109}
110
111void STATE_APIENTRY crStatePushAttrib(GLbitfield mask)
112{
113 CRContext *g = GetCurrentContext();
114 CRAttribState *a = &(g->attrib);
115 CRStateBits *sb = GetCurrentBits();
116 CRAttribBits *ab = &(sb->attrib);
117 unsigned int i;
118
119 if (g->current.inBeginEnd)
120 {
121 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glPushAttrib called in Begin/End");
122 return;
123 }
124
125 if (a->attribStackDepth == CR_MAX_ATTRIB_STACK_DEPTH - 1)
126 {
127 crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW, "glPushAttrib called with a full stack!" );
128 return;
129 }
130
131 FLUSH();
132
133 a->pushMaskStack[a->attribStackDepth++] = mask;
134
135 if (mask & GL_ACCUM_BUFFER_BIT)
136 {
137 a->accumBufferStack[a->accumBufferStackDepth].accumClearValue = g->buffer.accumClearValue;
138 a->accumBufferStackDepth++;
139 }
140 if (mask & GL_COLOR_BUFFER_BIT)
141 {
142 a->colorBufferStack[a->colorBufferStackDepth].alphaTest = g->buffer.alphaTest;
143 a->colorBufferStack[a->colorBufferStackDepth].alphaTestFunc = g->buffer.alphaTestFunc;
144 a->colorBufferStack[a->colorBufferStackDepth].alphaTestRef = g->buffer.alphaTestRef;
145 a->colorBufferStack[a->colorBufferStackDepth].blend = g->buffer.blend;
146 a->colorBufferStack[a->colorBufferStackDepth].blendSrcRGB = g->buffer.blendSrcRGB;
147 a->colorBufferStack[a->colorBufferStackDepth].blendDstRGB = g->buffer.blendDstRGB;
148#if defined(CR_EXT_blend_func_separate)
149 a->colorBufferStack[a->colorBufferStackDepth].blendSrcA = g->buffer.blendSrcA;
150 a->colorBufferStack[a->colorBufferStackDepth].blendDstA = g->buffer.blendDstA;
151#endif
152#ifdef CR_EXT_blend_color
153 a->colorBufferStack[a->colorBufferStackDepth].blendColor = g->buffer.blendColor;
154#endif
155#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
156 a->colorBufferStack[a->colorBufferStackDepth].blendEquation = g->buffer.blendEquation;
157#endif
158 a->colorBufferStack[a->colorBufferStackDepth].dither = g->buffer.dither;
159 a->colorBufferStack[a->colorBufferStackDepth].drawBuffer = g->buffer.drawBuffer;
160 a->colorBufferStack[a->colorBufferStackDepth].logicOp = g->buffer.logicOp;
161 a->colorBufferStack[a->colorBufferStackDepth].indexLogicOp = g->buffer.indexLogicOp;
162 a->colorBufferStack[a->colorBufferStackDepth].logicOpMode = g->buffer.logicOpMode;
163 a->colorBufferStack[a->colorBufferStackDepth].colorClearValue = g->buffer.colorClearValue;
164 a->colorBufferStack[a->colorBufferStackDepth].indexClearValue = g->buffer.indexClearValue;
165 a->colorBufferStack[a->colorBufferStackDepth].colorWriteMask = g->buffer.colorWriteMask;
166 a->colorBufferStack[a->colorBufferStackDepth].indexWriteMask = g->buffer.indexWriteMask;
167 a->colorBufferStackDepth++;
168 }
169 if (mask & GL_CURRENT_BIT)
170 {
171 for (i = 0 ; i < CR_MAX_VERTEX_ATTRIBS ; i++)
172 {
173 COPY_4V(a->currentStack[a->currentStackDepth].attrib[i] , g->current.vertexAttrib[i]);
174 COPY_4V(a->currentStack[a->currentStackDepth].rasterAttrib[i] , g->current.rasterAttrib[i]);
175 }
176 a->currentStack[a->currentStackDepth].rasterValid = g->current.rasterValid;
177 a->currentStack[a->currentStackDepth].edgeFlag = g->current.edgeFlag;
178 a->currentStack[a->currentStackDepth].colorIndex = g->current.colorIndex;
179 a->currentStackDepth++;
180 }
181 if (mask & GL_DEPTH_BUFFER_BIT)
182 {
183 a->depthBufferStack[a->depthBufferStackDepth].depthTest = g->buffer.depthTest;
184 a->depthBufferStack[a->depthBufferStackDepth].depthFunc = g->buffer.depthFunc;
185 a->depthBufferStack[a->depthBufferStackDepth].depthClearValue = g->buffer.depthClearValue;
186 a->depthBufferStack[a->depthBufferStackDepth].depthMask = g->buffer.depthMask;
187 a->depthBufferStackDepth++;
188 }
189 if (mask & GL_ENABLE_BIT)
190 {
191 if (a->enableStack[a->enableStackDepth].clip == NULL)
192 {
193 a->enableStack[a->enableStackDepth].clip = (GLboolean *) crCalloc( g->limits.maxClipPlanes * sizeof( GLboolean ));
194 }
195 if (a->enableStack[a->enableStackDepth].light == NULL)
196 {
197 a->enableStack[a->enableStackDepth].light = (GLboolean *) crCalloc( g->limits.maxLights * sizeof( GLboolean ));
198 }
199 a->enableStack[a->enableStackDepth].alphaTest = g->buffer.alphaTest;
200 a->enableStack[a->enableStackDepth].autoNormal = g->eval.autoNormal;
201 a->enableStack[a->enableStackDepth].blend = g->buffer.blend;
202 for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
203 {
204 a->enableStack[a->enableStackDepth].clip[i] = g->transform.clip[i];
205 }
206 a->enableStack[a->enableStackDepth].colorMaterial = g->lighting.colorMaterial;
207 a->enableStack[a->enableStackDepth].cullFace = g->polygon.cullFace;
208 a->enableStack[a->enableStackDepth].depthTest = g->buffer.depthTest;
209 a->enableStack[a->enableStackDepth].dither = g->buffer.dither;
210 a->enableStack[a->enableStackDepth].fog = g->fog.enable;
211 for (i = 0 ; i < g->limits.maxLights ; i++)
212 {
213 a->enableStack[a->enableStackDepth].light[i] = g->lighting.light[i].enable;
214 }
215 a->enableStack[a->enableStackDepth].lighting = g->lighting.lighting;
216 a->enableStack[a->enableStackDepth].lineSmooth = g->line.lineSmooth;
217 a->enableStack[a->enableStackDepth].lineStipple = g->line.lineStipple;
218 a->enableStack[a->enableStackDepth].logicOp = g->buffer.logicOp;
219 a->enableStack[a->enableStackDepth].indexLogicOp = g->buffer.indexLogicOp;
220 for (i = 0 ; i < GLEVAL_TOT ; i++)
221 {
222 a->enableStack[a->enableStackDepth].map1[i] = g->eval.enable1D[i];
223 a->enableStack[a->enableStackDepth].map2[i] = g->eval.enable2D[i];
224 }
225 a->enableStack[a->enableStackDepth].normalize = g->transform.normalize;
226 a->enableStack[a->enableStackDepth].pointSmooth = g->point.pointSmooth;
227#if CR_ARB_point_sprite
228 a->enableStack[a->enableStackDepth].pointSprite = g->point.pointSprite;
229 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
230 a->enableStack[a->enableStackDepth].coordReplacement[i] = g->point.coordReplacement[i];
231#endif
232 a->enableStack[a->enableStackDepth].polygonOffsetLine = g->polygon.polygonOffsetLine;
233 a->enableStack[a->enableStackDepth].polygonOffsetFill = g->polygon.polygonOffsetFill;
234 a->enableStack[a->enableStackDepth].polygonOffsetPoint = g->polygon.polygonOffsetPoint;
235 a->enableStack[a->enableStackDepth].polygonSmooth = g->polygon.polygonSmooth;
236 a->enableStack[a->enableStackDepth].polygonStipple = g->polygon.polygonStipple;
237#ifdef CR_OPENGL_VERSION_1_2
238 a->enableStack[a->enableStackDepth].rescaleNormals = g->transform.rescaleNormals;
239#endif
240 a->enableStack[a->enableStackDepth].scissorTest = g->viewport.scissorTest;
241 a->enableStack[a->enableStackDepth].stencilTest = g->stencil.stencilTest;
242 for (i = 0 ; i < g->limits.maxTextureUnits; i++)
243 {
244 a->enableStack[a->enableStackDepth].texture1D[i] = g->texture.unit[i].enabled1D;
245 a->enableStack[a->enableStackDepth].texture2D[i] = g->texture.unit[i].enabled2D;
246#ifdef CR_OPENGL_VERSION_1_2
247 a->enableStack[a->enableStackDepth].texture3D[i] = g->texture.unit[i].enabled3D;
248#endif
249#ifdef CR_ARB_texture_cube_map
250 a->enableStack[a->enableStackDepth].textureCubeMap[i] = g->texture.unit[i].enabledCubeMap;
251#endif
252#ifdef CR_NV_texture_rectangle
253 a->enableStack[a->enableStackDepth].textureRect[i] = g->texture.unit[i].enabledRect;
254#endif
255 a->enableStack[a->enableStackDepth].textureGenS[i] = g->texture.unit[i].textureGen.s;
256 a->enableStack[a->enableStackDepth].textureGenT[i] = g->texture.unit[i].textureGen.t;
257 a->enableStack[a->enableStackDepth].textureGenR[i] = g->texture.unit[i].textureGen.r;
258 a->enableStack[a->enableStackDepth].textureGenQ[i] = g->texture.unit[i].textureGen.q;
259 }
260 a->enableStackDepth++;
261 }
262 if (mask & GL_EVAL_BIT)
263 {
264 for (i = 0 ; i < GLEVAL_TOT ; i++)
265 {
266 int size1 = g->eval.eval1D[i].order * gleval_sizes[i] *
267 sizeof (GLfloat);
268 int size2 = g->eval.eval2D[i].uorder * g->eval.eval2D[i].vorder *
269 gleval_sizes[i] * sizeof (GLfloat);
270 a->evalStack[a->evalStackDepth].enable1D[i] = g->eval.enable1D[i];
271 a->evalStack[a->evalStackDepth].enable2D[i] = g->eval.enable2D[i];
272 a->evalStack[a->evalStackDepth].eval1D[i].u1 = g->eval.eval1D[i].u1;
273 a->evalStack[a->evalStackDepth].eval1D[i].u2 = g->eval.eval1D[i].u2;
274 a->evalStack[a->evalStackDepth].eval1D[i].order = g->eval.eval1D[i].order;
275 a->evalStack[a->evalStackDepth].eval1D[i].coeff = (GLfloat*)crCalloc(size1);
276 crMemcpy(a->evalStack[a->evalStackDepth].eval1D[i].coeff, g->eval.eval1D[i].coeff, size1);
277 a->evalStack[a->evalStackDepth].eval2D[i].u1 = g->eval.eval2D[i].u1;
278 a->evalStack[a->evalStackDepth].eval2D[i].u2 = g->eval.eval2D[i].u2;
279 a->evalStack[a->evalStackDepth].eval2D[i].v1 = g->eval.eval2D[i].v1;
280 a->evalStack[a->evalStackDepth].eval2D[i].v2 = g->eval.eval2D[i].v2;
281 a->evalStack[a->evalStackDepth].eval2D[i].uorder = g->eval.eval2D[i].uorder;
282 a->evalStack[a->evalStackDepth].eval2D[i].vorder = g->eval.eval2D[i].vorder;
283 a->evalStack[a->evalStackDepth].eval2D[i].coeff = (GLfloat*)crCalloc(size2);
284 crMemcpy(a->evalStack[a->evalStackDepth].eval2D[i].coeff, g->eval.eval2D[i].coeff, size2);
285 }
286 a->evalStack[a->evalStackDepth].autoNormal = g->eval.autoNormal;
287 a->evalStack[a->evalStackDepth].un1D = g->eval.un1D;
288 a->evalStack[a->evalStackDepth].u11D = g->eval.u11D;
289 a->evalStack[a->evalStackDepth].u21D = g->eval.u21D;
290 a->evalStack[a->evalStackDepth].un2D = g->eval.un2D;
291 a->evalStack[a->evalStackDepth].u12D = g->eval.u12D;
292 a->evalStack[a->evalStackDepth].u22D = g->eval.u22D;
293 a->evalStack[a->evalStackDepth].vn2D = g->eval.vn2D;
294 a->evalStack[a->evalStackDepth].v12D = g->eval.v12D;
295 a->evalStack[a->evalStackDepth].v22D = g->eval.v22D;
296 a->evalStackDepth++;
297 }
298 if (mask & GL_FOG_BIT)
299 {
300 a->fogStack[a->fogStackDepth].enable = g->fog.enable;
301 a->fogStack[a->fogStackDepth].color = g->fog.color;
302 a->fogStack[a->fogStackDepth].density = g->fog.density;
303 a->fogStack[a->fogStackDepth].start = g->fog.start;
304 a->fogStack[a->fogStackDepth].end = g->fog.end;
305 a->fogStack[a->fogStackDepth].index = g->fog.index;
306 a->fogStack[a->fogStackDepth].mode = g->fog.mode;
307 a->fogStackDepth++;
308 }
309 if (mask & GL_HINT_BIT)
310 {
311 a->hintStack[a->hintStackDepth].perspectiveCorrection = g->hint.perspectiveCorrection;
312 a->hintStack[a->hintStackDepth].pointSmooth = g->hint.pointSmooth;
313 a->hintStack[a->hintStackDepth].lineSmooth = g->hint.lineSmooth;
314 a->hintStack[a->hintStackDepth].polygonSmooth = g->hint.polygonSmooth;
315 a->hintStack[a->hintStackDepth].fog = g->hint.fog;
316#ifdef CR_EXT_clip_volume_hint
317 a->hintStack[a->hintStackDepth].clipVolumeClipping = g->hint.clipVolumeClipping;
318#endif
319#ifdef CR_ARB_texture_compression
320 a->hintStack[a->hintStackDepth].textureCompression = g->hint.textureCompression;
321#endif
322#ifdef CR_SGIS_generate_mipmap
323 a->hintStack[a->hintStackDepth].generateMipmap = g->hint.generateMipmap;
324#endif
325 a->hintStackDepth++;
326 }
327 if (mask & GL_LIGHTING_BIT)
328 {
329 if (a->lightingStack[a->lightingStackDepth].light == NULL)
330 {
331 a->lightingStack[a->lightingStackDepth].light = (CRLight *) crCalloc( g->limits.maxLights * sizeof( CRLight ));
332 }
333 a->lightingStack[a->lightingStackDepth].lightModelAmbient = g->lighting.lightModelAmbient;
334 a->lightingStack[a->lightingStackDepth].lightModelLocalViewer = g->lighting.lightModelLocalViewer;
335 a->lightingStack[a->lightingStackDepth].lightModelTwoSide = g->lighting.lightModelTwoSide;
336#if defined(CR_EXT_separate_specular_color) || defined(CR_OPENGL_VERSION_1_2)
337 a->lightingStack[a->lightingStackDepth].lightModelColorControlEXT = g->lighting.lightModelColorControlEXT;
338#endif
339 a->lightingStack[a->lightingStackDepth].lighting = g->lighting.lighting;
340 a->lightingStack[a->lightingStackDepth].colorMaterial = g->lighting.colorMaterial;
341 a->lightingStack[a->lightingStackDepth].colorMaterialMode = g->lighting.colorMaterialMode;
342 a->lightingStack[a->lightingStackDepth].colorMaterialFace = g->lighting.colorMaterialFace;
343 for (i = 0 ; i < g->limits.maxLights; i++)
344 {
345 a->lightingStack[a->lightingStackDepth].light[i].enable = g->lighting.light[i].enable;
346 a->lightingStack[a->lightingStackDepth].light[i].ambient = g->lighting.light[i].ambient;
347 a->lightingStack[a->lightingStackDepth].light[i].diffuse = g->lighting.light[i].diffuse;
348 a->lightingStack[a->lightingStackDepth].light[i].specular = g->lighting.light[i].specular;
349 a->lightingStack[a->lightingStackDepth].light[i].spotDirection = g->lighting.light[i].spotDirection;
350 a->lightingStack[a->lightingStackDepth].light[i].position = g->lighting.light[i].position;
351 a->lightingStack[a->lightingStackDepth].light[i].spotExponent = g->lighting.light[i].spotExponent;
352 a->lightingStack[a->lightingStackDepth].light[i].spotCutoff = g->lighting.light[i].spotCutoff;
353 a->lightingStack[a->lightingStackDepth].light[i].constantAttenuation = g->lighting.light[i].constantAttenuation;
354 a->lightingStack[a->lightingStackDepth].light[i].linearAttenuation = g->lighting.light[i].linearAttenuation;
355 a->lightingStack[a->lightingStackDepth].light[i].quadraticAttenuation = g->lighting.light[i].quadraticAttenuation;
356 }
357 for (i = 0 ; i < 2 ; i++)
358 {
359 a->lightingStack[a->lightingStackDepth].ambient[i] = g->lighting.ambient[i];
360 a->lightingStack[a->lightingStackDepth].diffuse[i] = g->lighting.diffuse[i];
361 a->lightingStack[a->lightingStackDepth].specular[i] = g->lighting.specular[i];
362 a->lightingStack[a->lightingStackDepth].emission[i] = g->lighting.emission[i];
363 a->lightingStack[a->lightingStackDepth].shininess[i] = g->lighting.shininess[i];
364 a->lightingStack[a->lightingStackDepth].indexes[i][0] = g->lighting.indexes[i][0];
365 a->lightingStack[a->lightingStackDepth].indexes[i][1] = g->lighting.indexes[i][1];
366 a->lightingStack[a->lightingStackDepth].indexes[i][2] = g->lighting.indexes[i][2];
367 }
368 a->lightingStack[a->lightingStackDepth].shadeModel = g->lighting.shadeModel;
369 a->lightingStackDepth++;
370 }
371 if (mask & GL_LINE_BIT)
372 {
373 a->lineStack[a->lineStackDepth].lineSmooth = g->line.lineSmooth;
374 a->lineStack[a->lineStackDepth].lineStipple = g->line.lineStipple;
375 a->lineStack[a->lineStackDepth].pattern = g->line.pattern;
376 a->lineStack[a->lineStackDepth].repeat = g->line.repeat;
377 a->lineStack[a->lineStackDepth].width = g->line.width;
378 a->lineStackDepth++;
379 }
380 if (mask & GL_LIST_BIT)
381 {
382 a->listStack[a->listStackDepth].base = g->lists.base;
383 a->listStackDepth++;
384 }
385 if (mask & GL_PIXEL_MODE_BIT)
386 {
387 a->pixelModeStack[a->pixelModeStackDepth].bias = g->pixel.bias;
388 a->pixelModeStack[a->pixelModeStackDepth].scale = g->pixel.scale;
389 a->pixelModeStack[a->pixelModeStackDepth].indexOffset = g->pixel.indexOffset;
390 a->pixelModeStack[a->pixelModeStackDepth].indexShift = g->pixel.indexShift;
391 a->pixelModeStack[a->pixelModeStackDepth].mapColor = g->pixel.mapColor;
392 a->pixelModeStack[a->pixelModeStackDepth].mapStencil = g->pixel.mapStencil;
393 a->pixelModeStack[a->pixelModeStackDepth].xZoom = g->pixel.xZoom;
394 a->pixelModeStack[a->pixelModeStackDepth].yZoom = g->pixel.yZoom;
395 a->pixelModeStack[a->pixelModeStackDepth].readBuffer = g->buffer.readBuffer;
396 a->pixelModeStackDepth++;
397 }
398 if (mask & GL_POINT_BIT)
399 {
400 a->pointStack[a->pointStackDepth].pointSmooth = g->point.pointSmooth;
401#if CR_ARB_point_sprite
402 a->pointStack[a->pointStackDepth].pointSprite = g->point.pointSprite;
403 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
404 a->pointStack[a->enableStackDepth].coordReplacement[i] = g->point.coordReplacement[i];
405#endif
406 a->pointStack[a->pointStackDepth].pointSize = g->point.pointSize;
407 a->pointStackDepth++;
408 }
409 if (mask & GL_POLYGON_BIT)
410 {
411 a->polygonStack[a->polygonStackDepth].cullFace = g->polygon.cullFace;
412 a->polygonStack[a->polygonStackDepth].cullFaceMode = g->polygon.cullFaceMode;
413 a->polygonStack[a->polygonStackDepth].frontFace = g->polygon.frontFace;
414 a->polygonStack[a->polygonStackDepth].frontMode = g->polygon.frontMode;
415 a->polygonStack[a->polygonStackDepth].backMode = g->polygon.backMode;
416 a->polygonStack[a->polygonStackDepth].polygonSmooth = g->polygon.polygonSmooth;
417 a->polygonStack[a->polygonStackDepth].polygonStipple = g->polygon.polygonStipple;
418 a->polygonStack[a->polygonStackDepth].polygonOffsetFill = g->polygon.polygonOffsetFill;
419 a->polygonStack[a->polygonStackDepth].polygonOffsetLine = g->polygon.polygonOffsetLine;
420 a->polygonStack[a->polygonStackDepth].polygonOffsetPoint = g->polygon.polygonOffsetPoint;
421 a->polygonStack[a->polygonStackDepth].offsetFactor = g->polygon.offsetFactor;
422 a->polygonStack[a->polygonStackDepth].offsetUnits = g->polygon.offsetUnits;
423 a->polygonStackDepth++;
424 }
425 if (mask & GL_POLYGON_STIPPLE_BIT)
426 {
427 crMemcpy( a->polygonStippleStack[a->polygonStippleStackDepth].pattern, g->polygon.stipple, 32*sizeof(GLint) );
428 a->polygonStippleStackDepth++;
429 }
430 if (mask & GL_SCISSOR_BIT)
431 {
432 a->scissorStack[a->scissorStackDepth].scissorTest = g->viewport.scissorTest;
433 a->scissorStack[a->scissorStackDepth].scissorX = g->viewport.scissorX;
434 a->scissorStack[a->scissorStackDepth].scissorY = g->viewport.scissorY;
435 a->scissorStack[a->scissorStackDepth].scissorW = g->viewport.scissorW;
436 a->scissorStack[a->scissorStackDepth].scissorH = g->viewport.scissorH;
437 a->scissorStackDepth++;
438 }
439 if (mask & GL_STENCIL_BUFFER_BIT)
440 {
441 a->stencilBufferStack[a->stencilBufferStackDepth].stencilTest = g->stencil.stencilTest;
442 a->stencilBufferStack[a->stencilBufferStackDepth].func = g->stencil.func;
443 a->stencilBufferStack[a->stencilBufferStackDepth].mask = g->stencil.mask;
444 a->stencilBufferStack[a->stencilBufferStackDepth].ref = g->stencil.ref;
445 a->stencilBufferStack[a->stencilBufferStackDepth].fail = g->stencil.fail;
446 a->stencilBufferStack[a->stencilBufferStackDepth].passDepthFail = g->stencil.passDepthFail;
447 a->stencilBufferStack[a->stencilBufferStackDepth].passDepthPass = g->stencil.passDepthPass;
448 a->stencilBufferStack[a->stencilBufferStackDepth].clearValue = g->stencil.clearValue;
449 a->stencilBufferStack[a->stencilBufferStackDepth].writeMask = g->stencil.writeMask;
450 a->stencilBufferStackDepth++;
451 }
452 if (mask & GL_TEXTURE_BIT)
453 {
454 CRTextureStack *tState = a->textureStack + a->textureStackDepth;
455 tState->curTextureUnit = g->texture.curTextureUnit;
456 for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
457 {
458 /* per-unit state */
459 copy_texunit(&tState->unit[i], &g->texture.unit[i]);
460 /* texture object state */
461 copy_texobj(&tState->unit[i].Saved1D, g->texture.unit[i].currentTexture1D, GL_TRUE);
462 copy_texobj(&tState->unit[i].Saved2D, g->texture.unit[i].currentTexture2D, GL_TRUE);
463#ifdef CR_OPENGL_VERSION_1_2
464 copy_texobj(&tState->unit[i].Saved3D, g->texture.unit[i].currentTexture3D, GL_TRUE);
465#endif
466#ifdef CR_ARB_texture_cube_map
467 copy_texobj(&tState->unit[i].SavedCubeMap, g->texture.unit[i].currentTextureCubeMap, GL_TRUE);
468#endif
469#ifdef CR_NV_texture_rectangle
470 copy_texobj(&tState->unit[i].SavedRect, g->texture.unit[i].currentTextureRect, GL_TRUE);
471#endif
472 }
473 a->textureStackDepth++;
474 }
475 if (mask & GL_TRANSFORM_BIT)
476 {
477 if (a->transformStack[a->transformStackDepth].clip == NULL)
478 {
479 a->transformStack[a->transformStackDepth].clip = (GLboolean *) crCalloc( g->limits.maxClipPlanes * sizeof( GLboolean ));
480 }
481 if (a->transformStack[a->transformStackDepth].clipPlane == NULL)
482 {
483 a->transformStack[a->transformStackDepth].clipPlane = (GLvectord *) crCalloc( g->limits.maxClipPlanes * sizeof( GLvectord ));
484 }
485 a->transformStack[a->transformStackDepth].matrixMode = g->transform.matrixMode;
486 for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
487 {
488 a->transformStack[a->transformStackDepth].clip[i] = g->transform.clip[i];
489 a->transformStack[a->transformStackDepth].clipPlane[i] = g->transform.clipPlane[i];
490 }
491 a->transformStack[a->transformStackDepth].normalize = g->transform.normalize;
492#ifdef CR_OPENGL_VERSION_1_2
493 a->transformStack[a->transformStackDepth].rescaleNormals = g->transform.rescaleNormals;
494#endif
495 a->transformStackDepth++;
496 }
497 if (mask & GL_VIEWPORT_BIT)
498 {
499 a->viewportStack[a->viewportStackDepth].viewportX = g->viewport.viewportX;
500 a->viewportStack[a->viewportStackDepth].viewportY = g->viewport.viewportY;
501 a->viewportStack[a->viewportStackDepth].viewportW = g->viewport.viewportW;
502 a->viewportStack[a->viewportStackDepth].viewportH = g->viewport.viewportH;
503 a->viewportStack[a->viewportStackDepth].nearClip = g->viewport.nearClip;
504 a->viewportStack[a->viewportStackDepth].farClip = g->viewport.farClip;
505 a->viewportStackDepth++;
506 }
507
508 DIRTY(ab->dirty, g->neg_bitid);
509}
510
511void STATE_APIENTRY crStatePopAttrib(void)
512{
513 CRContext *g = GetCurrentContext();
514 CRAttribState *a = &(g->attrib);
515 CRStateBits *sb = GetCurrentBits();
516 CRAttribBits *ab = &(sb->attrib);
517 CRbitvalue mask;
518 unsigned int i;
519
520 if (g->current.inBeginEnd)
521 {
522 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glPopAttrib called in Begin/End");
523 return;
524 }
525
526 if (a->attribStackDepth == 0)
527 {
528 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty stack!" );
529 return;
530 }
531
532 FLUSH();
533
534 mask = a->pushMaskStack[--a->attribStackDepth];
535
536 if (mask & GL_ACCUM_BUFFER_BIT)
537 {
538 if (a->accumBufferStackDepth == 0)
539 {
540 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty accum buffer stack!" );
541 return;
542 }
543 a->accumBufferStackDepth--;
544 g->buffer.accumClearValue = a->accumBufferStack[a->accumBufferStackDepth].accumClearValue;
545 DIRTY(sb->buffer.dirty, g->neg_bitid);
546 DIRTY(sb->buffer.clearAccum, g->neg_bitid);
547 }
548 if (mask & GL_COLOR_BUFFER_BIT)
549 {
550 if (a->colorBufferStackDepth == 0)
551 {
552 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty color buffer stack!" );
553 return;
554 }
555 a->colorBufferStackDepth--;
556 g->buffer.alphaTest = a->colorBufferStack[a->colorBufferStackDepth].alphaTest;
557 g->buffer.alphaTestFunc = a->colorBufferStack[a->colorBufferStackDepth].alphaTestFunc;
558 g->buffer.alphaTestRef = a->colorBufferStack[a->colorBufferStackDepth].alphaTestRef;
559 g->buffer.blend = a->colorBufferStack[a->colorBufferStackDepth].blend;
560 g->buffer.blendSrcRGB = a->colorBufferStack[a->colorBufferStackDepth].blendSrcRGB;
561 g->buffer.blendDstRGB = a->colorBufferStack[a->colorBufferStackDepth].blendDstRGB;
562#if defined(CR_EXT_blend_func_separate)
563 g->buffer.blendSrcA = a->colorBufferStack[a->colorBufferStackDepth].blendSrcA;
564 g->buffer.blendDstA = a->colorBufferStack[a->colorBufferStackDepth].blendDstA;
565#endif
566#ifdef CR_EXT_blend_color
567 g->buffer.blendColor = a->colorBufferStack[a->colorBufferStackDepth].blendColor;
568#endif
569#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
570 g->buffer.blendEquation = a->colorBufferStack[a->colorBufferStackDepth].blendEquation;
571#endif
572 g->buffer.dither = a->colorBufferStack[a->colorBufferStackDepth].dither;
573 g->buffer.drawBuffer = a->colorBufferStack[a->colorBufferStackDepth].drawBuffer;
574 g->buffer.logicOp = a->colorBufferStack[a->colorBufferStackDepth].logicOp;
575 g->buffer.indexLogicOp = a->colorBufferStack[a->colorBufferStackDepth].indexLogicOp;
576 g->buffer.logicOpMode = a->colorBufferStack[a->colorBufferStackDepth].logicOpMode;
577 g->buffer.colorClearValue = a->colorBufferStack[a->colorBufferStackDepth].colorClearValue;
578 g->buffer.indexClearValue = a->colorBufferStack[a->colorBufferStackDepth].indexClearValue;
579 g->buffer.colorWriteMask = a->colorBufferStack[a->colorBufferStackDepth].colorWriteMask;
580 g->buffer.indexWriteMask = a->colorBufferStack[a->colorBufferStackDepth].indexWriteMask;
581 DIRTY(sb->buffer.dirty, g->neg_bitid);
582 DIRTY(sb->buffer.enable, g->neg_bitid);
583 DIRTY(sb->buffer.alphaFunc, g->neg_bitid);
584 DIRTY(sb->buffer.blendFunc, g->neg_bitid);
585#ifdef CR_EXT_blend_color
586 DIRTY(sb->buffer.blendColor, g->neg_bitid);
587#endif
588#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
589 DIRTY(sb->buffer.blendEquation, g->neg_bitid);
590#endif
591 DIRTY(sb->buffer.drawBuffer, g->neg_bitid);
592 DIRTY(sb->buffer.logicOp, g->neg_bitid);
593 DIRTY(sb->buffer.indexLogicOp, g->neg_bitid);
594 DIRTY(sb->buffer.clearColor, g->neg_bitid);
595 DIRTY(sb->buffer.clearIndex, g->neg_bitid);
596 DIRTY(sb->buffer.colorWriteMask, g->neg_bitid);
597 DIRTY(sb->buffer.indexMask, g->neg_bitid);
598 }
599 if (mask & GL_CURRENT_BIT)
600 {
601 if (a->currentStackDepth == 0)
602 {
603 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty current stack!" );
604 return;
605 }
606 a->currentStackDepth--;
607 for (i = 0 ; i < CR_MAX_VERTEX_ATTRIBS ; i++)
608 {
609 COPY_4V(g->current.vertexAttrib[i], a->currentStack[a->currentStackDepth].attrib[i]);
610 COPY_4V(g->current.rasterAttrib[i], a->currentStack[a->currentStackDepth].rasterAttrib[i]);
611 DIRTY(sb->current.vertexAttrib[i], g->neg_bitid);
612 }
613 g->current.rasterValid = a->currentStack[a->currentStackDepth].rasterValid;
614 g->current.edgeFlag = a->currentStack[a->currentStackDepth].edgeFlag;
615 g->current.colorIndex = a->currentStack[a->currentStackDepth].colorIndex;
616 DIRTY(sb->current.dirty, g->neg_bitid);
617 DIRTY(sb->current.edgeFlag, g->neg_bitid);
618 DIRTY(sb->current.colorIndex, g->neg_bitid);
619 DIRTY(sb->current.rasterPos, g->neg_bitid);
620 }
621 if (mask & GL_DEPTH_BUFFER_BIT)
622 {
623 if (a->depthBufferStackDepth == 0)
624 {
625 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty depth buffer stack!" );
626 return;
627 }
628 a->depthBufferStackDepth--;
629 g->buffer.depthTest = a->depthBufferStack[a->depthBufferStackDepth].depthTest;
630 g->buffer.depthFunc = a->depthBufferStack[a->depthBufferStackDepth].depthFunc;
631 g->buffer.depthClearValue = a->depthBufferStack[a->depthBufferStackDepth].depthClearValue;
632 g->buffer.depthMask = a->depthBufferStack[a->depthBufferStackDepth].depthMask;
633 DIRTY(sb->buffer.dirty, g->neg_bitid);
634 DIRTY(sb->buffer.enable, g->neg_bitid);
635 DIRTY(sb->buffer.depthFunc, g->neg_bitid);
636 DIRTY(sb->buffer.clearDepth, g->neg_bitid);
637 DIRTY(sb->buffer.depthMask, g->neg_bitid);
638 }
639 if (mask & GL_ENABLE_BIT)
640 {
641 if (a->enableStackDepth == 0)
642 {
643 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty enable stack!" );
644 return;
645 }
646 a->enableStackDepth--;
647 g->buffer.alphaTest = a->enableStack[a->enableStackDepth].alphaTest;
648 g->eval.autoNormal = a->enableStack[a->enableStackDepth].autoNormal;
649 g->buffer.blend = a->enableStack[a->enableStackDepth].blend;
650 for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
651 {
652 g->transform.clip[i] = a->enableStack[a->enableStackDepth].clip[i];
653 }
654 g->lighting.colorMaterial = a->enableStack[a->enableStackDepth].colorMaterial;
655 g->polygon.cullFace = a->enableStack[a->enableStackDepth].cullFace;
656 g->buffer.depthTest = a->enableStack[a->enableStackDepth].depthTest;
657 g->buffer.dither = a->enableStack[a->enableStackDepth].dither;
658 g->fog.enable = a->enableStack[a->enableStackDepth].fog;
659 for (i = 0 ; i < g->limits.maxLights ; i++)
660 {
661 g->lighting.light[i].enable = a->enableStack[a->enableStackDepth].light[i];
662 }
663 g->lighting.lighting = a->enableStack[a->enableStackDepth].lighting;
664 g->line.lineSmooth = a->enableStack[a->enableStackDepth].lineSmooth;
665 g->line.lineStipple = a->enableStack[a->enableStackDepth].lineStipple;
666 g->buffer.logicOp = a->enableStack[a->enableStackDepth].logicOp;
667 g->buffer.indexLogicOp = a->enableStack[a->enableStackDepth].indexLogicOp;
668 for (i = 0 ; i < GLEVAL_TOT ; i++)
669 {
670 g->eval.enable1D[i] = a->enableStack[a->enableStackDepth].map1[i];
671 g->eval.enable2D[i] = a->enableStack[a->enableStackDepth].map2[i];
672 }
673 g->transform.normalize = a->enableStack[a->enableStackDepth].normalize;
674 g->point.pointSmooth = a->enableStack[a->enableStackDepth].pointSmooth;
675#ifdef CR_ARB_point_sprite
676 g->point.pointSprite = a->enableStack[a->enableStackDepth].pointSprite;
677 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
678 g->point.coordReplacement[i] = a->enableStack[a->enableStackDepth].coordReplacement[i];
679#endif
680 g->polygon.polygonOffsetLine = a->enableStack[a->enableStackDepth].polygonOffsetLine;
681 g->polygon.polygonOffsetFill = a->enableStack[a->enableStackDepth].polygonOffsetFill;
682 g->polygon.polygonOffsetPoint = a->enableStack[a->enableStackDepth].polygonOffsetPoint;
683 g->polygon.polygonSmooth = a->enableStack[a->enableStackDepth].polygonSmooth;
684 g->polygon.polygonStipple = a->enableStack[a->enableStackDepth].polygonStipple;
685#ifdef CR_OPENGL_VERSION_1_2
686 g->transform.rescaleNormals = a->enableStack[a->enableStackDepth].rescaleNormals;
687#endif
688 g->viewport.scissorTest = a->enableStack[a->enableStackDepth].scissorTest;
689 g->stencil.stencilTest = a->enableStack[a->enableStackDepth].stencilTest;
690 for (i = 0 ; i < g->limits.maxTextureUnits; i++)
691 {
692 g->texture.unit[i].enabled1D = a->enableStack[a->enableStackDepth].texture1D[i];
693 g->texture.unit[i].enabled2D = a->enableStack[a->enableStackDepth].texture2D[i];
694#ifdef CR_OPENGL_VERSION_1_2
695 g->texture.unit[i].enabled3D = a->enableStack[a->enableStackDepth].texture3D[i];
696#endif
697#ifdef CR_ARB_texture_cube_map
698 g->texture.unit[i].enabledCubeMap = a->enableStack[a->enableStackDepth].textureCubeMap[i];
699#endif
700#ifdef CR_NV_texture_rectangle
701 g->texture.unit[i].enabledRect = a->enableStack[a->enableStackDepth].textureRect[i];
702#endif
703 g->texture.unit[i].textureGen.s = a->enableStack[a->enableStackDepth].textureGenS[i];
704 g->texture.unit[i].textureGen.t = a->enableStack[a->enableStackDepth].textureGenT[i];
705 g->texture.unit[i].textureGen.r = a->enableStack[a->enableStackDepth].textureGenR[i];
706 g->texture.unit[i].textureGen.q = a->enableStack[a->enableStackDepth].textureGenQ[i];
707 }
708 DIRTY(sb->buffer.dirty, g->neg_bitid);
709 DIRTY(sb->eval.dirty, g->neg_bitid);
710 DIRTY(sb->transform.dirty, g->neg_bitid);
711 DIRTY(sb->lighting.dirty, g->neg_bitid);
712 DIRTY(sb->fog.dirty, g->neg_bitid);
713 DIRTY(sb->line.dirty, g->neg_bitid);
714 DIRTY(sb->polygon.dirty, g->neg_bitid);
715 DIRTY(sb->viewport.dirty, g->neg_bitid);
716 DIRTY(sb->stencil.dirty, g->neg_bitid);
717 DIRTY(sb->texture.dirty, g->neg_bitid);
718
719 DIRTY(sb->buffer.enable, g->neg_bitid);
720 DIRTY(sb->eval.enable, g->neg_bitid);
721 DIRTY(sb->transform.enable, g->neg_bitid);
722 DIRTY(sb->lighting.enable, g->neg_bitid);
723 DIRTY(sb->fog.enable, g->neg_bitid);
724 DIRTY(sb->line.enable, g->neg_bitid);
725 DIRTY(sb->polygon.enable, g->neg_bitid);
726 DIRTY(sb->viewport.enable, g->neg_bitid);
727 DIRTY(sb->stencil.enable, g->neg_bitid);
728 for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
729 {
730 DIRTY(sb->texture.enable[i], g->neg_bitid);
731 }
732 }
733 if (mask & GL_EVAL_BIT)
734 {
735 if (a->evalStackDepth == 0)
736 {
737 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty eval stack!" );
738 return;
739 }
740 a->evalStackDepth--;
741 for (i = 0 ; i < GLEVAL_TOT ; i++)
742 {
743 int size1 = a->evalStack[a->evalStackDepth].eval1D[i].order * gleval_sizes[i] * sizeof(GLfloat);
744 int size2 = a->evalStack[a->evalStackDepth].eval2D[i].uorder * a->evalStack[a->evalStackDepth].eval2D[i].vorder * gleval_sizes[i] * sizeof (GLfloat);
745 g->eval.enable1D[i] = a->evalStack[a->evalStackDepth].enable1D[i];
746 g->eval.enable2D[i] = a->evalStack[a->evalStackDepth].enable2D[i];
747 g->eval.eval1D[i].u1 = a->evalStack[a->evalStackDepth].eval1D[i].u1;
748 g->eval.eval1D[i].u2 = a->evalStack[a->evalStackDepth].eval1D[i].u2;
749 g->eval.eval1D[i].order = a->evalStack[a->evalStackDepth].eval1D[i].order;
750 crMemcpy((char*)g->eval.eval1D[i].coeff, a->evalStack[a->evalStackDepth].eval1D[i].coeff, size1);
751 crFree(a->evalStack[a->evalStackDepth].eval1D[i].coeff);
752 a->evalStack[a->evalStackDepth].eval1D[i].coeff = NULL;
753 g->eval.eval2D[i].u1 = a->evalStack[a->evalStackDepth].eval2D[i].u1;
754 g->eval.eval2D[i].u2 = a->evalStack[a->evalStackDepth].eval2D[i].u2;
755 g->eval.eval2D[i].v1 = a->evalStack[a->evalStackDepth].eval2D[i].v1;
756 g->eval.eval2D[i].v2 = a->evalStack[a->evalStackDepth].eval2D[i].v2;
757 g->eval.eval2D[i].uorder = a->evalStack[a->evalStackDepth].eval2D[i].uorder;
758 g->eval.eval2D[i].vorder = a->evalStack[a->evalStackDepth].eval2D[i].vorder;
759 crMemcpy((char*)g->eval.eval2D[i].coeff, a->evalStack[a->evalStackDepth].eval2D[i].coeff, size2);
760 crFree(a->evalStack[a->evalStackDepth].eval2D[i].coeff);
761 a->evalStack[a->evalStackDepth].eval2D[i].coeff = NULL;
762 }
763 g->eval.autoNormal = a->evalStack[a->evalStackDepth].autoNormal;
764 g->eval.un1D = a->evalStack[a->evalStackDepth].un1D;
765 g->eval.u11D = a->evalStack[a->evalStackDepth].u11D;
766 g->eval.u21D = a->evalStack[a->evalStackDepth].u21D;
767 g->eval.un2D = a->evalStack[a->evalStackDepth].un2D;
768 g->eval.u12D = a->evalStack[a->evalStackDepth].u12D;
769 g->eval.u22D = a->evalStack[a->evalStackDepth].u22D;
770 g->eval.vn2D = a->evalStack[a->evalStackDepth].vn2D;
771 g->eval.v12D = a->evalStack[a->evalStackDepth].v12D;
772 g->eval.v22D = a->evalStack[a->evalStackDepth].v22D;
773 for (i = 0; i < GLEVAL_TOT; i++) {
774 DIRTY(sb->eval.eval1D[i], g->neg_bitid);
775 DIRTY(sb->eval.eval2D[i], g->neg_bitid);
776 }
777 DIRTY(sb->eval.dirty, g->neg_bitid);
778 DIRTY(sb->eval.grid1D, g->neg_bitid);
779 DIRTY(sb->eval.grid2D, g->neg_bitid);
780 DIRTY(sb->eval.enable, g->neg_bitid);
781 }
782 if (mask & GL_FOG_BIT)
783 {
784 if (a->fogStackDepth == 0)
785 {
786 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty fog stack!" );
787 return;
788 }
789 a->fogStackDepth--;
790 g->fog.enable = a->fogStack[a->fogStackDepth].enable;
791 g->fog.color = a->fogStack[a->fogStackDepth].color;
792 g->fog.density = a->fogStack[a->fogStackDepth].density;
793 g->fog.start = a->fogStack[a->fogStackDepth].start;
794 g->fog.end = a->fogStack[a->fogStackDepth].end;
795 g->fog.index = a->fogStack[a->fogStackDepth].index;
796 g->fog.mode = a->fogStack[a->fogStackDepth].mode;
797 DIRTY(sb->fog.dirty, g->neg_bitid);
798 DIRTY(sb->fog.color, g->neg_bitid);
799 DIRTY(sb->fog.index, g->neg_bitid);
800 DIRTY(sb->fog.density, g->neg_bitid);
801 DIRTY(sb->fog.start, g->neg_bitid);
802 DIRTY(sb->fog.end, g->neg_bitid);
803 DIRTY(sb->fog.mode, g->neg_bitid);
804 DIRTY(sb->fog.enable, g->neg_bitid);
805 }
806 if (mask & GL_HINT_BIT)
807 {
808 if (a->hintStackDepth == 0)
809 {
810 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty hint stack!" );
811 return;
812 }
813 a->hintStackDepth--;
814 g->hint.perspectiveCorrection = a->hintStack[a->hintStackDepth].perspectiveCorrection;
815 g->hint.pointSmooth = a->hintStack[a->hintStackDepth].pointSmooth;
816 g->hint.lineSmooth = a->hintStack[a->hintStackDepth].lineSmooth;
817 g->hint.polygonSmooth = a->hintStack[a->hintStackDepth].polygonSmooth;
818 g->hint.fog = a->hintStack[a->hintStackDepth].fog;
819 DIRTY(sb->hint.dirty, g->neg_bitid);
820 DIRTY(sb->hint.perspectiveCorrection, g->neg_bitid);
821 DIRTY(sb->hint.pointSmooth, g->neg_bitid);
822 DIRTY(sb->hint.lineSmooth, g->neg_bitid);
823 DIRTY(sb->hint.polygonSmooth, g->neg_bitid);
824#ifdef CR_EXT_clip_volume_hint
825 g->hint.clipVolumeClipping = a->hintStack[a->hintStackDepth].clipVolumeClipping;
826 DIRTY(sb->hint.clipVolumeClipping, g->neg_bitid);
827#endif
828#ifdef CR_ARB_texture_compression
829 g->hint.textureCompression = a->hintStack[a->hintStackDepth].textureCompression;
830 DIRTY(sb->hint.textureCompression, g->neg_bitid);
831#endif
832#ifdef CR_SGIS_generate_mipmap
833 g->hint.generateMipmap = a->hintStack[a->hintStackDepth].generateMipmap;
834 DIRTY(sb->hint.generateMipmap, g->neg_bitid);
835#endif
836 }
837 if (mask & GL_LIGHTING_BIT)
838 {
839 if (a->lightingStackDepth == 0)
840 {
841 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty lighting stack!" );
842 return;
843 }
844 a->lightingStackDepth--;
845 g->lighting.lightModelAmbient = a->lightingStack[a->lightingStackDepth].lightModelAmbient;
846 g->lighting.lightModelLocalViewer = a->lightingStack[a->lightingStackDepth].lightModelLocalViewer;
847 g->lighting.lightModelTwoSide = a->lightingStack[a->lightingStackDepth].lightModelTwoSide;
848#if defined(CR_EXT_separate_specular_color) || defined(CR_OPENGL_VERSION_1_2)
849 g->lighting.lightModelColorControlEXT = a->lightingStack[a->lightingStackDepth].lightModelColorControlEXT;
850#endif
851 g->lighting.lighting = a->lightingStack[a->lightingStackDepth].lighting;
852 g->lighting.colorMaterial = a->lightingStack[a->lightingStackDepth].colorMaterial;
853 g->lighting.colorMaterialMode = a->lightingStack[a->lightingStackDepth].colorMaterialMode;
854 g->lighting.colorMaterialFace = a->lightingStack[a->lightingStackDepth].colorMaterialFace;
855 for (i = 0 ; i < g->limits.maxLights; i++)
856 {
857 g->lighting.light[i].enable = a->lightingStack[a->lightingStackDepth].light[i].enable;
858 g->lighting.light[i].ambient = a->lightingStack[a->lightingStackDepth].light[i].ambient;
859 g->lighting.light[i].diffuse = a->lightingStack[a->lightingStackDepth].light[i].diffuse;
860 g->lighting.light[i].specular = a->lightingStack[a->lightingStackDepth].light[i].specular;
861 g->lighting.light[i].spotDirection = a->lightingStack[a->lightingStackDepth].light[i].spotDirection;
862 g->lighting.light[i].position = a->lightingStack[a->lightingStackDepth].light[i].position;
863 g->lighting.light[i].spotExponent = a->lightingStack[a->lightingStackDepth].light[i].spotExponent;
864 g->lighting.light[i].spotCutoff = a->lightingStack[a->lightingStackDepth].light[i].spotCutoff;
865 g->lighting.light[i].constantAttenuation = a->lightingStack[a->lightingStackDepth].light[i].constantAttenuation;
866 g->lighting.light[i].linearAttenuation = a->lightingStack[a->lightingStackDepth].light[i].linearAttenuation;
867 g->lighting.light[i].quadraticAttenuation = a->lightingStack[a->lightingStackDepth].light[i].quadraticAttenuation;
868 }
869 for (i = 0 ; i < 2 ; i++)
870 {
871 g->lighting.ambient[i] = a->lightingStack[a->lightingStackDepth].ambient[i];
872 g->lighting.diffuse[i] = a->lightingStack[a->lightingStackDepth].diffuse[i];
873 g->lighting.specular[i] = a->lightingStack[a->lightingStackDepth].specular[i];
874 g->lighting.emission[i] = a->lightingStack[a->lightingStackDepth].emission[i];
875 g->lighting.shininess[i] = a->lightingStack[a->lightingStackDepth].shininess[i];
876 g->lighting.indexes[i][0] = a->lightingStack[a->lightingStackDepth].indexes[i][0];
877 g->lighting.indexes[i][1] = a->lightingStack[a->lightingStackDepth].indexes[i][1];
878 g->lighting.indexes[i][2] = a->lightingStack[a->lightingStackDepth].indexes[i][2];
879 }
880 g->lighting.shadeModel = a->lightingStack[a->lightingStackDepth].shadeModel;
881 DIRTY(sb->lighting.dirty, g->neg_bitid);
882 DIRTY(sb->lighting.shadeModel, g->neg_bitid);
883 DIRTY(sb->lighting.lightModel, g->neg_bitid);
884 DIRTY(sb->lighting.material, g->neg_bitid);
885 DIRTY(sb->lighting.enable, g->neg_bitid);
886 for (i = 0 ; i < g->limits.maxLights; i++)
887 {
888 DIRTY(sb->lighting.light[i].dirty, g->neg_bitid);
889 DIRTY(sb->lighting.light[i].enable, g->neg_bitid);
890 DIRTY(sb->lighting.light[i].ambient, g->neg_bitid);
891 DIRTY(sb->lighting.light[i].diffuse, g->neg_bitid);
892 DIRTY(sb->lighting.light[i].specular, g->neg_bitid);
893 DIRTY(sb->lighting.light[i].position, g->neg_bitid);
894 DIRTY(sb->lighting.light[i].attenuation, g->neg_bitid);
895 DIRTY(sb->lighting.light[i].spot, g->neg_bitid);
896 }
897 }
898 if (mask & GL_LINE_BIT)
899 {
900 if (a->lineStackDepth == 0)
901 {
902 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty line stack!" );
903 return;
904 }
905 a->lineStackDepth--;
906 g->line.lineSmooth = a->lineStack[a->lineStackDepth].lineSmooth;
907 g->line.lineStipple = a->lineStack[a->lineStackDepth].lineStipple;
908 g->line.pattern = a->lineStack[a->lineStackDepth].pattern;
909 g->line.repeat = a->lineStack[a->lineStackDepth].repeat;
910 g->line.width = a->lineStack[a->lineStackDepth].width;
911 DIRTY(sb->line.dirty, g->neg_bitid);
912 DIRTY(sb->line.enable, g->neg_bitid);
913 DIRTY(sb->line.width, g->neg_bitid);
914 DIRTY(sb->line.stipple, g->neg_bitid);
915 }
916 if (mask & GL_LIST_BIT)
917 {
918 if (a->listStackDepth == 0)
919 {
920 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty list stack!" );
921 return;
922 }
923 a->listStackDepth--;
924 g->lists.base = a->listStack[a->listStackDepth].base;
925 DIRTY(sb->lists.dirty, g->neg_bitid);
926 }
927 if (mask & GL_PIXEL_MODE_BIT)
928 {
929 if (a->pixelModeStackDepth == 0)
930 {
931 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty pixel mode stack!" );
932 return;
933 }
934 a->pixelModeStackDepth--;
935 g->pixel.bias = a->pixelModeStack[a->pixelModeStackDepth].bias;
936 g->pixel.scale = a->pixelModeStack[a->pixelModeStackDepth].scale;
937 g->pixel.indexOffset = a->pixelModeStack[a->pixelModeStackDepth].indexOffset;
938 g->pixel.indexShift = a->pixelModeStack[a->pixelModeStackDepth].indexShift;
939 g->pixel.mapColor = a->pixelModeStack[a->pixelModeStackDepth].mapColor;
940 g->pixel.mapStencil = a->pixelModeStack[a->pixelModeStackDepth].mapStencil;
941 g->pixel.xZoom = a->pixelModeStack[a->pixelModeStackDepth].xZoom;
942 g->pixel.yZoom = a->pixelModeStack[a->pixelModeStackDepth].yZoom;
943 g->buffer.readBuffer = a->pixelModeStack[a->pixelModeStackDepth].readBuffer;
944 DIRTY(sb->pixel.dirty, g->neg_bitid);
945 DIRTY(sb->pixel.transfer, g->neg_bitid);
946 DIRTY(sb->pixel.zoom, g->neg_bitid);
947 DIRTY(sb->buffer.dirty, g->neg_bitid);
948 DIRTY(sb->buffer.readBuffer, g->neg_bitid);
949 }
950 if (mask & GL_POINT_BIT)
951 {
952 if (a->pointStackDepth == 0)
953 {
954 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty point stack!" );
955 return;
956 }
957 a->pointStackDepth--;
958 g->point.pointSmooth = a->pointStack[a->pointStackDepth].pointSmooth;
959 g->point.pointSize = a->pointStack[a->pointStackDepth].pointSize;
960#if GL_ARB_point_sprite
961 g->point.pointSprite = a->pointStack[a->pointStackDepth].pointSprite;
962 DIRTY(sb->point.enableSprite, g->neg_bitid);
963 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++) {
964 g->point.coordReplacement[i] = a->enableStack[a->enableStackDepth].coordReplacement[i];
965 DIRTY(sb->point.coordReplacement[i], g->neg_bitid);
966 }
967#endif
968 DIRTY(sb->point.dirty, g->neg_bitid);
969 DIRTY(sb->point.size, g->neg_bitid);
970 DIRTY(sb->point.enableSmooth, g->neg_bitid);
971 }
972 if (mask & GL_POLYGON_BIT)
973 {
974 if (a->polygonStackDepth == 0)
975 {
976 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty polygon stack!" );
977 return;
978 }
979 a->polygonStackDepth--;
980 g->polygon.cullFace = a->polygonStack[a->polygonStackDepth].cullFace;
981 g->polygon.cullFaceMode = a->polygonStack[a->polygonStackDepth].cullFaceMode;
982 g->polygon.frontFace = a->polygonStack[a->polygonStackDepth].frontFace;
983 g->polygon.frontMode = a->polygonStack[a->polygonStackDepth].frontMode;
984 g->polygon.backMode = a->polygonStack[a->polygonStackDepth].backMode;
985 g->polygon.polygonSmooth = a->polygonStack[a->polygonStackDepth].polygonSmooth;
986 g->polygon.polygonStipple = a->polygonStack[a->polygonStackDepth].polygonStipple;
987 g->polygon.polygonOffsetFill = a->polygonStack[a->polygonStackDepth].polygonOffsetFill;
988 g->polygon.polygonOffsetLine = a->polygonStack[a->polygonStackDepth].polygonOffsetLine;
989 g->polygon.polygonOffsetPoint = a->polygonStack[a->polygonStackDepth].polygonOffsetPoint;
990 g->polygon.offsetFactor = a->polygonStack[a->polygonStackDepth].offsetFactor;
991 g->polygon.offsetUnits = a->polygonStack[a->polygonStackDepth].offsetUnits;
992 DIRTY(sb->polygon.dirty, g->neg_bitid);
993 DIRTY(sb->polygon.enable, g->neg_bitid);
994 DIRTY(sb->polygon.offset, g->neg_bitid);
995 DIRTY(sb->polygon.mode, g->neg_bitid);
996 DIRTY(sb->polygon.stipple, g->neg_bitid);
997 }
998 if (mask & GL_POLYGON_STIPPLE_BIT)
999 {
1000 if (a->polygonStippleStackDepth == 0)
1001 {
1002 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty polygon stipple stack!" );
1003 return;
1004 }
1005 a->polygonStippleStackDepth--;
1006 crMemcpy( g->polygon.stipple, a->polygonStippleStack[a->polygonStippleStackDepth].pattern, 32*sizeof(GLint) );
1007 DIRTY(sb->polygon.dirty, g->neg_bitid);
1008 DIRTY(sb->polygon.stipple, g->neg_bitid);
1009 }
1010 if (mask & GL_SCISSOR_BIT)
1011 {
1012 if (a->scissorStackDepth == 0)
1013 {
1014 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty scissor stack!" );
1015 return;
1016 }
1017 a->scissorStackDepth--;
1018 g->viewport.scissorTest = a->scissorStack[a->scissorStackDepth].scissorTest;
1019 g->viewport.scissorX = a->scissorStack[a->scissorStackDepth].scissorX;
1020 g->viewport.scissorY = a->scissorStack[a->scissorStackDepth].scissorY;
1021 g->viewport.scissorW = a->scissorStack[a->scissorStackDepth].scissorW;
1022 g->viewport.scissorH = a->scissorStack[a->scissorStackDepth].scissorH;
1023 DIRTY(sb->viewport.dirty, g->neg_bitid);
1024 DIRTY(sb->viewport.enable, g->neg_bitid);
1025 DIRTY(sb->viewport.s_dims, g->neg_bitid);
1026 }
1027 if (mask & GL_STENCIL_BUFFER_BIT)
1028 {
1029 if (a->stencilBufferStackDepth == 0)
1030 {
1031 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty stencil stack!" );
1032 return;
1033 }
1034 a->stencilBufferStackDepth--;
1035 g->stencil.stencilTest = a->stencilBufferStack[a->stencilBufferStackDepth].stencilTest;
1036 g->stencil.func = a->stencilBufferStack[a->stencilBufferStackDepth].func;
1037 g->stencil.mask = a->stencilBufferStack[a->stencilBufferStackDepth].mask;
1038 g->stencil.ref = a->stencilBufferStack[a->stencilBufferStackDepth].ref;
1039 g->stencil.fail = a->stencilBufferStack[a->stencilBufferStackDepth].fail;
1040 g->stencil.passDepthFail = a->stencilBufferStack[a->stencilBufferStackDepth].passDepthFail;
1041 g->stencil.passDepthPass = a->stencilBufferStack[a->stencilBufferStackDepth].passDepthPass;
1042 g->stencil.clearValue = a->stencilBufferStack[a->stencilBufferStackDepth].clearValue;
1043 g->stencil.writeMask = a->stencilBufferStack[a->stencilBufferStackDepth].writeMask;
1044 DIRTY(sb->stencil.dirty, g->neg_bitid);
1045 DIRTY(sb->stencil.enable, g->neg_bitid);
1046 DIRTY(sb->stencil.func, g->neg_bitid);
1047 DIRTY(sb->stencil.op, g->neg_bitid);
1048 DIRTY(sb->stencil.clearValue, g->neg_bitid);
1049 DIRTY(sb->stencil.writeMask, g->neg_bitid);
1050 }
1051 if (mask & GL_TEXTURE_BIT)
1052 {
1053 CRTextureStack *tState;
1054 if (a->textureStackDepth == 0)
1055 {
1056 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty texture stack!" );
1057 return;
1058 }
1059 a->textureStackDepth--;
1060 tState = a->textureStack + a->textureStackDepth;
1061
1062 g->texture.curTextureUnit = tState->curTextureUnit;
1063 for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
1064 {
1065 copy_texunit(&g->texture.unit[i], &tState->unit[i]);
1066 /* first, restore the bindings! */
1067 g->texture.unit[i].currentTexture1D = crStateTextureGet(GL_TEXTURE_1D, tState->unit[i].Saved1D.id);
1068 copy_texobj(g->texture.unit[i].currentTexture1D, &tState->unit[i].Saved1D, GL_FALSE);
1069 g->texture.unit[i].currentTexture2D = crStateTextureGet(GL_TEXTURE_2D, tState->unit[i].Saved2D.id);
1070 copy_texobj(g->texture.unit[i].currentTexture2D, &tState->unit[i].Saved2D, GL_FALSE);
1071#ifdef CR_OPENGL_VERSION_1_2
1072 g->texture.unit[i].currentTexture3D = crStateTextureGet(GL_TEXTURE_3D, tState->unit[i].Saved3D.id);
1073 copy_texobj(g->texture.unit[i].currentTexture3D, &tState->unit[i].Saved3D, GL_FALSE);
1074#endif
1075#ifdef CR_ARB_texture_cube_map
1076 g->texture.unit[i].currentTextureCubeMap = crStateTextureGet(GL_TEXTURE_CUBE_MAP_ARB, tState->unit[i].SavedCubeMap.id);
1077 copy_texobj(g->texture.unit[i].currentTextureCubeMap, &tState->unit[i].SavedCubeMap, GL_FALSE);
1078#endif
1079#ifdef CR_NV_texture_rectangle
1080 g->texture.unit[i].currentTextureRect = crStateTextureGet(GL_TEXTURE_CUBE_MAP_ARB, tState->unit[i].SavedRect.id);
1081 copy_texobj(g->texture.unit[i].currentTextureRect, &tState->unit[i].SavedRect, GL_FALSE);
1082#endif
1083 }
1084 DIRTY(sb->texture.dirty, g->neg_bitid);
1085 for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
1086 {
1087 DIRTY(sb->texture.enable[i], g->neg_bitid);
1088 DIRTY(sb->texture.current[i], g->neg_bitid);
1089 DIRTY(sb->texture.objGen[i], g->neg_bitid);
1090 DIRTY(sb->texture.eyeGen[i], g->neg_bitid);
1091 DIRTY(sb->texture.envBit[i], g->neg_bitid);
1092 DIRTY(sb->texture.genMode[i], g->neg_bitid);
1093 }
1094
1095 for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
1096 {
1097 DIRTY(g->texture.unit[i].currentTexture1D->dirty, g->neg_bitid);
1098 DIRTY(g->texture.unit[i].currentTexture2D->dirty, g->neg_bitid);
1099 DIRTY(g->texture.unit[i].currentTexture3D->dirty, g->neg_bitid);
1100#ifdef CR_ARB_texture_cube_map
1101 DIRTY(g->texture.unit[i].currentTextureCubeMap->dirty, g->neg_bitid);
1102#endif
1103#ifdef CR_NV_texture_rectangle
1104 DIRTY(g->texture.unit[i].currentTextureRect->dirty, g->neg_bitid);
1105#endif
1106 DIRTY(g->texture.unit[i].currentTexture1D->paramsBit[i], g->neg_bitid);
1107 DIRTY(g->texture.unit[i].currentTexture2D->paramsBit[i], g->neg_bitid);
1108 DIRTY(g->texture.unit[i].currentTexture3D->paramsBit[i], g->neg_bitid);
1109#ifdef CR_ARB_texture_cube_map
1110 DIRTY(g->texture.unit[i].currentTextureCubeMap->paramsBit[i], g->neg_bitid);
1111#endif
1112#ifdef CR_NV_texture_rectangle
1113 DIRTY(g->texture.unit[i].currentTextureRect->paramsBit[i], g->neg_bitid);
1114#endif
1115 }
1116 }
1117 if (mask & GL_TRANSFORM_BIT)
1118 {
1119 if (a->transformStackDepth == 0)
1120 {
1121 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty transform stack!" );
1122 return;
1123 }
1124 a->transformStackDepth--;
1125 g->transform.matrixMode = a->transformStack[a->transformStackDepth].matrixMode;
1126 crStateMatrixMode(g->transform.matrixMode);
1127 for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
1128 {
1129 g->transform.clip[i] = a->transformStack[a->transformStackDepth].clip[i];
1130 g->transform.clipPlane[i] = a->transformStack[a->transformStackDepth].clipPlane[i];
1131 }
1132 g->transform.normalize = a->transformStack[a->transformStackDepth].normalize;
1133#ifdef CR_OPENGL_VERSION_1_2
1134 g->transform.rescaleNormals = a->transformStack[a->transformStackDepth].rescaleNormals;
1135#endif
1136 DIRTY(sb->transform.dirty, g->neg_bitid);
1137 DIRTY(sb->transform.matrixMode, g->neg_bitid);
1138 DIRTY(sb->transform.clipPlane, g->neg_bitid);
1139 DIRTY(sb->transform.enable, g->neg_bitid);
1140 }
1141 if (mask & GL_VIEWPORT_BIT)
1142 {
1143 if (a->viewportStackDepth == 0)
1144 {
1145 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty viewport stack!" );
1146 return;
1147 }
1148 a->viewportStackDepth--;
1149 g->viewport.viewportX = a->viewportStack[a->viewportStackDepth].viewportX;
1150 g->viewport.viewportY = a->viewportStack[a->viewportStackDepth].viewportY;
1151 g->viewport.viewportW = a->viewportStack[a->viewportStackDepth].viewportW;
1152 g->viewport.viewportH = a->viewportStack[a->viewportStackDepth].viewportH;
1153 g->viewport.nearClip = a->viewportStack[a->viewportStackDepth].nearClip;
1154 g->viewport.farClip = a->viewportStack[a->viewportStackDepth].farClip;
1155 DIRTY(sb->viewport.dirty, g->neg_bitid);
1156 DIRTY(sb->viewport.v_dims, g->neg_bitid);
1157 DIRTY(sb->viewport.depth, g->neg_bitid);
1158 }
1159 DIRTY(ab->dirty, g->neg_bitid);
1160}
1161
1162void crStateAttribSwitch( CRAttribBits *bb, CRbitvalue *bitID,
1163 CRContext *fromCtx, CRContext *toCtx )
1164{
1165 CRAttribState *to = &(toCtx->attrib);
1166 CRAttribState *from = &(fromCtx->attrib);
1167 if (to->attribStackDepth != 0 || from->attribStackDepth != 0)
1168 {
1169 crWarning( "Trying to switch contexts when the attribute stacks "
1170 "weren't empty. Currently, this is not supported." );
1171 }
1172 (void) bb;
1173 (void) bitID;
1174}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette