VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c@ 78493

Last change on this file since 78493 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 62.8 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 "state.h"
8#include "state/cr_statetypes.h"
9#include "state/cr_texture.h"
10#include "cr_hash.h"
11#include "cr_string.h"
12#include "cr_mem.h"
13#include "cr_version.h"
14#include "state_internals.h"
15
16
17#define UNIMPLEMENTED() crStateError(pState, __LINE__,__FILE__,GL_INVALID_OPERATION, "Unimplemented something or other" )
18
19
20#if 0 /* NOT USED??? */
21void crStateTextureObjSwitchCallback( unsigned long key, void *data1, void *data2 )
22{
23 CRTextureObj *tobj = (CRTextureObj *) data1;
24 CRContext *fromCtx = (CRContext *) data2;
25 unsigned int i = 0;
26 unsigned int j = 0;
27 CRbitvalue *bitID = fromCtx->bitid;
28 CRbitvalue nbitID[CR_MAX_BITARRAY];
29
30 for (j=0;j<CR_MAX_BITARRAY;j++)
31 nbitID[j] = ~bitID[j];
32
33 if (!tobj) return;
34
35 FILLDIRTY(tobj->dirty);
36 FILLDIRTY(tobj->imageBit);
37
38 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
39 {
40 int j;
41
42 FILLDIRTY(tobj->paramsBit[i]);
43
44 switch (tobj->target)
45 {
46 case GL_TEXTURE_1D:
47 case GL_TEXTURE_2D:
48 for (j = 0; j <= fromCtx->texture.maxLevel; j++)
49 {
50 CRTextureLevel *tl = &(tobj->level[j]);
51 FILLDIRTY(tl->dirty);
52 }
53 break;
54#ifdef CR_OPENGL_VERSION_1_2
55 case GL_TEXTURE_3D:
56#endif
57 for (j = 0; j <= fromCtx->texture.max3DLevel; j++)
58 {
59 CRTextureLevel *tl = &(tobj->level[j]);
60 FILLDIRTY(tl->dirty);
61 }
62 break;
63#ifdef CR_ARB_texture_cube_map
64 case GL_TEXTURE_CUBE_MAP_ARB:
65 for (j = 0; j <= fromCtx->texture.maxCubeMapLevel; j++)
66 {
67 CRTextureLevel *tl;
68 /* Positive X */
69 tl = &(tobj->level[j]);
70 FILLDIRTY(tl->dirty);
71 /* Negative X */
72 tl = &(tobj->negativeXlevel[j]);
73 FILLDIRTY(tl->dirty);
74 /* Positive Y */
75 tl = &(tobj->positiveYlevel[j]);
76 FILLDIRTY(tl->dirty);
77 /* Negative Y */
78 tl = &(tobj->negativeYlevel[j]);
79 FILLDIRTY(tl->dirty);
80 /* Positive Z */
81 tl = &(tobj->positiveZlevel[j]);
82 FILLDIRTY(tl->dirty);
83 /* Negative Z */
84 tl = &(tobj->negativeZlevel[j]);
85 FILLDIRTY(tl->dirty);
86 }
87 break;
88#endif
89 default:
90 UNIMPLEMENTED();
91 }
92 }
93}
94#endif
95
96
97void crStateTextureSwitch( CRTextureBits *tb, CRbitvalue *bitID,
98 CRContext *fromCtx, CRContext *toCtx )
99{
100 PCRStateTracker pState = fromCtx->pStateTracker;
101 CRTextureState *from = &(fromCtx->texture);
102 const CRTextureState *to = &(toCtx->texture);
103 unsigned int i,j;
104 glAble able[2];
105 CRbitvalue nbitID[CR_MAX_BITARRAY];
106 unsigned int activeUnit = (unsigned int) -1;
107
108 CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);
109
110 for (j=0;j<CR_MAX_BITARRAY;j++)
111 nbitID[j] = ~bitID[j];
112 able[0] = pState->diff_api.Disable;
113 able[1] = pState->diff_api.Enable;
114
115 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
116 {
117 if (CHECKDIRTY(tb->enable[i], bitID))
118 {
119 if (activeUnit != i) {
120 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
121 activeUnit = i;
122 }
123 if (from->unit[i].enabled1D != to->unit[i].enabled1D)
124 {
125 able[to->unit[i].enabled1D](GL_TEXTURE_1D);
126 FILLDIRTY(tb->enable[i]);
127 FILLDIRTY(tb->dirty);
128 }
129 if (from->unit[i].enabled2D != to->unit[i].enabled2D)
130 {
131 able[to->unit[i].enabled2D](GL_TEXTURE_2D);
132 FILLDIRTY(tb->enable[i]);
133 FILLDIRTY(tb->dirty);
134 }
135#ifdef CR_OPENGL_VERSION_1_2
136 if (from->unit[i].enabled3D != to->unit[i].enabled3D)
137 {
138 able[to->unit[i].enabled3D](GL_TEXTURE_3D);
139 FILLDIRTY(tb->enable[i]);
140 FILLDIRTY(tb->dirty);
141 }
142#endif
143#ifdef CR_ARB_texture_cube_map
144 if (fromCtx->extensions.ARB_texture_cube_map &&
145 from->unit[i].enabledCubeMap != to->unit[i].enabledCubeMap)
146 {
147 able[to->unit[i].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
148 FILLDIRTY(tb->enable[i]);
149 FILLDIRTY(tb->dirty);
150 }
151#endif
152#ifdef CR_NV_texture_rectangle
153 if (fromCtx->extensions.NV_texture_rectangle &&
154 from->unit[i].enabledRect != to->unit[i].enabledRect)
155 {
156 able[to->unit[i].enabledRect](GL_TEXTURE_RECTANGLE_NV);
157 FILLDIRTY(tb->enable[i]);
158 FILLDIRTY(tb->dirty);
159 }
160#endif
161 if (from->unit[i].textureGen.s != to->unit[i].textureGen.s ||
162 from->unit[i].textureGen.t != to->unit[i].textureGen.t ||
163 from->unit[i].textureGen.r != to->unit[i].textureGen.r ||
164 from->unit[i].textureGen.q != to->unit[i].textureGen.q)
165 {
166 able[to->unit[i].textureGen.s](GL_TEXTURE_GEN_S);
167 able[to->unit[i].textureGen.t](GL_TEXTURE_GEN_T);
168 able[to->unit[i].textureGen.r](GL_TEXTURE_GEN_R);
169 able[to->unit[i].textureGen.q](GL_TEXTURE_GEN_Q);
170 FILLDIRTY(tb->enable[i]);
171 FILLDIRTY(tb->dirty);
172 }
173 CLEARDIRTY(tb->enable[i], nbitID);
174 }
175
176 /*
177 ** A thought on switching with textures:
178 ** Since we are only performing a switch
179 ** and not a sync, we won't need to
180 ** update individual textures, just
181 ** the bindings....
182 */
183
184 if (CHECKDIRTY(tb->current[i], bitID))
185 {
186 if (activeUnit != i) {
187 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
188 activeUnit = i;
189 }
190 if (from->unit[i].currentTexture1D->hwid != to->unit[i].currentTexture1D->hwid)
191 {
192 pState->diff_api.BindTexture(GL_TEXTURE_1D, crStateGetTextureObjHWID(pState, to->unit[i].currentTexture1D));
193 FILLDIRTY(tb->current[i]);
194 FILLDIRTY(tb->dirty);
195 }
196 if (from->unit[i].currentTexture2D->hwid != to->unit[i].currentTexture2D->hwid)
197 {
198 pState->diff_api.BindTexture(GL_TEXTURE_2D, crStateGetTextureObjHWID(pState, to->unit[i].currentTexture2D));
199 FILLDIRTY(tb->current[i]);
200 FILLDIRTY(tb->dirty);
201 }
202#ifdef CR_OPENGL_VERSION_1_2
203 if (from->unit[i].currentTexture3D->hwid != to->unit[i].currentTexture3D->hwid)
204 {
205 pState->diff_api.BindTexture(GL_TEXTURE_3D, crStateGetTextureObjHWID(pState, to->unit[i].currentTexture3D));
206 FILLDIRTY(tb->current[i]);
207 FILLDIRTY(tb->dirty);
208 }
209#endif
210#ifdef CR_ARB_texture_cube_map
211 if (fromCtx->extensions.ARB_texture_cube_map &&
212 from->unit[i].currentTextureCubeMap->hwid != to->unit[i].currentTextureCubeMap->hwid)
213 {
214 pState->diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, crStateGetTextureObjHWID(pState, to->unit[i].currentTextureCubeMap));
215 FILLDIRTY(tb->current[i]);
216 FILLDIRTY(tb->dirty);
217 }
218#endif
219#ifdef CR_NV_texture_rectangle
220 if (fromCtx->extensions.NV_texture_rectangle &&
221 from->unit[i].currentTextureRect->hwid != to->unit[i].currentTextureRect->hwid)
222 {
223 pState->diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, crStateGetTextureObjHWID(pState, to->unit[i].currentTextureRect));
224 FILLDIRTY(tb->current[i]);
225 FILLDIRTY(tb->dirty);
226 }
227#endif
228 CLEARDIRTY(tb->current[i], nbitID);
229 }
230
231 if (CHECKDIRTY(tb->objGen[i], bitID))
232 {
233 if (activeUnit != i) {
234 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
235 activeUnit = i;
236 }
237 if (from->unit[i].objSCoeff.x != to->unit[i].objSCoeff.x ||
238 from->unit[i].objSCoeff.y != to->unit[i].objSCoeff.y ||
239 from->unit[i].objSCoeff.z != to->unit[i].objSCoeff.z ||
240 from->unit[i].objSCoeff.w != to->unit[i].objSCoeff.w)
241 {
242 GLfloat f[4];
243 f[0] = to->unit[i].objSCoeff.x;
244 f[1] = to->unit[i].objSCoeff.y;
245 f[2] = to->unit[i].objSCoeff.z;
246 f[3] = to->unit[i].objSCoeff.w;
247 pState->diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
248 FILLDIRTY(tb->objGen[i]);
249 FILLDIRTY(tb->dirty);
250 }
251 if (from->unit[i].objTCoeff.x != to->unit[i].objTCoeff.x ||
252 from->unit[i].objTCoeff.y != to->unit[i].objTCoeff.y ||
253 from->unit[i].objTCoeff.z != to->unit[i].objTCoeff.z ||
254 from->unit[i].objTCoeff.w != to->unit[i].objTCoeff.w) {
255 GLfloat f[4];
256 f[0] = to->unit[i].objTCoeff.x;
257 f[1] = to->unit[i].objTCoeff.y;
258 f[2] = to->unit[i].objTCoeff.z;
259 f[3] = to->unit[i].objTCoeff.w;
260 pState->diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
261 FILLDIRTY(tb->objGen[i]);
262 FILLDIRTY(tb->dirty);
263 }
264 if (from->unit[i].objRCoeff.x != to->unit[i].objRCoeff.x ||
265 from->unit[i].objRCoeff.y != to->unit[i].objRCoeff.y ||
266 from->unit[i].objRCoeff.z != to->unit[i].objRCoeff.z ||
267 from->unit[i].objRCoeff.w != to->unit[i].objRCoeff.w) {
268 GLfloat f[4];
269 f[0] = to->unit[i].objRCoeff.x;
270 f[1] = to->unit[i].objRCoeff.y;
271 f[2] = to->unit[i].objRCoeff.z;
272 f[3] = to->unit[i].objRCoeff.w;
273 pState->diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
274 FILLDIRTY(tb->objGen[i]);
275 FILLDIRTY(tb->dirty);
276 }
277 if (from->unit[i].objQCoeff.x != to->unit[i].objQCoeff.x ||
278 from->unit[i].objQCoeff.y != to->unit[i].objQCoeff.y ||
279 from->unit[i].objQCoeff.z != to->unit[i].objQCoeff.z ||
280 from->unit[i].objQCoeff.w != to->unit[i].objQCoeff.w) {
281 GLfloat f[4];
282 f[0] = to->unit[i].objQCoeff.x;
283 f[1] = to->unit[i].objQCoeff.y;
284 f[2] = to->unit[i].objQCoeff.z;
285 f[3] = to->unit[i].objQCoeff.w;
286 pState->diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
287 FILLDIRTY(tb->objGen[i]);
288 FILLDIRTY(tb->dirty);
289 }
290 CLEARDIRTY(tb->objGen[i], nbitID);
291 }
292 if (CHECKDIRTY(tb->eyeGen[i], bitID))
293 {
294 if (activeUnit != i) {
295 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
296 activeUnit = i;
297 }
298 pState->diff_api.MatrixMode(GL_MODELVIEW);
299 pState->diff_api.PushMatrix();
300 pState->diff_api.LoadIdentity();
301 if (from->unit[i].eyeSCoeff.x != to->unit[i].eyeSCoeff.x ||
302 from->unit[i].eyeSCoeff.y != to->unit[i].eyeSCoeff.y ||
303 from->unit[i].eyeSCoeff.z != to->unit[i].eyeSCoeff.z ||
304 from->unit[i].eyeSCoeff.w != to->unit[i].eyeSCoeff.w) {
305 GLfloat f[4];
306 f[0] = to->unit[i].eyeSCoeff.x;
307 f[1] = to->unit[i].eyeSCoeff.y;
308 f[2] = to->unit[i].eyeSCoeff.z;
309 f[3] = to->unit[i].eyeSCoeff.w;
310 pState->diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
311 FILLDIRTY(tb->eyeGen[i]);
312 FILLDIRTY(tb->dirty);
313 }
314 if (from->unit[i].eyeTCoeff.x != to->unit[i].eyeTCoeff.x ||
315 from->unit[i].eyeTCoeff.y != to->unit[i].eyeTCoeff.y ||
316 from->unit[i].eyeTCoeff.z != to->unit[i].eyeTCoeff.z ||
317 from->unit[i].eyeTCoeff.w != to->unit[i].eyeTCoeff.w) {
318 GLfloat f[4];
319 f[0] = to->unit[i].eyeTCoeff.x;
320 f[1] = to->unit[i].eyeTCoeff.y;
321 f[2] = to->unit[i].eyeTCoeff.z;
322 f[3] = to->unit[i].eyeTCoeff.w;
323 pState->diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
324 FILLDIRTY(tb->eyeGen[i]);
325 FILLDIRTY(tb->dirty);
326 }
327 if (from->unit[i].eyeRCoeff.x != to->unit[i].eyeRCoeff.x ||
328 from->unit[i].eyeRCoeff.y != to->unit[i].eyeRCoeff.y ||
329 from->unit[i].eyeRCoeff.z != to->unit[i].eyeRCoeff.z ||
330 from->unit[i].eyeRCoeff.w != to->unit[i].eyeRCoeff.w) {
331 GLfloat f[4];
332 f[0] = to->unit[i].eyeRCoeff.x;
333 f[1] = to->unit[i].eyeRCoeff.y;
334 f[2] = to->unit[i].eyeRCoeff.z;
335 f[3] = to->unit[i].eyeRCoeff.w;
336 pState->diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
337 FILLDIRTY(tb->eyeGen[i]);
338 FILLDIRTY(tb->dirty);
339 }
340 if (from->unit[i].eyeQCoeff.x != to->unit[i].eyeQCoeff.x ||
341 from->unit[i].eyeQCoeff.y != to->unit[i].eyeQCoeff.y ||
342 from->unit[i].eyeQCoeff.z != to->unit[i].eyeQCoeff.z ||
343 from->unit[i].eyeQCoeff.w != to->unit[i].eyeQCoeff.w) {
344 GLfloat f[4];
345 f[0] = to->unit[i].eyeQCoeff.x;
346 f[1] = to->unit[i].eyeQCoeff.y;
347 f[2] = to->unit[i].eyeQCoeff.z;
348 f[3] = to->unit[i].eyeQCoeff.w;
349 pState->diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
350 FILLDIRTY(tb->eyeGen[i]);
351 FILLDIRTY(tb->dirty);
352 }
353 pState->diff_api.PopMatrix();
354 CLEARDIRTY(tb->eyeGen[i], nbitID);
355 }
356 if (CHECKDIRTY(tb->genMode[i], bitID))
357 {
358 if (activeUnit != i) {
359 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
360 activeUnit = i;
361 }
362 if (from->unit[i].gen.s != to->unit[i].gen.s ||
363 from->unit[i].gen.t != to->unit[i].gen.t ||
364 from->unit[i].gen.r != to->unit[i].gen.r ||
365 from->unit[i].gen.q != to->unit[i].gen.q)
366 {
367 pState->diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[i].gen.s);
368 pState->diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[i].gen.t);
369 pState->diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[i].gen.r);
370 pState->diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[i].gen.q);
371 FILLDIRTY(tb->genMode[i]);
372 FILLDIRTY(tb->dirty);
373 }
374 CLEARDIRTY(tb->genMode[i], nbitID);
375 }
376 CLEARDIRTY(tb->dirty, nbitID);
377
378 /* Texture enviroment */
379 if (CHECKDIRTY(tb->envBit[i], bitID))
380 {
381 if (activeUnit != i) {
382 pState->diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
383 activeUnit = i;
384 }
385 if (from->unit[i].envMode != to->unit[i].envMode)
386 {
387 pState->diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[i].envMode);
388 FILLDIRTY(tb->envBit[i]);
389 FILLDIRTY(tb->dirty);
390 }
391 if (from->unit[i].envColor.r != to->unit[i].envColor.r ||
392 from->unit[i].envColor.g != to->unit[i].envColor.g ||
393 from->unit[i].envColor.b != to->unit[i].envColor.b ||
394 from->unit[i].envColor.a != to->unit[i].envColor.a)
395 {
396 GLfloat f[4];
397 f[0] = to->unit[i].envColor.r;
398 f[1] = to->unit[i].envColor.g;
399 f[2] = to->unit[i].envColor.b;
400 f[3] = to->unit[i].envColor.a;
401 pState->diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
402 FILLDIRTY(tb->envBit[i]);
403 FILLDIRTY(tb->dirty);
404 }
405 if (from->unit[i].combineModeRGB != to->unit[i].combineModeRGB)
406 {
407 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[i].combineModeRGB);
408 FILLDIRTY(tb->envBit[i]);
409 FILLDIRTY(tb->dirty);
410 }
411 if (from->unit[i].combineModeA != to->unit[i].combineModeA)
412 {
413 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[i].combineModeA);
414 FILLDIRTY(tb->envBit[i]);
415 FILLDIRTY(tb->dirty);
416 }
417 if (from->unit[i].combineSourceRGB[0] != to->unit[i].combineSourceRGB[0])
418 {
419 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[i].combineSourceRGB[0]);
420 FILLDIRTY(tb->envBit[i]);
421 FILLDIRTY(tb->dirty);
422 }
423 if (from->unit[i].combineSourceRGB[1] != to->unit[i].combineSourceRGB[1])
424 {
425 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[i].combineSourceRGB[1]);
426 FILLDIRTY(tb->envBit[i]);
427 FILLDIRTY(tb->dirty);
428 }
429 if (from->unit[i].combineSourceRGB[2] != to->unit[i].combineSourceRGB[2])
430 {
431 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[i].combineSourceRGB[2]);
432 FILLDIRTY(tb->envBit[i]);
433 FILLDIRTY(tb->dirty);
434 }
435 if (from->unit[i].combineSourceA[0] != to->unit[i].combineSourceA[0])
436 {
437 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[i].combineSourceA[0]);
438 FILLDIRTY(tb->envBit[i]);
439 FILLDIRTY(tb->dirty);
440 }
441 if (from->unit[i].combineSourceA[1] != to->unit[i].combineSourceA[1])
442 {
443 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[i].combineSourceA[1]);
444 FILLDIRTY(tb->envBit[i]);
445 FILLDIRTY(tb->dirty);
446 }
447 if (from->unit[i].combineSourceA[2] != to->unit[i].combineSourceA[2])
448 {
449 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[i].combineSourceA[2]);
450 FILLDIRTY(tb->envBit[i]);
451 FILLDIRTY(tb->dirty);
452 }
453 if (from->unit[i].combineOperandRGB[0] != to->unit[i].combineOperandRGB[0])
454 {
455 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[i].combineOperandRGB[0]);
456 FILLDIRTY(tb->envBit[i]);
457 FILLDIRTY(tb->dirty);
458 }
459 if (from->unit[i].combineOperandRGB[1] != to->unit[i].combineOperandRGB[1])
460 {
461 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[i].combineOperandRGB[1]);
462 FILLDIRTY(tb->envBit[i]);
463 FILLDIRTY(tb->dirty);
464 }
465 if (from->unit[i].combineOperandRGB[2] != to->unit[i].combineOperandRGB[2])
466 {
467 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[i].combineOperandRGB[2]);
468 FILLDIRTY(tb->envBit[i]);
469 FILLDIRTY(tb->dirty);
470 }
471 if (from->unit[i].combineOperandA[0] != to->unit[i].combineOperandA[0])
472 {
473 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[i].combineOperandA[0]);
474 FILLDIRTY(tb->envBit[i]);
475 FILLDIRTY(tb->dirty);
476 }
477 if (from->unit[i].combineOperandA[1] != to->unit[i].combineOperandA[1])
478 {
479 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[i].combineOperandA[1]);
480 FILLDIRTY(tb->envBit[i]);
481 FILLDIRTY(tb->dirty);
482 }
483 if (from->unit[i].combineOperandA[2] != to->unit[i].combineOperandA[2])
484 {
485 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[i].combineOperandA[2]);
486 FILLDIRTY(tb->envBit[i]);
487 FILLDIRTY(tb->dirty);
488 }
489 if (from->unit[i].combineScaleRGB != to->unit[i].combineScaleRGB)
490 {
491 pState->diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[i].combineScaleRGB);
492 FILLDIRTY(tb->envBit[i]);
493 FILLDIRTY(tb->dirty);
494 }
495 if (from->unit[i].combineScaleA != to->unit[i].combineScaleA)
496 {
497 pState->diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[i].combineScaleA);
498 FILLDIRTY(tb->envBit[i]);
499 FILLDIRTY(tb->dirty);
500 }
501 CLEARDIRTY(tb->envBit[i], nbitID);
502 }
503 }
504
505 /* Resend texture images */
506 if (toCtx->shared->bTexResyncNeeded)
507 {
508 toCtx->shared->bTexResyncNeeded = GL_FALSE;
509
510 crStateDiffAllTextureObjects(toCtx, bitID, GL_TRUE);
511 }
512
513 /* After possible fiddling put them back now */
514 if (activeUnit != toCtx->texture.curTextureUnit) {
515 pState->diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
516 }
517 pState->diff_api.MatrixMode(toCtx->transform.matrixMode);
518}
519
520
521/*
522 * Check the dirty bits for the specified texture on a given unit to
523 * determine if any of its images are dirty.
524 * Return: 1 -- dirty, 0 -- clean
525 */
526int crStateTextureCheckDirtyImages(CRContext *from, CRContext *to, GLenum target, int textureUnit)
527{
528 CRContext *g = GetCurrentContext(from->pStateTracker);
529 CRTextureState *tsto;
530 CRbitvalue *bitID;
531 CRTextureObj *tobj = NULL;
532 int maxLevel = 0, i;
533 int face, numFaces;
534
535 CRASSERT(to);
536 CRASSERT(from);
537 CRASSERT(from->pStateTracker == to->pStateTracker);
538
539 tsto = &(to->texture);
540 bitID = from->bitid;
541
542 CRASSERT(tsto);
543
544 switch(target)
545 {
546 case GL_TEXTURE_1D:
547 tobj = tsto->unit[textureUnit].currentTexture1D;
548 maxLevel = tsto->maxLevel;
549 break;
550 case GL_TEXTURE_2D:
551 tobj = tsto->unit[textureUnit].currentTexture2D;
552 maxLevel = tsto->maxLevel;
553 break;
554#ifdef CR_OPENGL_VERSION_1_2
555 case GL_TEXTURE_3D:
556 tobj = tsto->unit[textureUnit].currentTexture3D;
557 maxLevel = tsto->max3DLevel;
558 break;
559#endif
560#ifdef CR_ARB_texture_cube_map
561 case GL_TEXTURE_CUBE_MAP:
562 if (g->extensions.ARB_texture_cube_map) {
563 tobj = tsto->unit[textureUnit].currentTextureCubeMap;
564 maxLevel = tsto->maxCubeMapLevel;
565 }
566 break;
567#endif
568#ifdef CR_NV_texture_rectangle
569 case GL_TEXTURE_RECTANGLE_NV:
570 if (g->extensions.NV_texture_rectangle) {
571 tobj = tsto->unit[textureUnit].currentTextureRect;
572 maxLevel = 1;
573 }
574 break;
575#endif
576 default:
577 crError("Bad texture target in crStateTextureCheckDirtyImages()");
578 return 0;
579 }
580
581 if (!tobj)
582 {
583 return 0;
584 }
585
586 numFaces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
587
588 for (face = 0; face < numFaces; face++) {
589 for (i = 0; i < maxLevel; i++) {
590 if (CHECKDIRTY(tobj->level[face][i].dirty, bitID))
591 return 1;
592 }
593 }
594
595 return 0;
596}
597
598
599/*
600 * Do texture state differencing for the given texture object.
601 */
602void
603crStateTextureObjectDiff(CRContext *fromCtx,
604 const CRbitvalue *bitID, const CRbitvalue *nbitID,
605 CRTextureObj *tobj, GLboolean alwaysDirty)
606{
607 PCRStateTracker pState = fromCtx->pStateTracker;
608 CRTextureState *from = &(fromCtx->texture);
609 glAble able[2];
610 int u = 0; /* always use texture unit 0 for diff'ing */
611 GLuint hwid = crStateGetTextureObjHWID(pState, tobj);
612
613 if (!hwid)
614 return;
615
616 able[0] = pState->diff_api.Disable;
617 able[1] = pState->diff_api.Enable;
618
619#if 0
620 /* XXX disabling this code fixed Wes Bethel's problem with missing/white
621 * textures. Setting the active texture unit here can screw up the
622 * current texture object bindings.
623 */
624 /* Set active texture unit, and bind this texture object */
625 if (from->curTextureUnit != u) {
626 pState->diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
627 from->curTextureUnit = u;
628 }
629#endif
630
631 pState->diff_api.BindTexture(tobj->target, hwid);
632
633 if (alwaysDirty || CHECKDIRTY(tobj->paramsBit[u], bitID))
634 {
635 GLfloat f[4];
636 f[0] = tobj->borderColor.r;
637 f[1] = tobj->borderColor.g;
638 f[2] = tobj->borderColor.b;
639 f[3] = tobj->borderColor.a;
640 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_BASE_LEVEL, tobj->baseLevel);
641 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAX_LEVEL, tobj->maxLevel);
642 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_MIN_FILTER, tobj->minFilter);
643 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAG_FILTER, tobj->magFilter);
644 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_S, tobj->wrapS);
645 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_T, tobj->wrapT);
646#ifdef CR_OPENGL_VERSION_1_2
647 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_R, tobj->wrapR);
648 pState->diff_api.TexParameterf(tobj->target, GL_TEXTURE_PRIORITY, tobj->priority);
649#endif
650 pState->diff_api.TexParameterfv(tobj->target, GL_TEXTURE_BORDER_COLOR, (const GLfloat *) f);
651#ifdef CR_EXT_texture_filter_anisotropic
652 if (fromCtx->extensions.EXT_texture_filter_anisotropic) {
653 pState->diff_api.TexParameterf(tobj->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, tobj->maxAnisotropy);
654 }
655#endif
656#ifdef CR_ARB_depth_texture
657 if (fromCtx->extensions.ARB_depth_texture)
658 pState->diff_api.TexParameteri(tobj->target, GL_DEPTH_TEXTURE_MODE_ARB, tobj->depthMode);
659#endif
660#ifdef CR_ARB_shadow
661 if (fromCtx->extensions.ARB_shadow) {
662 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_MODE_ARB, tobj->compareMode);
663 pState->diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_FUNC_ARB, tobj->compareFunc);
664 }
665#endif
666#ifdef CR_ARB_shadow_ambient
667 if (fromCtx->extensions.ARB_shadow_ambient) {
668 pState->diff_api.TexParameterf(tobj->target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, tobj->compareFailValue);
669 }
670#endif
671#ifdef CR_SGIS_generate_mipmap
672 if (fromCtx->extensions.SGIS_generate_mipmap) {
673 pState->diff_api.TexParameteri(tobj->target, GL_GENERATE_MIPMAP_SGIS, tobj->generateMipmap);
674 }
675#endif
676 if (!alwaysDirty)
677 CLEARDIRTY(tobj->paramsBit[u], nbitID);
678 }
679
680 /* now, if the texture images are dirty */
681 if (alwaysDirty || CHECKDIRTY(tobj->imageBit, bitID))
682 {
683 int lvl;
684 int face;
685
686 switch (tobj->target)
687 {
688 case GL_TEXTURE_1D:
689 for (lvl = 0; lvl <= from->maxLevel; lvl++)
690 {
691 CRTextureLevel *tl = &(tobj->level[0][lvl]);
692 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
693 {
694 if (tl->generateMipmap) {
695 pState->diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
696 }
697 if (tl->width)
698 {
699 if (tl->compressed) {
700 pState->diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
701 tl->internalFormat, tl->width,
702 tl->border, tl->bytes, tl->img);
703 }
704 else {
705 /* alignment must be one */
706 pState->diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
707 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
708 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
709 pState->diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
710 if (tl->generateMipmap) {
711 pState->diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
712 }
713 pState->diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
714 tl->internalFormat,
715 tl->width, tl->border,
716 tl->format, tl->type, tl->img);
717 }
718 }
719 if (!alwaysDirty)
720 {
721 CLEARDIRTY(tl->dirty, nbitID);
722 }
723#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
724 else
725 {
726 crFree(tl->img);
727 tl->img = NULL;
728 }
729#endif
730 }
731 }
732 break;
733 case GL_TEXTURE_2D:
734 for (lvl = 0; lvl <= from->maxLevel; lvl++)
735 {
736 CRTextureLevel *tl = &(tobj->level[0][lvl]);
737 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
738 {
739 if (tl->generateMipmap) {
740 pState->diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
741 }
742
743 if (tl->width && tl->height)
744 {
745 if (tl->compressed) {
746 pState->diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
747 tl->internalFormat, tl->width,
748 tl->height, tl->border,
749 tl->bytes, tl->img);
750 }
751 else {
752 /* alignment must be one */
753 pState->diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
754 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
755 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
756 pState->diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
757 pState->diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
758 tl->internalFormat,
759 tl->width, tl->height, tl->border,
760 tl->format, tl->type, tl->img);
761 }
762 }
763
764 if (!alwaysDirty)
765 {
766 CLEARDIRTY(tl->dirty, nbitID);
767 }
768#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
769 else
770 {
771 crFree(tl->img);
772 tl->img = NULL;
773 }
774#endif
775 }
776 }
777 break;
778#ifdef CR_OPENGL_VERSION_1_2
779 case GL_TEXTURE_3D:
780 for (lvl = 0; lvl <= from->max3DLevel; lvl++)
781 {
782 CRTextureLevel *tl = &(tobj->level[0][lvl]);
783 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
784 {
785 if (tl->generateMipmap) {
786 pState->diff_api.TexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, 1);
787 }
788
789 if (tl->width && tl->height)
790 {
791 if (tl->compressed) {
792 pState->diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
793 tl->internalFormat, tl->width,
794 tl->height, tl->depth,
795 tl->border, tl->bytes, tl->img);
796 }
797 else {
798 /* alignment must be one */
799 pState->diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
800 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
801 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
802 pState->diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
803 pState->diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
804 tl->internalFormat,
805 tl->width, tl->height, tl->depth,
806 tl->border, tl->format,
807 tl->type, tl->img);
808 }
809 }
810
811 if (!alwaysDirty)
812 {
813 CLEARDIRTY(tl->dirty, nbitID);
814 }
815#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
816 else
817 {
818 crFree(tl->img);
819 tl->img = NULL;
820 }
821#endif
822 }
823 }
824 break;
825#endif
826#ifdef CR_NV_texture_rectangle
827 case GL_TEXTURE_RECTANGLE_NV:
828 /* only one level */
829 for (lvl = 0; lvl <= from->maxRectLevel; lvl++)
830 {
831 CRTextureLevel *tl = &(tobj->level[0][lvl]);
832 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
833 {
834 if (tl->width && tl->height)
835 {
836 if (tl->compressed) {
837 pState->diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
838 tl->internalFormat, tl->width,
839 tl->height, tl->border,
840 tl->bytes, tl->img);
841 }
842 else {
843 /* alignment must be one */
844 pState->diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
845 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
846 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
847 pState->diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
848 pState->diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
849 tl->internalFormat,
850 tl->width, tl->height, tl->border,
851 tl->format, tl->type, tl->img);
852 }
853 }
854
855 if (!alwaysDirty)
856 {
857 CLEARDIRTY(tl->dirty, nbitID);
858 }
859#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
860 else
861 {
862 crFree(tl->img);
863 tl->img = NULL;
864 }
865#endif
866 }
867 }
868 break;
869#endif
870#ifdef CR_ARB_texture_cube_map
871 case GL_TEXTURE_CUBE_MAP_ARB:
872 for (face = 0; face < 6; face++)
873 {
874 const GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
875 for (lvl = 0; lvl <= from->maxCubeMapLevel; lvl++)
876 {
877 CRTextureLevel *tl = &(tobj->level[face][lvl]);
878 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
879 {
880 if (tl->generateMipmap) {
881 pState->diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
882 GL_GENERATE_MIPMAP_SGIS, 1);
883 }
884
885 if (tl->width && tl->height)
886 {
887 if (tl->compressed) {
888 pState->diff_api.CompressedTexImage2DARB(target,
889 lvl, tl->internalFormat,
890 tl->width, tl->height,
891 tl->border, tl->bytes, tl->img);
892 }
893 else {
894 /* alignment must be one */
895 pState->diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
896 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
897 pState->diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
898 pState->diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
899 pState->diff_api.TexImage2D(target, lvl,
900 tl->internalFormat,
901 tl->width, tl->height, tl->border,
902 tl->format, tl->type, tl->img);
903 }
904 }
905
906 if (!alwaysDirty)
907 {
908 CLEARDIRTY(tl->dirty, nbitID);
909 }
910#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
911 else
912 {
913 crFree(tl->img);
914 tl->img = NULL;
915 }
916#endif
917 }
918 } /* for lvl */
919 } /* for face */
920 break;
921#endif
922 default:
923 UNIMPLEMENTED();
924
925 } /* switch */
926 } /* if (CHECKDIRTY(tobj->imageBit, bitID)) */
927}
928
929
930
931void
932crStateTextureDiff( CRTextureBits *tb, CRbitvalue *bitID,
933 CRContext *fromCtx, CRContext *toCtx )
934{
935 PCRStateTracker pState = fromCtx->pStateTracker;
936 CRTextureState *from = &(fromCtx->texture);
937 CRTextureState *to = &(toCtx->texture);
938 unsigned int u, t, j;
939 glAble able[2];
940 CRbitvalue nbitID[CR_MAX_BITARRAY];
941 const GLboolean haveFragProg = fromCtx->extensions.ARB_fragment_program || fromCtx->extensions.NV_fragment_program;
942
943 CRASSERT(fromCtx->pStateTracker == toCtx->pStateTracker);
944
945 for (j=0;j<CR_MAX_BITARRAY;j++)
946 nbitID[j] = ~bitID[j];
947
948 able[0] = pState->diff_api.Disable;
949 able[1] = pState->diff_api.Enable;
950
951 /* loop over texture units */
952 for (u = 0; u < fromCtx->limits.maxTextureUnits; u++)
953 {
954 CRTextureObj **fromBinding = NULL;
955 CRTextureObj *tobj;
956
957 /* take care of enables/disables */
958 if (CHECKDIRTY(tb->enable[u], bitID))
959 {
960
961 /* Activate texture unit u if needed */
962 if (fromCtx->texture.curTextureUnit != u) {
963 pState->diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
964 fromCtx->texture.curTextureUnit = u;
965 }
966
967 if (from->unit[u].enabled1D != to->unit[u].enabled1D)
968 {
969 able[to->unit[u].enabled1D](GL_TEXTURE_1D);
970 from->unit[u].enabled1D = to->unit[u].enabled1D;
971 }
972 if (from->unit[u].enabled2D != to->unit[u].enabled2D)
973 {
974 able[to->unit[u].enabled2D](GL_TEXTURE_2D);
975 from->unit[u].enabled2D = to->unit[u].enabled2D;
976 }
977#ifdef CR_OPENGL_VERSION_1_2
978 if (from->unit[u].enabled3D != to->unit[u].enabled3D)
979 {
980 able[to->unit[u].enabled3D](GL_TEXTURE_3D);
981 from->unit[u].enabled3D = to->unit[u].enabled3D;
982 }
983#endif
984#ifdef CR_ARB_texture_cube_map
985 if (fromCtx->extensions.ARB_texture_cube_map &&
986 from->unit[u].enabledCubeMap != to->unit[u].enabledCubeMap)
987 {
988 able[to->unit[u].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
989 from->unit[u].enabledCubeMap = to->unit[u].enabledCubeMap;
990 }
991#endif
992#ifdef CR_NV_texture_rectangle
993 if (fromCtx->extensions.NV_texture_rectangle &&
994 from->unit[u].enabledRect != to->unit[u].enabledRect)
995 {
996 able[to->unit[u].enabledRect](GL_TEXTURE_RECTANGLE_NV);
997 from->unit[u].enabledRect = to->unit[u].enabledRect;
998 }
999#endif
1000
1001 /* texgen enables */
1002 if (from->unit[u].textureGen.s != to->unit[u].textureGen.s ||
1003 from->unit[u].textureGen.t != to->unit[u].textureGen.t ||
1004 from->unit[u].textureGen.r != to->unit[u].textureGen.r ||
1005 from->unit[u].textureGen.q != to->unit[u].textureGen.q)
1006 {
1007 able[to->unit[u].textureGen.s](GL_TEXTURE_GEN_S);
1008 able[to->unit[u].textureGen.t](GL_TEXTURE_GEN_T);
1009 able[to->unit[u].textureGen.r](GL_TEXTURE_GEN_R);
1010 able[to->unit[u].textureGen.q](GL_TEXTURE_GEN_Q);
1011 from->unit[u].textureGen = to->unit[u].textureGen;
1012 }
1013 CLEARDIRTY(tb->enable[u], nbitID);
1014 }
1015
1016
1017 /* Texgen coefficients */
1018 if (CHECKDIRTY(tb->objGen[u], bitID))
1019 {
1020 if (fromCtx->texture.curTextureUnit != u) {
1021 pState->diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1022 fromCtx->texture.curTextureUnit = u;
1023 }
1024 if (from->unit[u].objSCoeff.x != to->unit[u].objSCoeff.x ||
1025 from->unit[u].objSCoeff.y != to->unit[u].objSCoeff.y ||
1026 from->unit[u].objSCoeff.z != to->unit[u].objSCoeff.z ||
1027 from->unit[u].objSCoeff.w != to->unit[u].objSCoeff.w)
1028 {
1029 GLfloat f[4];
1030 f[0] = to->unit[u].objSCoeff.x;
1031 f[1] = to->unit[u].objSCoeff.y;
1032 f[2] = to->unit[u].objSCoeff.z;
1033 f[3] = to->unit[u].objSCoeff.w;
1034 pState->diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
1035 from->unit[u].objSCoeff = to->unit[u].objSCoeff;
1036 }
1037 if (from->unit[u].objTCoeff.x != to->unit[u].objTCoeff.x ||
1038 from->unit[u].objTCoeff.y != to->unit[u].objTCoeff.y ||
1039 from->unit[u].objTCoeff.z != to->unit[u].objTCoeff.z ||
1040 from->unit[u].objTCoeff.w != to->unit[u].objTCoeff.w)
1041 {
1042 GLfloat f[4];
1043 f[0] = to->unit[u].objTCoeff.x;
1044 f[1] = to->unit[u].objTCoeff.y;
1045 f[2] = to->unit[u].objTCoeff.z;
1046 f[3] = to->unit[u].objTCoeff.w;
1047 pState->diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
1048 from->unit[u].objTCoeff = to->unit[u].objTCoeff;
1049 }
1050 if (from->unit[u].objRCoeff.x != to->unit[u].objRCoeff.x ||
1051 from->unit[u].objRCoeff.y != to->unit[u].objRCoeff.y ||
1052 from->unit[u].objRCoeff.z != to->unit[u].objRCoeff.z ||
1053 from->unit[u].objRCoeff.w != to->unit[u].objRCoeff.w)
1054 {
1055 GLfloat f[4];
1056 f[0] = to->unit[u].objRCoeff.x;
1057 f[1] = to->unit[u].objRCoeff.y;
1058 f[2] = to->unit[u].objRCoeff.z;
1059 f[3] = to->unit[u].objRCoeff.w;
1060 pState->diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
1061 from->unit[u].objRCoeff = to->unit[u].objRCoeff;
1062 }
1063 if (from->unit[u].objQCoeff.x != to->unit[u].objQCoeff.x ||
1064 from->unit[u].objQCoeff.y != to->unit[u].objQCoeff.y ||
1065 from->unit[u].objQCoeff.z != to->unit[u].objQCoeff.z ||
1066 from->unit[u].objQCoeff.w != to->unit[u].objQCoeff.w)
1067 {
1068 GLfloat f[4];
1069 f[0] = to->unit[u].objQCoeff.x;
1070 f[1] = to->unit[u].objQCoeff.y;
1071 f[2] = to->unit[u].objQCoeff.z;
1072 f[3] = to->unit[u].objQCoeff.w;
1073 pState->diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
1074 from->unit[u].objQCoeff = to->unit[u].objQCoeff;
1075 }
1076 CLEARDIRTY(tb->objGen[u], nbitID);
1077 }
1078 if (CHECKDIRTY(tb->eyeGen[u], bitID))
1079 {
1080 if (fromCtx->texture.curTextureUnit != u) {
1081 pState->diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1082 fromCtx->texture.curTextureUnit = u;
1083 }
1084 if (fromCtx->transform.matrixMode != GL_MODELVIEW) {
1085 pState->diff_api.MatrixMode(GL_MODELVIEW);
1086 fromCtx->transform.matrixMode = GL_MODELVIEW;
1087 }
1088 pState->diff_api.PushMatrix();
1089 pState->diff_api.LoadIdentity();
1090 if (from->unit[u].eyeSCoeff.x != to->unit[u].eyeSCoeff.x ||
1091 from->unit[u].eyeSCoeff.y != to->unit[u].eyeSCoeff.y ||
1092 from->unit[u].eyeSCoeff.z != to->unit[u].eyeSCoeff.z ||
1093 from->unit[u].eyeSCoeff.w != to->unit[u].eyeSCoeff.w)
1094 {
1095 GLfloat f[4];
1096 f[0] = to->unit[u].eyeSCoeff.x;
1097 f[1] = to->unit[u].eyeSCoeff.y;
1098 f[2] = to->unit[u].eyeSCoeff.z;
1099 f[3] = to->unit[u].eyeSCoeff.w;
1100 pState->diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
1101 from->unit[u].eyeSCoeff = to->unit[u].eyeSCoeff;
1102 }
1103 if (from->unit[u].eyeTCoeff.x != to->unit[u].eyeTCoeff.x ||
1104 from->unit[u].eyeTCoeff.y != to->unit[u].eyeTCoeff.y ||
1105 from->unit[u].eyeTCoeff.z != to->unit[u].eyeTCoeff.z ||
1106 from->unit[u].eyeTCoeff.w != to->unit[u].eyeTCoeff.w)
1107 {
1108 GLfloat f[4];
1109 f[0] = to->unit[u].eyeTCoeff.x;
1110 f[1] = to->unit[u].eyeTCoeff.y;
1111 f[2] = to->unit[u].eyeTCoeff.z;
1112 f[3] = to->unit[u].eyeTCoeff.w;
1113 pState->diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
1114 from->unit[u].eyeTCoeff = to->unit[u].eyeTCoeff;
1115 }
1116 if (from->unit[u].eyeRCoeff.x != to->unit[u].eyeRCoeff.x ||
1117 from->unit[u].eyeRCoeff.y != to->unit[u].eyeRCoeff.y ||
1118 from->unit[u].eyeRCoeff.z != to->unit[u].eyeRCoeff.z ||
1119 from->unit[u].eyeRCoeff.w != to->unit[u].eyeRCoeff.w)
1120 {
1121 GLfloat f[4];
1122 f[0] = to->unit[u].eyeRCoeff.x;
1123 f[1] = to->unit[u].eyeRCoeff.y;
1124 f[2] = to->unit[u].eyeRCoeff.z;
1125 f[3] = to->unit[u].eyeRCoeff.w;
1126 pState->diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
1127 from->unit[u].eyeRCoeff = to->unit[u].eyeRCoeff;
1128 }
1129 if (from->unit[u].eyeQCoeff.x != to->unit[u].eyeQCoeff.x ||
1130 from->unit[u].eyeQCoeff.y != to->unit[u].eyeQCoeff.y ||
1131 from->unit[u].eyeQCoeff.z != to->unit[u].eyeQCoeff.z ||
1132 from->unit[u].eyeQCoeff.w != to->unit[u].eyeQCoeff.w)
1133 {
1134 GLfloat f[4];
1135 f[0] = to->unit[u].eyeQCoeff.x;
1136 f[1] = to->unit[u].eyeQCoeff.y;
1137 f[2] = to->unit[u].eyeQCoeff.z;
1138 f[3] = to->unit[u].eyeQCoeff.w;
1139 pState->diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
1140 from->unit[u].eyeQCoeff = to->unit[u].eyeQCoeff;
1141 }
1142 pState->diff_api.PopMatrix();
1143 CLEARDIRTY(tb->eyeGen[u], nbitID);
1144 }
1145 if (CHECKDIRTY(tb->genMode[u], bitID))
1146 {
1147 if (fromCtx->texture.curTextureUnit != u) {
1148 pState->diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1149 fromCtx->texture.curTextureUnit = u;
1150 }
1151 if (from->unit[u].gen.s != to->unit[u].gen.s ||
1152 from->unit[u].gen.t != to->unit[u].gen.t ||
1153 from->unit[u].gen.r != to->unit[u].gen.r ||
1154 from->unit[u].gen.q != to->unit[u].gen.q)
1155 {
1156 pState->diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[u].gen.s);
1157 pState->diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[u].gen.t);
1158 pState->diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[u].gen.r);
1159 pState->diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[u].gen.q);
1160 from->unit[u].gen = to->unit[u].gen;
1161 }
1162 CLEARDIRTY(tb->genMode[u], nbitID);
1163 }
1164
1165 /* Texture enviroment */
1166 if (CHECKDIRTY(tb->envBit[u], bitID))
1167 {
1168 if (from->unit[u].envMode != to->unit[u].envMode)
1169 {
1170 pState->diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[u].envMode);
1171 from->unit[u].envMode = to->unit[u].envMode;
1172 }
1173 if (from->unit[u].envColor.r != to->unit[u].envColor.r ||
1174 from->unit[u].envColor.g != to->unit[u].envColor.g ||
1175 from->unit[u].envColor.b != to->unit[u].envColor.b ||
1176 from->unit[u].envColor.a != to->unit[u].envColor.a)
1177 {
1178 GLfloat f[4];
1179 f[0] = to->unit[u].envColor.r;
1180 f[1] = to->unit[u].envColor.g;
1181 f[2] = to->unit[u].envColor.b;
1182 f[3] = to->unit[u].envColor.a;
1183 pState->diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
1184 from->unit[u].envColor = to->unit[u].envColor;
1185 }
1186#ifdef CR_ARB_texture_env_combine
1187 if (from->unit[u].combineModeRGB != to->unit[u].combineModeRGB)
1188 {
1189 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[u].combineModeRGB);
1190 from->unit[u].combineModeRGB = to->unit[u].combineModeRGB;
1191 }
1192 if (from->unit[u].combineModeA != to->unit[u].combineModeA)
1193 {
1194 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[u].combineModeA);
1195 from->unit[u].combineModeA = to->unit[u].combineModeA;
1196 }
1197 if (from->unit[u].combineSourceRGB[0] != to->unit[u].combineSourceRGB[0])
1198 {
1199 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[u].combineSourceRGB[0]);
1200 from->unit[u].combineSourceRGB[0] = to->unit[u].combineSourceRGB[0];
1201 }
1202 if (from->unit[u].combineSourceRGB[1] != to->unit[u].combineSourceRGB[1])
1203 {
1204 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[u].combineSourceRGB[1]);
1205 from->unit[u].combineSourceRGB[1] = to->unit[u].combineSourceRGB[1];
1206 }
1207 if (from->unit[u].combineSourceRGB[2] != to->unit[u].combineSourceRGB[2])
1208 {
1209 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[u].combineSourceRGB[2]);
1210 from->unit[u].combineSourceRGB[2] = to->unit[u].combineSourceRGB[2];
1211 }
1212 if (from->unit[u].combineSourceA[0] != to->unit[u].combineSourceA[0])
1213 {
1214 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[u].combineSourceA[0]);
1215 from->unit[u].combineSourceA[0] = to->unit[u].combineSourceA[0];
1216 }
1217 if (from->unit[u].combineSourceA[1] != to->unit[u].combineSourceA[1])
1218 {
1219 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[u].combineSourceA[1]);
1220 from->unit[u].combineSourceA[1] = to->unit[u].combineSourceA[1];
1221 }
1222 if (from->unit[u].combineSourceA[2] != to->unit[u].combineSourceA[2])
1223 {
1224 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[u].combineSourceA[2]);
1225 from->unit[u].combineSourceA[2] = to->unit[u].combineSourceA[2];
1226 }
1227 if (from->unit[u].combineOperandRGB[0] != to->unit[u].combineOperandRGB[0])
1228 {
1229 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[u].combineOperandRGB[0]);
1230 from->unit[u].combineOperandRGB[0] = to->unit[u].combineOperandRGB[0];
1231 }
1232 if (from->unit[u].combineOperandRGB[1] != to->unit[u].combineOperandRGB[1])
1233 {
1234 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[u].combineOperandRGB[1]);
1235 from->unit[u].combineOperandRGB[1] = to->unit[u].combineOperandRGB[1];
1236 }
1237 if (from->unit[u].combineOperandRGB[2] != to->unit[u].combineOperandRGB[2])
1238 {
1239 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[u].combineOperandRGB[2]);
1240 from->unit[u].combineOperandRGB[2] = to->unit[u].combineOperandRGB[2];
1241 }
1242 if (from->unit[u].combineOperandA[0] != to->unit[u].combineOperandA[0])
1243 {
1244 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[u].combineOperandA[0]);
1245 from->unit[u].combineOperandA[0] = to->unit[u].combineOperandA[0];
1246 }
1247 if (from->unit[u].combineOperandA[1] != to->unit[u].combineOperandA[1])
1248 {
1249 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[u].combineOperandA[1]);
1250 from->unit[u].combineOperandA[1] = to->unit[u].combineOperandA[1];
1251 }
1252 if (from->unit[u].combineOperandA[2] != to->unit[u].combineOperandA[2])
1253 {
1254 pState->diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[u].combineOperandA[2]);
1255 from->unit[u].combineOperandA[2] = to->unit[u].combineOperandA[2];
1256 }
1257 if (from->unit[u].combineScaleRGB != to->unit[u].combineScaleRGB)
1258 {
1259 pState->diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[u].combineScaleRGB);
1260 from->unit[u].combineScaleRGB = to->unit[u].combineScaleRGB;
1261 }
1262 if (from->unit[u].combineScaleA != to->unit[u].combineScaleA)
1263 {
1264 pState->diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[u].combineScaleA);
1265 from->unit[u].combineScaleA = to->unit[u].combineScaleA;
1266 }
1267#endif
1268#if CR_EXT_texture_lod_bias
1269 if (from->unit[u].lodBias != to->unit[u].lodBias)
1270 {
1271 pState->diff_api.TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, to->unit[u].lodBias);
1272 from->unit[u].lodBias = to->unit[u].lodBias;
1273 }
1274#endif
1275 CLEARDIRTY(tb->envBit[u], nbitID);
1276 }
1277
1278 /* loop over texture targets */
1279 for (t = 0; t < 5; t++)
1280 {
1281 tobj = NULL;
1282
1283 switch (t) {
1284 case 0:
1285 if (to->unit[u].enabled1D || haveFragProg) {
1286 tobj = to->unit[u].currentTexture1D;
1287 fromBinding = &(from->unit[u].currentTexture1D);
1288 }
1289 break;
1290 case 1:
1291 if (to->unit[u].enabled2D || haveFragProg) {
1292 tobj = to->unit[u].currentTexture2D;
1293 fromBinding = &(from->unit[u].currentTexture2D);
1294 }
1295 break;
1296#ifdef CR_OPENGL_VERSION_1_2
1297 case 2:
1298 if (to->unit[u].enabled3D || haveFragProg) {
1299 tobj = to->unit[u].currentTexture3D;
1300 fromBinding = &(from->unit[u].currentTexture3D);
1301 }
1302 break;
1303#endif
1304#ifdef CR_ARB_texture_cube_map
1305 case 3:
1306 if (fromCtx->extensions.ARB_texture_cube_map &&
1307 (to->unit[u].enabledCubeMap || haveFragProg)) {
1308 tobj = to->unit[u].currentTextureCubeMap;
1309 fromBinding = &(from->unit[u].currentTextureCubeMap);
1310 }
1311 break;
1312#endif
1313#ifdef CR_NV_texture_rectangle
1314 case 4:
1315 if (fromCtx->extensions.NV_texture_rectangle &&
1316 (to->unit[u].enabledRect || haveFragProg)) {
1317 tobj = to->unit[u].currentTextureRect;
1318 fromBinding = &(from->unit[u].currentTextureRect);
1319 }
1320 break;
1321#endif
1322 default:
1323 /* maybe don't support cube maps or rects */
1324 continue;
1325 }
1326
1327 if (!tobj) {
1328 continue; /* with next target */
1329 }
1330
1331 /* Activate texture unit u if needed */
1332 if (fromCtx->texture.curTextureUnit != u) {
1333 pState->diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
1334 fromCtx->texture.curTextureUnit = u;
1335 }
1336
1337 /* bind this texture if needed */
1338 if (CHECKDIRTY(tb->current[u], bitID))
1339 {
1340 if (*fromBinding != tobj)
1341 {
1342 pState->diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(pState, tobj));
1343 *fromBinding = tobj;
1344 }
1345 }
1346
1347 /* now, if the texture object is dirty */
1348 if (CHECKDIRTY(tobj->dirty, bitID))
1349 {
1350 crStateTextureObjectDiff(fromCtx, bitID, nbitID, tobj, GL_FALSE);
1351 }
1352 CLEARDIRTY(tobj->dirty, nbitID);
1353
1354 } /* loop over targets */
1355
1356 CLEARDIRTY(tb->current[u], nbitID);
1357
1358 } /* loop over units */
1359
1360 /* After possible fiddling with the active unit, put it back now */
1361 if (fromCtx->texture.curTextureUnit != toCtx->texture.curTextureUnit) {
1362 pState->diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
1363 fromCtx->texture.curTextureUnit = toCtx->texture.curTextureUnit;
1364 }
1365 if (fromCtx->transform.matrixMode != toCtx->transform.matrixMode) {
1366 pState->diff_api.MatrixMode(toCtx->transform.matrixMode);
1367 fromCtx->transform.matrixMode = toCtx->transform.matrixMode;
1368 }
1369
1370 CLEARDIRTY(tb->dirty, nbitID);
1371}
1372
1373
1374
1375struct callback_info
1376{
1377 CRbitvalue *bitID, *nbitID;
1378 CRContext *g;
1379 GLboolean bForceUpdate;
1380};
1381
1382
1383/* Called by crHashtableWalk() below */
1384static void
1385DiffTextureObjectCallback( unsigned long key, void *texObj , void *cbData)
1386{
1387 struct callback_info *info = (struct callback_info *) cbData;
1388 CRTextureObj *tobj = (CRTextureObj *) texObj;
1389 (void)key;
1390
1391 /*
1392 printf(" Checking %d 0x%x bitid=0x%x\n",tobj->name, tobj->dirty[0], info->bitID[0]);
1393 */
1394 if (info->bForceUpdate || CHECKDIRTY(tobj->dirty, info->bitID)) {
1395 /*
1396 printf(" Found Dirty! %d\n", tobj->name);
1397 */
1398 crStateTextureObjectDiff(info->g, info->bitID, info->nbitID, tobj, info->bForceUpdate);
1399 CLEARDIRTY(tobj->dirty, info->nbitID);
1400 }
1401}
1402
1403
1404/*
1405 * This isn't used right now, but will be used in the future to fix some
1406 * potential display list problems. Specifically, if glBindTexture is
1407 * in a display list, we have to be sure that all outstanding texture object
1408 * updates are resolved before the list is called. If we don't, we may
1409 * wind up binding texture objects that are stale.
1410 */
1411void
1412crStateDiffAllTextureObjects( CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate )
1413{
1414 PCRStateTracker pState = g->pStateTracker;
1415 CRbitvalue nbitID[CR_MAX_BITARRAY];
1416 struct callback_info info;
1417 int j;
1418 int origUnit, orig1D, orig2D, orig3D, origCube, origRect;
1419
1420 for (j = 0; j < CR_MAX_BITARRAY; j++)
1421 nbitID[j] = ~bitID[j];
1422
1423 info.bitID = bitID;
1424 info.nbitID = nbitID;
1425 info.g = g;
1426 info.bForceUpdate = bForceUpdate;
1427
1428 /* save current texture bindings */
1429 origUnit = g->texture.curTextureUnit;
1430 orig1D = crStateGetTextureObjHWID(pState, g->texture.unit[0].currentTexture1D);
1431 orig2D = crStateGetTextureObjHWID(pState, g->texture.unit[0].currentTexture2D);
1432 orig3D = crStateGetTextureObjHWID(pState, g->texture.unit[0].currentTexture3D);
1433#ifdef CR_ARB_texture_cube_map
1434 origCube = crStateGetTextureObjHWID(pState, g->texture.unit[0].currentTextureCubeMap);
1435#endif
1436#ifdef CR_NV_texture_rectangle
1437 origRect = crStateGetTextureObjHWID(pState, g->texture.unit[0].currentTextureRect);
1438#endif
1439
1440 /* use texture unit 0 for updates */
1441 pState->diff_api.ActiveTextureARB(GL_TEXTURE0_ARB);
1442
1443 /* diff all the textures */
1444 crHashtableWalk(g->shared->textureTable, DiffTextureObjectCallback, (void *) &info);
1445
1446 /* default ones */
1447 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base1D, GL_TRUE);
1448 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base2D, GL_TRUE);
1449 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base3D, GL_TRUE);
1450 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy1D, GL_TRUE);
1451 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy2D, GL_TRUE);
1452 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy3D, GL_TRUE);
1453#ifdef CR_ARB_texture_cube_map
1454 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseCubeMap, GL_TRUE);
1455 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyCubeMap, GL_TRUE);
1456#endif
1457#ifdef CR_NV_texture_rectangle
1458 if (g->extensions.NV_texture_rectangle)
1459 {
1460 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseRect, GL_TRUE);
1461 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyRect, GL_TRUE);
1462 }
1463#endif
1464
1465 /* restore bindings */
1466 /* first restore unit 0 bindings the unit 0 is active currently */
1467 pState->diff_api.BindTexture(GL_TEXTURE_1D, orig1D);
1468 pState->diff_api.BindTexture(GL_TEXTURE_2D, orig2D);
1469 pState->diff_api.BindTexture(GL_TEXTURE_3D, orig3D);
1470#ifdef CR_ARB_texture_cube_map
1471 pState->diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, origCube);
1472#endif
1473#ifdef CR_NV_texture_rectangle
1474 pState->diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, origRect);
1475#endif
1476 /* now restore the proper active unit */
1477 pState->diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + origUnit);
1478}
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