Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

576 lines
18 KiB

  1. /*
  2. ** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #include "devlock.h"
  20. void APIPRIVATE __glim_Accum(GLenum op, GLfloat value)
  21. {
  22. __GLaccumBuffer *fb;
  23. __GL_SETUP();
  24. GLuint beginMode;
  25. void (*accumOp)(__GLaccumBuffer *fb, __GLfloat val);
  26. beginMode = gc->beginMode;
  27. if (beginMode != __GL_NOT_IN_BEGIN) {
  28. if (beginMode == __GL_NEED_VALIDATE) {
  29. (*gc->procs.validate)(gc);
  30. gc->beginMode = __GL_NOT_IN_BEGIN;
  31. __glim_Accum(op,value);
  32. return;
  33. } else {
  34. __glSetError(GL_INVALID_OPERATION);
  35. return;
  36. }
  37. }
  38. fb = &gc->accumBuffer;
  39. if (!gc->modes.accumBits || gc->modes.colorIndexMode) {
  40. __glSetError(GL_INVALID_OPERATION);
  41. return;
  42. }
  43. if (!gc->modes.haveAccumBuffer) {
  44. LazyAllocateAccum(gc);
  45. if (!gc->modes.haveAccumBuffer) // LazyAllocate failed
  46. return;
  47. }
  48. switch (op) {
  49. case GL_ACCUM:
  50. accumOp = fb->accumulate;
  51. break;
  52. case GL_LOAD:
  53. accumOp = fb->load;
  54. break;
  55. case GL_RETURN:
  56. accumOp = fb->ret;
  57. break;
  58. case GL_MULT:
  59. accumOp = fb->mult;
  60. break;
  61. case GL_ADD:
  62. accumOp = fb->add;
  63. break;
  64. default:
  65. __glSetError(GL_INVALID_ENUM);
  66. return;
  67. }
  68. if (gc->renderMode == GL_RENDER) {
  69. BOOL bResetViewportAdj = FALSE;
  70. if (((__GLGENcontext *)gc)->pMcdState) {
  71. //
  72. // MCD does not hook glBitmap, so we go straight to the
  73. // simulations. Therefore, if we are grabbing the device
  74. // lock lazily, we need to grab it now.
  75. //
  76. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc,
  77. COLOR_LOCK_FLAGS)) {
  78. __glSetError(GL_OUT_OF_MEMORY);
  79. return;
  80. }
  81. //
  82. // We may need to temporarily reset the viewport adjust values
  83. // before calling simulations. If GenMcdResetViewportAdj returns
  84. // TRUE, the viewport is changed and we need restore later with
  85. // VP_NOBIAS.
  86. //
  87. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS);
  88. }
  89. (*accumOp)(fb, value);
  90. //
  91. // Restore viewport values if needed.
  92. //
  93. if (bResetViewportAdj)
  94. {
  95. GenMcdResetViewportAdj(gc, VP_NOBIAS);
  96. }
  97. }
  98. }
  99. /************************************************************************/
  100. static void FASTCALL Pick(__GLcontext *gc, __GLaccumBuffer *afb)
  101. {
  102. #ifdef __GL_LINT
  103. gc = gc;
  104. afb = afb;
  105. #endif
  106. }
  107. static void Load32(__GLaccumBuffer* afb, __GLfloat val)
  108. {
  109. __GLcontext *gc = afb->buf.gc;
  110. GLint x0 = gc->transform.clipX0;
  111. GLint y0 = gc->transform.clipY0;
  112. GLint x1 = gc->transform.clipX1;
  113. GLint y1 = gc->transform.clipY1;
  114. GLint w, w4, w1, ow, skip;
  115. GLint redShift, greenShift, blueShift;
  116. GLuint redMask, greenMask, blueMask;
  117. __GLfloat rval, gval, bval;
  118. GLuint *ac;
  119. __GLcolorBuffer *cfb;
  120. __GLcolor *cbuf;
  121. __GLuicolor *shift, *mask, *sign;
  122. __GLcolor cval, *cp;
  123. GLint i;
  124. shift = &afb->shift;
  125. mask = &afb->mask;
  126. sign = &afb->sign;
  127. cval.r = val * afb->redScale;
  128. cval.g = val * afb->greenScale;
  129. cval.b = val * afb->blueScale;
  130. cval.a = val * afb->alphaScale;
  131. w = x1 - x0;
  132. cbuf = (__GLcolor *) gcTempAlloc(gc, w * sizeof(__GLcolor));
  133. if (!cbuf)
  134. return;
  135. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  136. cfb = gc->readBuffer;
  137. ow = w;
  138. w4 = w >> 2;
  139. w1 = w & 3;
  140. skip = afb->buf.outerWidth - w;
  141. for (; y0 < y1; y0++, ac+= skip ) {
  142. __GLcolor *cp = &cbuf[0];
  143. (*cfb->readSpan)(cfb, x0, y0, &cbuf[0], w);
  144. if( ! gc->modes.alphaBits ) {
  145. for( i = 0; i < w; i++, ac++, cp++ ) {
  146. *ac = (((GLuint)(cp->r * cval.r) & mask->r) << shift->r) |
  147. (((GLuint)(cp->g * cval.g) & mask->g) << shift->g) |
  148. (((GLuint)(cp->b * cval.b) & mask->b) << shift->b);
  149. }
  150. } else
  151. // accum buffer has alpha component
  152. for( i = 0; i < w; i++, ac++, cp++ ) {
  153. *ac = (((GLuint)(cp->r * cval.r) & mask->r) << shift->r) |
  154. (((GLuint)(cp->g * cval.g) & mask->g) << shift->g) |
  155. (((GLuint)(cp->b * cval.b) & mask->b) << shift->b) |
  156. (((GLuint)(cp->a * cval.a) & mask->a) << shift->a);
  157. }
  158. }
  159. gcTempFree(gc, cbuf);
  160. }
  161. // Macros for accumulation operations on color components
  162. #define ACCUM_ACCUM_MASKED_COLOR_COMPONENT( col, fbcol, shift, sign, mask, val) \
  163. col = (*ac >> shift) & mask; \
  164. if (col & sign) \
  165. col |= ~mask; \
  166. col += (GLint) (fbcol * val);
  167. #define ACCUM_ADD_MASKED_COLOR_COMPONENT( col, shift, sign, mask, val) \
  168. col = (*ac >> shift) & mask; \
  169. if (col & sign) \
  170. col |= ~mask; \
  171. col = (GLint) (col + val);
  172. #define ACCUM_MULT_MASKED_COLOR_COMPONENT( col, shift, sign, mask, val) \
  173. col = (*ac >> shift) & mask; \
  174. if (col & sign) \
  175. col |= ~mask; \
  176. col = (GLint) (col * val);
  177. static void Accumulate32(__GLaccumBuffer* afb, __GLfloat val)
  178. {
  179. __GLcontext *gc = afb->buf.gc;
  180. GLint x0 = gc->transform.clipX0;
  181. GLint y0 = gc->transform.clipY0;
  182. GLint x1 = gc->transform.clipX1;
  183. GLint y1 = gc->transform.clipY1;
  184. GLint w, ow, skip, w4, w1;
  185. GLint r, g, b;
  186. GLuint *ac, acVal;
  187. __GLfloat rval, gval, bval;
  188. __GLcolorBuffer *cfb;
  189. __GLcolor *cbuf;
  190. __GLuicolor *shift, *mask, *sign;
  191. __GLcolor cval, *cp;
  192. GLint a;
  193. shift = &afb->shift;
  194. mask = &afb->mask;
  195. sign = &afb->sign;
  196. cval.r = val * afb->redScale;
  197. cval.g = val * afb->greenScale;
  198. cval.b = val * afb->blueScale;
  199. cval.a = val * afb->alphaScale;
  200. w = x1 - x0;
  201. cbuf = (__GLcolor *) gcTempAlloc(gc, w * sizeof(__GLcolor));
  202. if (!cbuf)
  203. return;
  204. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  205. cfb = gc->readBuffer;
  206. ow = w;
  207. skip = afb->buf.outerWidth - w;
  208. for (; y0 < y1; y0++, ac+= skip ) {
  209. (*cfb->readSpan)(cfb, x0, y0, &cbuf[0], ow);
  210. cp = &cbuf[0];
  211. if( ! gc->modes.alphaBits ) {
  212. for( w = ow; w; w--, ac++, cp++ ) {
  213. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( r, cp->r, shift->r, sign->r,
  214. mask->r, cval.r);
  215. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( g, cp->g, shift->g, sign->g,
  216. mask->g, cval.g);
  217. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( b, cp->b, shift->b, sign->b,
  218. mask->b, cval.b);
  219. *ac = ((r & mask->r) << shift->r) |
  220. ((g & mask->g) << shift->g) |
  221. ((b & mask->b) << shift->b);
  222. }
  223. } else {
  224. for( w = ow; w; w--, ac++, cp++ ) {
  225. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( r, cp->r, shift->r, sign->r,
  226. mask->r, cval.r);
  227. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( g, cp->g, shift->g, sign->g,
  228. mask->g, cval.g);
  229. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( b, cp->b, shift->b, sign->b,
  230. mask->b, cval.b);
  231. ACCUM_ACCUM_MASKED_COLOR_COMPONENT( a, cp->a, shift->a, sign->a,
  232. mask->a, cval.a);
  233. *ac = ((r & mask->r) << shift->r) |
  234. ((g & mask->g) << shift->g) |
  235. ((b & mask->b) << shift->b) |
  236. ((a & mask->a) << shift->a);
  237. }
  238. }
  239. }
  240. gcTempFree(gc, cbuf);
  241. }
  242. static void Mult32(__GLaccumBuffer *afb, __GLfloat val)
  243. {
  244. __GLcontext *gc = afb->buf.gc;
  245. GLint x0 = gc->transform.clipX0;
  246. GLint y0 = gc->transform.clipY0;
  247. GLint x1 = gc->transform.clipX1;
  248. GLint y1 = gc->transform.clipY1;
  249. GLint w, w4, w1, skip;
  250. GLuint acVal, *ac;
  251. GLint r, g, b;
  252. __GLuicolor *shift, *mask, *sign;
  253. GLint i;
  254. GLint a;
  255. shift = &afb->shift;
  256. mask = &afb->mask;
  257. sign = &afb->sign;
  258. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  259. w = x1 - x0;
  260. skip = afb->buf.outerWidth - w;
  261. if (val == __glZero) {
  262. /* Zero out the buffers contents */
  263. for (; y0 < y1; y0++) {
  264. GLint ww = w;
  265. while (ww > 0) {
  266. *ac++ = 0;
  267. ww--;
  268. }
  269. ac += skip;
  270. }
  271. return;
  272. }
  273. w4 = w >> 2;
  274. w1 = w & 3;
  275. for (; y0 < y1; y0++, ac+= skip) {
  276. if( ! gc->modes.alphaBits ) {
  277. for( i = 0; i < w; i++, ac++ ) {
  278. ACCUM_MULT_MASKED_COLOR_COMPONENT( r, shift->r, sign->r,
  279. mask->r, val);
  280. ACCUM_MULT_MASKED_COLOR_COMPONENT( g, shift->g, sign->g,
  281. mask->g, val);
  282. ACCUM_MULT_MASKED_COLOR_COMPONENT( b, shift->b, sign->b,
  283. mask->b, val);
  284. *ac = ((r & mask->r) << shift->r) |
  285. ((g & mask->g) << shift->g) |
  286. ((b & mask->b) << shift->b);
  287. }
  288. } else {
  289. for( i = 0; i < w; i++, ac++ ) {
  290. ACCUM_MULT_MASKED_COLOR_COMPONENT( r, shift->r, sign->r,
  291. mask->r, val);
  292. ACCUM_MULT_MASKED_COLOR_COMPONENT( g, shift->g, sign->g,
  293. mask->g, val);
  294. ACCUM_MULT_MASKED_COLOR_COMPONENT( b, shift->b, sign->b,
  295. mask->b, val);
  296. ACCUM_MULT_MASKED_COLOR_COMPONENT( a, shift->a, sign->a,
  297. mask->a, val);
  298. *ac = ((r & mask->r) << shift->r) |
  299. ((g & mask->g) << shift->g) |
  300. ((b & mask->b) << shift->b) |
  301. ((a & mask->a) << shift->a);
  302. }
  303. }
  304. }
  305. }
  306. static void Add32(__GLaccumBuffer *afb, __GLfloat value)
  307. {
  308. __GLcontext *gc = afb->buf.gc;
  309. GLint x0 = gc->transform.clipX0;
  310. GLint y0 = gc->transform.clipY0;
  311. GLint x1 = gc->transform.clipX1;
  312. GLint y1 = gc->transform.clipY1;
  313. GLint w, w4, w1, skip;
  314. GLint rval, gval, bval;
  315. GLuint acVal, *ac;
  316. GLint r, g, b;
  317. __GLuicolor *shift, *mask, *sign;
  318. __GLicolor cval;
  319. GLint i;
  320. GLint a;
  321. shift = &afb->shift;
  322. mask = &afb->mask;
  323. sign = &afb->sign;
  324. cval.r = (GLint)
  325. (value * gc->frontBuffer.redScale * afb->redScale + __glHalf);
  326. cval.g = (GLint)
  327. (value * gc->frontBuffer.greenScale * afb->greenScale + __glHalf);
  328. cval.b = (GLint)
  329. (value * gc->frontBuffer.blueScale * afb->blueScale + __glHalf);
  330. cval.a = (GLint)
  331. (value * gc->frontBuffer.alphaScale * afb->alphaScale + __glHalf);
  332. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  333. w = x1 - x0;
  334. w4 = w >> 2;
  335. w1 = w & 3;
  336. skip = afb->buf.outerWidth - w;
  337. for (; y0 < y1; y0++, ac+= skip) {
  338. if( ! gc->modes.alphaBits ) {
  339. for( i = 0; i < w; i++, ac++ ) {
  340. ACCUM_ADD_MASKED_COLOR_COMPONENT( r, shift->r, sign->r,
  341. mask->r, cval.r);
  342. ACCUM_ADD_MASKED_COLOR_COMPONENT( g, shift->g, sign->g,
  343. mask->g, cval.g);
  344. ACCUM_ADD_MASKED_COLOR_COMPONENT( b, shift->b, sign->b,
  345. mask->b, cval.b);
  346. *ac = ((r & mask->r) << shift->r) |
  347. ((g & mask->g) << shift->g) |
  348. ((b & mask->b) << shift->b);
  349. }
  350. } else {
  351. for( i = 0; i < w; i++, ac++ ) {
  352. ACCUM_ADD_MASKED_COLOR_COMPONENT( r, shift->r, sign->r,
  353. mask->r, cval.r);
  354. ACCUM_ADD_MASKED_COLOR_COMPONENT( g, shift->g, sign->g,
  355. mask->g, cval.g);
  356. ACCUM_ADD_MASKED_COLOR_COMPONENT( b, shift->b, sign->b,
  357. mask->b, cval.b);
  358. ACCUM_ADD_MASKED_COLOR_COMPONENT( a, shift->a, sign->a,
  359. mask->a, cval.a);
  360. *ac = ((r & mask->r) << shift->r) |
  361. ((g & mask->g) << shift->g) |
  362. ((b & mask->b) << shift->b) |
  363. ((a & mask->a) << shift->a);
  364. }
  365. }
  366. }
  367. }
  368. static void Return32(__GLaccumBuffer* afb, __GLfloat val)
  369. {
  370. __GLcontext *gc = afb->buf.gc;
  371. GLint x0 = gc->transform.clipX0;
  372. GLint y0 = gc->transform.clipY0;
  373. GLint x1 = gc->transform.clipX1;
  374. GLint y1 = gc->transform.clipY1;
  375. GLint w, next;
  376. GLuint *ac;
  377. __GLcolorBuffer *cfb;
  378. __GLcolorBuffer *cfb2;
  379. __GLfragment frag;
  380. __GLcolor *pAccumCol;
  381. // The returnspan routines use FTOL
  382. FPU_SAVE_MODE();
  383. FPU_CHOP_ON_PREC_LOW();
  384. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  385. w = x1 - x0;
  386. next = afb->buf.outerWidth;
  387. frag.y = y0;
  388. // Preallocate a color buffer for the return span functions
  389. pAccumCol = (__GLcolor *) gcTempAlloc(gc, w * sizeof(__GLcolor));
  390. if( NULL == pAccumCol )
  391. return;
  392. afb->colors = pAccumCol;
  393. if (gc->buffers.doubleStore) {
  394. /* Store to both buffers */
  395. cfb = &gc->frontBuffer;
  396. cfb2 = &gc->backBuffer;
  397. for (; y0 < y1; y0++) {
  398. (*cfb->returnSpan)(cfb, x0, y0, (__GLaccumCell *)ac, val, w);
  399. (*cfb2->returnSpan)(cfb2, x0, y0, (__GLaccumCell *)ac, val, w);
  400. ac += next;
  401. }
  402. } else {
  403. cfb = gc->drawBuffer;
  404. for (; y0 < y1; y0++) {
  405. (*cfb->returnSpan)(cfb, x0, y0, (__GLaccumCell *)ac, val, w);
  406. ac += next;
  407. }
  408. }
  409. FPU_RESTORE_MODE();
  410. gcTempFree( gc, pAccumCol );
  411. }
  412. static void FASTCALL Clear32(__GLaccumBuffer* afb)
  413. {
  414. __GLcontext *gc = afb->buf.gc;
  415. GLint x0 = gc->transform.clipX0;
  416. GLint y0 = gc->transform.clipY0;
  417. GLint y1 = gc->transform.clipY1;
  418. GLint w, w4, w1, skip;
  419. GLuint *ac, acVal;
  420. GLint r, g, b;
  421. __GLcolorBuffer *cfb = &gc->frontBuffer;
  422. __GLcolor *val = &gc->state.accum.clear;
  423. GLint a;
  424. /*
  425. ** Convert abstract color into specific color value.
  426. */
  427. r = (GLint) (val->r * cfb->redScale * afb->redScale);
  428. g = (GLint) (val->g * cfb->greenScale * afb->greenScale);
  429. b = (GLint) (val->b * cfb->blueScale * afb->blueScale);
  430. a = (GLint) (val->a * cfb->alphaScale * afb->alphaScale);
  431. acVal = ((r & afb->mask.r) << afb->shift.r) |
  432. ((g & afb->mask.g) << afb->shift.g) |
  433. ((b & afb->mask.b) << afb->shift.b);
  434. if( gc->modes.alphaBits )
  435. acVal |= (a & afb->mask.a) << afb->shift.a;
  436. ac = __GL_ACCUM_ADDRESS(afb,(GLuint*),x0,y0);
  437. w = gc->transform.clipX1 - x0;
  438. w4 = w >> 2;
  439. w1 = w & 3;
  440. skip = afb->buf.outerWidth - w;
  441. for (; y0 < y1; y0++) {
  442. w = w4;
  443. while (--w >= 0) {
  444. ac[0] = acVal;
  445. ac[1] = acVal;
  446. ac[2] = acVal;
  447. ac[3] = acVal;
  448. ac += 4;
  449. }
  450. w = w1;
  451. while (--w >= 0) {
  452. *ac++ = acVal;
  453. }
  454. ac += skip;
  455. }
  456. }
  457. void FASTCALL __glInitAccum32(__GLcontext *gc, __GLaccumBuffer *afb)
  458. {
  459. __GLGENcontext *gengc;
  460. PIXELFORMATDESCRIPTOR *pfmt;
  461. gengc = (__GLGENcontext *) gc;
  462. pfmt = &gengc->gsurf.pfd;
  463. afb->buf.elementSize = sizeof(GLuint);
  464. afb->buf.gc = gc;
  465. if (gc->modes.rgbMode) {
  466. __GLcolorBuffer *cfb;
  467. __GLfloat redScale, greenScale, blueScale;
  468. __GLfloat alphaScale;
  469. redScale = (__GLfloat) (1 << pfmt->cAccumRedBits)/2 - 1;
  470. greenScale = (__GLfloat) (1 << pfmt->cAccumGreenBits)/2 - 1;
  471. blueScale = (__GLfloat) (1 << pfmt->cAccumBlueBits)/2 - 1;
  472. cfb = &gc->frontBuffer;
  473. afb->redScale = redScale / (cfb->redScale);
  474. afb->greenScale = greenScale / (cfb->greenScale);
  475. afb->blueScale = blueScale / (cfb->blueScale);
  476. afb->alphaScale = (__GLfloat) 1.0;
  477. afb->oneOverRedScale = 1 / afb->redScale;
  478. afb->oneOverGreenScale = 1 / afb->greenScale;
  479. afb->oneOverBlueScale = 1 / afb->blueScale;
  480. afb->oneOverAlphaScale = 1 / afb->alphaScale;
  481. afb->shift.r = 0;
  482. afb->shift.g = pfmt->cAccumRedBits;
  483. afb->shift.b = afb->shift.g + pfmt->cAccumGreenBits;
  484. afb->mask.r = (1 << pfmt->cAccumRedBits) - 1;
  485. afb->mask.g = (1 << pfmt->cAccumGreenBits) - 1;
  486. afb->mask.b = (1 << pfmt->cAccumBlueBits) - 1;
  487. afb->sign.r = 1 << (pfmt->cAccumRedBits - 1);
  488. afb->sign.g = 1 << (pfmt->cAccumGreenBits - 1);
  489. afb->sign.b = 1 << (pfmt->cAccumBlueBits - 1);
  490. if( gc->modes.alphaBits ) {
  491. alphaScale = (__GLfloat) (1 << pfmt->cAccumAlphaBits)/2 - 1;
  492. afb->alphaScale = alphaScale / (cfb->alphaScale);
  493. afb->oneOverAlphaScale = 1 / afb->alphaScale;
  494. afb->shift.a = afb->shift.b + pfmt->cAccumBlueBits;
  495. afb->mask.a = (1 << pfmt->cAccumAlphaBits) - 1;
  496. afb->sign.a = 1 << (pfmt->cAccumAlphaBits - 1);
  497. }
  498. }
  499. afb->pick = Pick;
  500. afb->clear = Clear32;
  501. afb->accumulate = Accumulate32;
  502. afb->load = Load32;
  503. afb->ret = Return32;
  504. afb->mult = Mult32;
  505. afb->add = Add32;
  506. }