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.

2419 lines
77 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: genclear.c
  3. *
  4. * Clear functions.
  5. *
  6. * Created: 01-Dec-1993 16:11:17
  7. * Author: Gilman Wong [gilmanw]
  8. *
  9. * Copyright (c) 1992 Microsoft Corporation
  10. *
  11. \**************************************************************************/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "genci.h"
  15. #include "genrgb.h"
  16. #include "devlock.h"
  17. /******************************Public*Routine******************************\
  18. * __glim_Clear
  19. *
  20. * Generic proc table entry point for glClear. It allocates ancillary buffers
  21. * the first time they are used
  22. *
  23. * History:
  24. * 14-Dec-1993 -by- Eddie Robinson [v-eddier]
  25. * Wrote it.
  26. \**************************************************************************/
  27. void APIPRIVATE __glim_Clear(GLbitfield mask)
  28. {
  29. __GL_SETUP();
  30. GLuint beginMode;
  31. beginMode = gc->beginMode;
  32. if ( beginMode != __GL_NOT_IN_BEGIN )
  33. {
  34. if ( beginMode == __GL_NEED_VALIDATE )
  35. {
  36. (*gc->procs.validate)(gc);
  37. gc->beginMode = __GL_NOT_IN_BEGIN;
  38. __glim_Clear(mask);
  39. return;
  40. }
  41. else
  42. {
  43. __glSetError(GL_INVALID_OPERATION);
  44. return;
  45. }
  46. }
  47. if ( mask & ~(GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT
  48. | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) )
  49. {
  50. __glSetError(GL_INVALID_VALUE);
  51. return;
  52. }
  53. if ( gc->renderMode == GL_RENDER )
  54. {
  55. BOOL bResetViewportAdj = FALSE;
  56. #ifdef _MCD_
  57. // Let MCD have first chance at clearing any of the MCD managed buffers.
  58. if ( ((__GLGENcontext *) (gc))->pMcdState &&
  59. (mask & (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
  60. GL_STENCIL_BUFFER_BIT)) )
  61. {
  62. // Don't attempt to clear depth/stencil buffer if it does not exist.
  63. if ( !gc->modes.depthBits )
  64. mask &= ~GL_DEPTH_BUFFER_BIT;
  65. if ( !gc->modes.stencilBits )
  66. mask &= ~GL_STENCIL_BUFFER_BIT;
  67. // GenMcdClear will clear the mask bits of the buffers it
  68. // successfully cleared.
  69. GenMcdClear((__GLGENcontext *) gc, &mask);
  70. // If simulations are needed for any of the MCD buffers, now is
  71. // the time to grab the device lock.
  72. if (mask & (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
  73. GL_STENCIL_BUFFER_BIT))
  74. {
  75. // Abandon the clear if we cannot acquire the lock.
  76. if (!glsrvLazyGrabSurfaces((__GLGENcontext *) gc,
  77. COLOR_LOCK_FLAGS |
  78. DEPTH_LOCK_FLAGS))
  79. return;
  80. // We may need to temporarily reset the viewport adjust values
  81. // before calling simulations. If GenMcdResetViewportAdj returns
  82. // TRUE, the viewport is changed and we need restore later with
  83. // VP_NOBIAS.
  84. bResetViewportAdj = GenMcdResetViewportAdj(gc, VP_FIXBIAS);
  85. }
  86. }
  87. #endif
  88. if ( mask & GL_COLOR_BUFFER_BIT )
  89. {
  90. // Clear the software alpha buffer here too, as approppriate
  91. switch ( gc->state.raster.drawBuffer )
  92. {
  93. case GL_NONE:
  94. break;
  95. case GL_FRONT:
  96. (*gc->front->clear)(gc->front);
  97. if( ALPHA_BUFFER_WRITE( gc->front ) )
  98. (*gc->front->alphaBuf.clear)(&gc->front->alphaBuf);
  99. break;
  100. case GL_FRONT_AND_BACK:
  101. (*gc->front->clear)(gc->front);
  102. if( ALPHA_BUFFER_WRITE( gc->front ) )
  103. (*gc->front->alphaBuf.clear)(&gc->front->alphaBuf);
  104. // fall through...
  105. case GL_BACK:
  106. if ( gc->modes.doubleBufferMode ) {
  107. (*gc->back->clear)(gc->back);
  108. if( ALPHA_BUFFER_WRITE( gc->back ) )
  109. (*gc->back->alphaBuf.clear)(&gc->back->alphaBuf);
  110. }
  111. break;
  112. #if __GL_NUMBER_OF_AUX_BUFFERS > 0
  113. case GL_AUX0:
  114. case GL_AUX1:
  115. case GL_AUX2:
  116. case GL_AUX3:
  117. i = gc->state.raster.drawBuffer - GL_AUX0;
  118. if ( i < gc->modes.maxAuxBuffers )
  119. (*gc->auxBuffer[i].clear)(&gc->auxBuffer[i]);
  120. break;
  121. #endif
  122. }
  123. }
  124. if ( (mask & GL_DEPTH_BUFFER_BIT) && gc->modes.depthBits )
  125. {
  126. if ( !gc->modes.haveDepthBuffer )
  127. LazyAllocateDepth(gc);
  128. //XXX Any reason we have to check base???
  129. //XXX That doesn't really fit with 3d DDI model! So check haveDepthBuffer
  130. //XXX instead...
  131. if ( gc->modes.haveDepthBuffer )
  132. (*gc->depthBuffer.clear)(&gc->depthBuffer);
  133. }
  134. if ( (mask & GL_ACCUM_BUFFER_BIT) && gc->modes.accumBits )
  135. {
  136. if ( !gc->modes.haveAccumBuffer )
  137. LazyAllocateAccum(gc);
  138. if ( gc->accumBuffer.buf.base )
  139. (*gc->accumBuffer.clear)(&gc->accumBuffer);
  140. }
  141. if ( (mask & GL_STENCIL_BUFFER_BIT) && gc->modes.stencilBits )
  142. {
  143. if ( !gc->modes.haveStencilBuffer )
  144. LazyAllocateStencil(gc);
  145. if ( gc->stencilBuffer.buf.base )
  146. (*gc->stencilBuffer.clear)(&gc->stencilBuffer);
  147. }
  148. // Restore viewport values if needed.
  149. if (bResetViewportAdj)
  150. {
  151. GenMcdResetViewportAdj(gc, VP_NOBIAS);
  152. }
  153. }
  154. }
  155. /******************************Public*Routine******************************\
  156. * InitClearRectangle
  157. *
  158. * If the wndobj is complex, need to start the enumeration
  159. *
  160. * History:
  161. * 23-Jun-1994 Gilman Wong [gilmanw]
  162. * Use cache of clip rectangles.
  163. *
  164. * 24-Jan-1994 -by- Scott Carr [v-scottc]
  165. * Wrote it.
  166. \**************************************************************************/
  167. void FASTCALL InitClearRectangle(GLGENwindow *pwnd, GLint *pEnumState)
  168. {
  169. __GLGENbuffers *buffers = pwnd->buffers;
  170. ASSERTOPENGL(pwnd->clipComplexity == CLC_COMPLEX,
  171. "InitClearRectangle(): not CLC_COMPLEX\n");
  172. #ifndef _CLIENTSIDE_
  173. // Check the uniqueness signature. Note that if the clip cache is
  174. // uninitialized, the clip cache uniqueness is -1 (which is invalid).
  175. if (buffers->clip.WndUniq != buffers->WndUniq)
  176. {
  177. if (buffers->clip.prcl)
  178. (*private->free)(buffers->clip.prcl);
  179. // How many clip rectangles?
  180. buffers->clip.crcl = wglGetClipRects(pwnd, NULL);
  181. // Allocate a new clip cache.
  182. buffers->clip.prcl =
  183. (RECTL *) (*private->malloc)(buffers->clip.crcl * sizeof(RECTL));
  184. if (!buffers->clip.prcl)
  185. {
  186. buffers->clip.crcl = 0;
  187. return;
  188. }
  189. // Get the clip rectangles.
  190. buffers->clip.crcl = wglGetClipRects(pwnd, buffers->clip.prcl);
  191. buffers->clip.WndUniq = buffers->WndUniq;
  192. }
  193. #else
  194. {
  195. // In the client-side case, we don't need to cache rectangles. We already
  196. // have the rectangles cached for direct screen access.
  197. // Just grab a copy of the pointer and count from the
  198. // cached RGNDATA structure in the GLGENwindow.
  199. buffers->clip.crcl = pwnd->prgndat->rdh.nCount;
  200. buffers->clip.prcl = (RECTL *) pwnd->prgndat->Buffer;
  201. buffers->clip.WndUniq = buffers->WndUniq;
  202. }
  203. #endif
  204. *pEnumState = 0;
  205. }
  206. /******************************Public*Routine******************************\
  207. * GetClearSubRectangle
  208. *
  209. * Enumerate the rectangles (inclusive-exclusive) in screen coordinates that
  210. * need to be cleared. If the clipping region is complex, InitClearRectangle
  211. * must be called prior to calling GetClearSubRectangle.
  212. *
  213. * Returns:
  214. * TRUE if there are more clip rectangles, FALSE if no more.
  215. *
  216. * History:
  217. * 23-Jun-1994 Gilman Wong [gilmanw]
  218. * Use cache of clip rectangles.
  219. *
  220. * 03-Dec-1993 -by- Gilman Wong [gilmanw]
  221. * Wrote it.
  222. \**************************************************************************/
  223. GLboolean
  224. GetClearSubRectangle(
  225. __GLcolorBuffer *cfb,
  226. RECTL *prcl,
  227. GLGENwindow *pwnd,
  228. GLint *pEnumState)
  229. {
  230. __GLcontext *gc = cfb->buf.gc;
  231. GLint x, y, x1, y1;
  232. GLboolean retval;
  233. RECTL *prcl2;
  234. // Get the OpenGL clipping rectangle and convert to screen coordinates.
  235. //!!!XXX -- We want to return the clear rectangle as inclusive-exclusive.
  236. //!!!XXX Does the gc->tranform.clip* coordinates represent
  237. //!!!XXX inclusive-exclusive or inclusive-inclusive?
  238. x = gc->transform.clipX0;
  239. y = gc->transform.clipY0;
  240. x1 = gc->transform.clipX1;
  241. y1 = gc->transform.clipY1;
  242. if ((x1 - x == 0) || (y1 - y == 0)) {
  243. prcl->left = prcl->right = 0;
  244. prcl->top = prcl->bottom = 0;
  245. return GL_FALSE;
  246. }
  247. prcl->left = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
  248. prcl->right = __GL_UNBIAS_X(gc, x1) + cfb->buf.xOrigin;
  249. prcl->bottom = __GL_UNBIAS_Y(gc, y1) + cfb->buf.yOrigin;
  250. prcl->top = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
  251. // Now get the windowing system clipping. There are three cases: CLC_TRIVIAL,
  252. // CLC_COMPLEX, and CLC_RECTANGLE.
  253. // CLC_TRIVIAL case -- no clipping, use rclClient.
  254. if (pwnd->clipComplexity == CLC_TRIVIAL)
  255. {
  256. prcl2 = &pwnd->rclClient;
  257. if ((pwnd->rclClient.left == 0) && (pwnd->rclClient.right == 0))
  258. {
  259. prcl->left = prcl->right = 0;
  260. return GL_FALSE;
  261. }
  262. retval = GL_FALSE;
  263. }
  264. // CLC_COMPLEX case -- rectangles have already been enumerated and put into
  265. // the clip cache. The pEnumState parameter tracks current rectangle to be
  266. // enumerated.
  267. else if (pwnd->clipComplexity == CLC_COMPLEX)
  268. {
  269. __GLGENbuffers *buffers = ((__GLGENcontext *)gc)->pwndLocked->buffers;
  270. ASSERTOPENGL(buffers->WndUniq == buffers->clip.WndUniq,
  271. "GetClearSubRectangle(): clip cache is dirty\n");
  272. if (*pEnumState < buffers->clip.crcl)
  273. {
  274. prcl2 = &buffers->clip.prcl[*pEnumState];
  275. *pEnumState += 1;
  276. retval = (*pEnumState < buffers->clip.crcl);
  277. }
  278. else
  279. {
  280. RIP("GetClearSubRectangle(): no more rectangles!\n");
  281. prcl->left = prcl->right = 0;
  282. return GL_FALSE;
  283. }
  284. }
  285. // CLC_RECT case -- only one rectangle, use rclBounds.
  286. else
  287. {
  288. ASSERTOPENGL(pwnd->clipComplexity == CLC_RECT,
  289. "Unexpected clipComplexity\n");
  290. prcl2 = &pwnd->rclBounds;
  291. if ((pwnd->rclBounds.left == 0) && (pwnd->rclBounds.right == 0))
  292. {
  293. prcl->left = prcl->right = 0;
  294. return GL_FALSE;
  295. }
  296. retval = GL_FALSE;
  297. }
  298. // Sanity check the rectangle.
  299. ASSERTOPENGL(
  300. (prcl2->right - prcl2->left) <= __GL_MAX_WINDOW_WIDTH
  301. && (prcl2->bottom - prcl2->top) <= __GL_MAX_WINDOW_HEIGHT,
  302. "GetClearSubRectangle(): bad visible rect size\n"
  303. );
  304. // Need to take intersection of prcl & prcl2.
  305. if (prcl2->left > prcl->left)
  306. prcl->left = prcl2->left;
  307. if (prcl2->right < prcl->right)
  308. prcl->right = prcl2->right;
  309. if (prcl2->top > prcl->top)
  310. prcl->top = prcl2->top;
  311. if (prcl2->bottom < prcl->bottom)
  312. prcl->bottom = prcl2->bottom;
  313. if ((prcl->left >= prcl->right) || (prcl->top >= prcl->bottom))
  314. prcl->left = prcl->right = 0; // empty inclusive-exclusive rect
  315. return retval;
  316. }
  317. /******************************Public*Routine******************************\
  318. * ScrnRGBCIReadSpan
  319. *
  320. * Reads a span of RGB, and converts to ColorIndex
  321. *
  322. * History:
  323. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  324. * Wrote it.
  325. \**************************************************************************/
  326. void
  327. ScrnRGBCIReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, GLuint *pResults,
  328. GLint w, GLboolean bDIB)
  329. {
  330. __GLcontext *gc = cfb->buf.gc;
  331. __GLGENcontext *gengc;
  332. GLubyte *puj;
  333. GLint i;
  334. GLuint iColor;
  335. gengc = (__GLGENcontext *)gc;
  336. if (bDIB) {
  337. puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
  338. (y*cfb->buf.outerWidth) + (x * 3));
  339. }
  340. else {
  341. (*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
  342. puj = gengc->ColorsBits;
  343. }
  344. for (i = 0; i < w; i++, puj += 3)
  345. {
  346. iColor = *( (GLuint *) puj) & 0xffffff;
  347. *pResults++ = ColorToIndex( gengc, iColor );
  348. }
  349. }
  350. /******************************Public*Routine******************************\
  351. * ScrnBitfield16CIReadSpan
  352. *
  353. * Reads a span of Bitfield16, and converts to ColorIndex
  354. *
  355. * History:
  356. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  357. * Wrote it.
  358. \**************************************************************************/
  359. void
  360. ScrnBitfield16CIReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
  361. GLuint *pResults, GLint w, GLboolean bDIB)
  362. {
  363. __GLcontext *gc = cfb->buf.gc;
  364. __GLGENcontext *gengc;
  365. GLushort *pus;
  366. GLint i;
  367. GLuint iColor;
  368. gengc = (__GLGENcontext *)gc;
  369. if (bDIB) {
  370. pus = (GLushort *)((ULONG_PTR)cfb->buf.base +
  371. (y*cfb->buf.outerWidth) + (x << 1));
  372. }
  373. else {
  374. (*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
  375. pus = gengc->ColorsBits;
  376. }
  377. for (i = 0; i < w; i++)
  378. {
  379. iColor = *pus++;
  380. *pResults++ = ColorToIndex( gengc, iColor );
  381. }
  382. }
  383. /******************************Public*Routine******************************\
  384. * ScrnBitfield32CIReadSpan
  385. *
  386. * Reads a span of Bitfield32, and converts to ColorIndex
  387. *
  388. * History:
  389. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  390. * Wrote it.
  391. \**************************************************************************/
  392. void
  393. ScrnBitfield32CIReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
  394. GLuint *pResults, GLint w, GLboolean bDIB)
  395. {
  396. __GLcontext *gc = cfb->buf.gc;
  397. __GLGENcontext *gengc;
  398. GLuint *pul;
  399. GLint i;
  400. GLuint iColor;
  401. gengc = (__GLGENcontext *)gc;
  402. if (bDIB) {
  403. pul = (GLuint *)((ULONG_PTR)cfb->buf.base +
  404. (y*cfb->buf.outerWidth) + (x << 2));
  405. }
  406. else {
  407. (*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
  408. pul = gengc->ColorsBits;
  409. }
  410. for (i = 0; i < w; i++)
  411. {
  412. iColor = *pul++;
  413. *pResults++ = ColorToIndex( gengc, iColor );
  414. }
  415. }
  416. /******************************Public*Routine******************************\
  417. * CalcDitherMatrix
  418. *
  419. * Calculate the 16 element dither matrix, or return FALSE if dithering
  420. * would have no effect.
  421. *
  422. * History:
  423. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  424. * Wrote it.
  425. \**************************************************************************/
  426. GLboolean
  427. CalcDitherMatrix( __GLcolorBuffer *cfb, GLboolean bRGBA, GLboolean bMasking,
  428. GLboolean bBitfield16, GLubyte *mDither )
  429. {
  430. __GLcontext *gc = cfb->buf.gc;
  431. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  432. UINT i, j; // indices into the dither array
  433. GLushort result; // dithered color value (in 332 RGB)
  434. __GLcolor *clear;
  435. GLfloat inc = DITHER_INC(15); // largest dither increment
  436. GLushort *msDither = (GLushort *) mDither;
  437. GLuint *pTrans = (GLuint *) (gengc->pajTranslateVector + 1);
  438. // see if we can ignore dithering altogether
  439. if( bRGBA ) {
  440. clear = &gc->state.raster.clear;
  441. if( ((BYTE)(clear->r*gc->frontBuffer.redScale) ==
  442. (BYTE)(clear->r*gc->frontBuffer.redScale + inc)) &&
  443. ((BYTE)(clear->g*gc->frontBuffer.greenScale) ==
  444. (BYTE)(clear->g*gc->frontBuffer.greenScale + inc)) &&
  445. ((BYTE)(clear->b*gc->frontBuffer.blueScale) ==
  446. (BYTE)(clear->b*gc->frontBuffer.blueScale + inc)) ) {
  447. return GL_FALSE;
  448. }
  449. }
  450. else { // Color Index (cast to short so works for up to 16-bit)
  451. if( (GLushort) (gc->state.raster.clearIndex) ==
  452. (GLushort) (gc->state.raster.clearIndex + inc)) {
  453. return GL_FALSE;
  454. }
  455. }
  456. //XXX -- could cache this in the gengc
  457. for (j = 0; j < 4; j++)
  458. {
  459. for (i = 0; i < 4; i++)
  460. {
  461. inc = fDitherIncTable[__GL_DITHER_INDEX(i, j)];
  462. if( bRGBA ) {
  463. result =
  464. ((BYTE)(clear->r*gc->frontBuffer.redScale + inc) <<
  465. cfb->redShift) |
  466. ((BYTE)(clear->g*gc->frontBuffer.greenScale + inc) <<
  467. cfb->greenShift) |
  468. ((BYTE)(clear->b*gc->frontBuffer.blueScale + inc) <<
  469. cfb->blueShift);
  470. }
  471. else {
  472. result = (BYTE) (gc->state.raster.clearIndex + inc);
  473. result &= cfb->redMax;
  474. }
  475. if( bBitfield16 ) {
  476. if( !bMasking ) {
  477. if( bRGBA )
  478. *msDither++ = result;
  479. else
  480. *msDither++ = (GLushort)pTrans[result];
  481. }
  482. else
  483. *msDither++ = (GLushort)(result & cfb->sourceMask);
  484. }
  485. else {
  486. if( !bMasking )
  487. *mDither++ = gengc->pajTranslateVector[(GLubyte)result];
  488. else
  489. *mDither++ = (GLubyte)(result & cfb->sourceMask);
  490. }
  491. }
  492. }
  493. return TRUE;
  494. }
  495. /******************************Public*Routine******************************\
  496. * Index4DitherClear
  497. *
  498. * Clear function for Display 4-bit pixel formats
  499. *
  500. * History:
  501. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  502. * Wrote it.
  503. \**************************************************************************/
  504. void
  505. Index4DitherClear(__GLcolorBuffer *cfb, RECTL *rcl, GLubyte *mDither,
  506. GLboolean bDIB )
  507. {
  508. __GLcontext *gc = cfb->buf.gc;
  509. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  510. UINT cjSpan; // length of span in bytes
  511. GLubyte *pDither; // dithered color, relative to window origin
  512. UINT i, j; // indices into the dither array
  513. GLubyte *puj, *pujStart; // pointer into span buffer
  514. GLint ySpan; // index to window row to clear
  515. GLushort pattern, *pus; // replicatable 4-nibble dither pattern
  516. GLuint lRightByte, // right edge of span that is byte aligned
  517. lLeftByte; // left edge of span that is byte aligned
  518. GLuint cSpanWidth; // span width in pixels
  519. GLuint dithX, dithY; // x,y offsets into dither matrix
  520. GLubyte dithQuad[4]; // dither repetion quad along a span
  521. lLeftByte = (rcl->left + 1) / 2;
  522. lRightByte = rcl->right / 2;
  523. cjSpan = lRightByte - lLeftByte;
  524. cSpanWidth = rcl->right - rcl->left;
  525. if( bDIB )
  526. pujStart = (GLubyte *)
  527. ((ULONG_PTR)cfb->buf.base +
  528. (rcl->top*cfb->buf.outerWidth) + lLeftByte);
  529. // calc dither offset in x,y
  530. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  531. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  532. for (j = 0; (j < 4) && ((rcl->top + j) < (UINT)rcl->bottom); j++)
  533. {
  534. // Arrange the 4-pixel dither repetition pattern in x. This
  535. // pattern is relative to rcl->left.
  536. pDither = mDither + ((dithY+j)&3)*4;
  537. for( i = 0; i < 4; i ++ ) {
  538. dithQuad[i] = pDither[(dithX+i)&3];
  539. }
  540. // Copy the clear pattern into the span buffer.
  541. puj = gengc->ColorsBits;
  542. pus = (GLushort *) puj;
  543. // For every line, we can replicate a 2-byte(4-nibble) pattern
  544. // into the span buffer. This will allow us to quickly output
  545. // the byte aligned portion of the dithered span.
  546. //
  547. // If we are writing to a DIB and the first pixel does not fall
  548. // on a byte boundary, then the buffer will replicate (using
  549. // the dithQuad pattern) the dither pattern:
  550. //
  551. // <dith 1> <dith 2> <dith 3> <dith 0>
  552. //
  553. // (The non-aligned first dither pixel will have to be handled
  554. // separately).
  555. //
  556. // Otherwise (if we are writing to a display managed surface or
  557. // the first pixel does fall on a byte boundary), then the buffer
  558. // will replicate the dither pattern:
  559. //
  560. // <dith 0> <dith 1> <dith 2> <dith 3>
  561. //
  562. // Note -- for a VGA, the layout of the pixels in a ushort is:
  563. //
  564. // | -------------- ushort --------------- |
  565. // | ---- byte 1 ----- | ---- byte 0 ----- |
  566. // <pixel 2> <pixel 3> <pixel 0> <pixel 1>
  567. if( bDIB && (rcl->left & 1) ) { // not on byte boundary
  568. // dither: 1230 pattern: 3012
  569. pattern = (dithQuad[3] << 12) | (dithQuad[0] << 8) |
  570. (dithQuad[1] << 4 ) | (dithQuad[2]);
  571. }
  572. else { // all other cases
  573. // dither: 0123 pattern: 2301
  574. pattern = (dithQuad[2] << 12) | (dithQuad[3] << 8) |
  575. (dithQuad[0] << 4 ) | (dithQuad[1]);
  576. }
  577. // Replicate pattern into ColorsBits (round up to next short)
  578. for( i = (rcl->right - rcl->left + 3)/4; i; i-- ) {
  579. *pus++ = pattern;
  580. }
  581. // Copy the span to the display for every 4th row of the window.
  582. if( bDIB ) {
  583. for (ySpan = rcl->top + j, puj = pujStart;
  584. ySpan < rcl->bottom;
  585. ySpan+=4,
  586. puj = (GLubyte *)((ULONG_PTR)puj + 4*cfb->buf.outerWidth) ) {
  587. RtlCopyMemory_UnalignedDst( puj, gengc->ColorsBits, cjSpan );
  588. }
  589. // Take care of non-byte aligned left edge.
  590. if( rcl->left & 1 ) {
  591. for (ySpan = rcl->top + j, puj = (pujStart-1);
  592. ySpan < rcl->bottom;
  593. ySpan+=4,
  594. puj = (GLubyte *)((ULONG_PTR)puj + 4*cfb->buf.outerWidth) )
  595. *puj = (*puj & 0xf0) | (dithQuad[0] & 0x0f);
  596. }
  597. // Take care of non-byte aligned right edge.
  598. if( rcl->right & 1 ) {
  599. GLuint dindex = ((rcl->right - 1) - cfb->buf.xOrigin)&3;
  600. for (ySpan = rcl->top + j, puj = (pujStart + cjSpan);
  601. ySpan < rcl->bottom;
  602. ySpan+=4,
  603. puj = (GLubyte *)((ULONG_PTR)puj + 4*cfb->buf.outerWidth) )
  604. *puj = (*puj & 0x0f) | (dithQuad[dindex] << 4);
  605. }
  606. pujStart += cfb->buf.outerWidth;
  607. }
  608. else {
  609. for (ySpan = rcl->top + j; ySpan < rcl->bottom; ySpan+=4)
  610. {
  611. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  612. ySpan, cSpanWidth, TRUE);
  613. }
  614. }
  615. }
  616. }
  617. /******************************Public*Routine******************************\
  618. * Index4MaskedClear
  619. *
  620. * Clear function for Index4 Masked clears
  621. *
  622. * History:
  623. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  624. * Wrote it.
  625. \**************************************************************************/
  626. void
  627. Index4MaskedClear(__GLcolorBuffer *cfb, RECTL *rcl, GLubyte index,
  628. GLubyte *mDither)
  629. {
  630. GLint cSpanWidth, ySpan, w;
  631. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  632. GLboolean bDIB;
  633. GLubyte *puj, *puj2;
  634. GLubyte result, pixel, src;
  635. GLubyte *pTrans, *pInvTrans, *clearDither;
  636. GLuint i,j;
  637. GLuint dithX, dithY; // x,y offsets into dither matrix
  638. cSpanWidth = rcl->right - rcl->left;
  639. bDIB = cfb->buf.flags & DIB_FORMAT ? TRUE : FALSE;
  640. pTrans = (GLubyte *) gengc->pajTranslateVector;
  641. pInvTrans = (GLubyte *) gengc->pajInvTranslateVector;
  642. puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base +
  643. (rcl->top*cfb->buf.outerWidth) + (rcl->left>>1))
  644. : gengc->ColorsBits;
  645. if( mDither ) {
  646. // calc dither offset in x,y
  647. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  648. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  649. }
  650. for (ySpan = rcl->top, j=0; ySpan < rcl->bottom; ySpan++, j++) {
  651. i = 0;
  652. if( !bDIB ) {
  653. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  654. ySpan, cSpanWidth, FALSE);
  655. }
  656. if( mDither )
  657. clearDither = mDither + ((dithY + j)&3)*4;
  658. src = (GLubyte)(index & cfb->sourceMask);
  659. w = cSpanWidth;
  660. puj2 = puj;
  661. if ( rcl->left & 1 ) {
  662. result = (GLubyte)(pInvTrans[*puj2 & 0xf] & cfb->destMask);
  663. if( mDither ) {
  664. src = clearDither[dithX];
  665. i++;
  666. }
  667. result = pTrans[src | result];
  668. *puj2++ = (*puj2 & 0xf0) | result;
  669. w--;
  670. }
  671. while( w > 1 ) {
  672. pixel = (GLubyte)(pInvTrans[*puj2 >> 4] & cfb->destMask);
  673. pixel = pTrans[src | pixel];
  674. result = pixel << 4;
  675. pixel = (GLubyte)(pInvTrans[*puj2 & 0x0f] & cfb->destMask);
  676. if( mDither )
  677. src = clearDither[(dithX + i)&3];
  678. pixel = pTrans[src | pixel];
  679. *puj2++ = result | pixel;
  680. w -= 2;
  681. i++;
  682. }
  683. if( w ) {
  684. result = (GLubyte)(pInvTrans[*puj2 >> 4] & cfb->destMask);
  685. if( mDither )
  686. src = clearDither[(dithX + i)&3];
  687. result = pTrans[src | result];
  688. *puj2++ = (*puj2 & 0x0f) | (result << 4);
  689. }
  690. if( !bDIB )
  691. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  692. ySpan, cSpanWidth, TRUE);
  693. if( bDIB ) {
  694. puj += cfb->buf.outerWidth;
  695. }
  696. }
  697. }
  698. /******************************Public*Routine******************************\
  699. * DIBIndex4Clear
  700. *
  701. * Clear function for DIB 4-bit pixel formats
  702. *
  703. * History:
  704. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  705. * Wrote it.
  706. \**************************************************************************/
  707. void FASTCALL DIBIndex4Clear(__GLcolorBuffer *cfb, RECTL *rcl, BYTE clearColor)
  708. {
  709. UINT cjSpan; // length of span in bytes
  710. LONG lRightByte, // right edge of span that is byte aligned
  711. lLeftByte; // left edge of span that is byte aligned
  712. GLubyte *puj, *pujEnd; // pointers into DIB
  713. lLeftByte = (rcl->left + 1) / 2;
  714. lRightByte = rcl->right / 2;
  715. cjSpan = lRightByte - lLeftByte;
  716. // Copy the clear color into the DIB.
  717. puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + lLeftByte);
  718. pujEnd = (GLubyte *)((ULONG_PTR)puj + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  719. // Note: exit condition is (pul != pulEnd) rather than (pul < pulEnd)
  720. // because the DIB may be upside down which means that pul is moving
  721. // "backward" in memory rather than "forward".
  722. for ( ; puj != pujEnd; puj = (GLubyte *)((ULONG_PTR)puj + cfb->buf.outerWidth) )
  723. {
  724. RtlFillMemory((PVOID) puj, cjSpan, clearColor);
  725. }
  726. // Take care of possible 1 nibble overhang on the left.
  727. if ( rcl->left & 1 )
  728. {
  729. // Inclusive-exclusive, so on the left we want to turn on the pixel that
  730. // that is the "right" pixel in the byte.
  731. puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + (rcl->left/2));
  732. pujEnd = (GLubyte *)((ULONG_PTR)puj + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  733. for ( ; puj != pujEnd; puj = (GLubyte *)((ULONG_PTR)puj + cfb->buf.outerWidth) )
  734. *puj = (*puj & 0xf0) | (clearColor & 0x0f);
  735. }
  736. // Take care of possible 1 nibble overhang on the right.
  737. if ( rcl->right & 1 )
  738. {
  739. // Inclusive-exclusive, so on the right we want to turn on the pixel that
  740. // that is the "left" pixel in the byte.
  741. puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + (rcl->right/2));
  742. pujEnd = (GLubyte *)((ULONG_PTR)puj + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  743. for ( ; puj != pujEnd; puj = (GLubyte *)((ULONG_PTR)puj + cfb->buf.outerWidth) )
  744. *puj = (*puj & 0x0f) | (clearColor & 0xf0);
  745. }
  746. }
  747. /******************************Public*Routine******************************\
  748. * Index4Clear
  749. *
  750. * Clear function for all 4-bit pixel formats
  751. *
  752. * History:
  753. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  754. * Wrote it.
  755. \**************************************************************************/
  756. void FASTCALL Index4Clear(__GLcolorBuffer *cfb)
  757. {
  758. __GLcontext *gc = cfb->buf.gc;
  759. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  760. PIXELFORMATDESCRIPTOR *pfmt;
  761. GLubyte clearColor; // clear color in 32BPP format
  762. RECTL rcl; // clear rectangle in screen coord.
  763. GLGENwindow *pwnd;
  764. GLboolean bMoreRects = GL_TRUE;
  765. GLboolean bDither = GL_FALSE;
  766. GLboolean bMasking = (cfb->buf.flags & COLORMASK_ON) != 0;
  767. GLboolean bDIB = (cfb->buf.flags & DIB_FORMAT) != 0;
  768. GLboolean bUseMcdSpans = gengc->pMcdState && !bDIB;
  769. GLboolean bRGBA;
  770. GLubyte ditherMatrix[4][4];
  771. GLint ClipEnumState;
  772. DBGENTRY("Index4Clear\n");
  773. pfmt = &gengc->gsurf.pfd;
  774. bRGBA = (pfmt->iPixelType == PFD_TYPE_RGBA);
  775. /* if dithering enabled, see if we can ignore it, and if not,
  776. precompute a dither matrix
  777. */
  778. if( gc->state.enables.general & __GL_DITHER_ENABLE ) {
  779. bDither = CalcDitherMatrix( cfb, bRGBA, bMasking, GL_FALSE,
  780. (GLubyte *)ditherMatrix );
  781. }
  782. // Convert the clear color to 4BPP format.
  783. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  784. clearColor =
  785. ((BYTE)(gc->state.raster.clear.r*gc->frontBuffer.redScale +
  786. __glHalf) << cfb->redShift) |
  787. ((BYTE)(gc->state.raster.clear.g*gc->frontBuffer.greenScale +
  788. __glHalf) << cfb->greenShift) |
  789. ((BYTE)(gc->state.raster.clear.b*gc->frontBuffer.blueScale +
  790. __glHalf) << cfb->blueShift);
  791. }
  792. else {
  793. clearColor = (BYTE) (gc->state.raster.clearIndex + 0.5F);
  794. clearColor &= cfb->redMax;
  795. }
  796. clearColor = gengc->pajTranslateVector[clearColor];
  797. clearColor = (clearColor << 4) | clearColor;
  798. // Get clear rectangle in screen coordinates.
  799. pwnd = cfb->bitmap->pwnd;
  800. if (pwnd->clipComplexity == CLC_COMPLEX) {
  801. InitClearRectangle(pwnd, &ClipEnumState);
  802. #ifdef LATER
  803. } else if ( !bMasking
  804. && !bDither
  805. && bDIB
  806. && gengc->fDirtyRegionEnabled
  807. && !RECTLISTIsMax(&gengc->rlClear)
  808. && ((GLuint)clearColor == gengc->clearColor)
  809. ) {
  810. //
  811. // use dirty region rects
  812. //
  813. if (!RECTLISTIsEmpty(&gengc->rlClear)) {
  814. PYLIST pylist = gengc->rlClear.pylist;
  815. while (pylist != NULL) {
  816. PXLIST pxlist = pylist->pxlist;
  817. rcl.top = pylist->s;
  818. rcl.bottom = pylist->e;
  819. while (pxlist != NULL) {
  820. rcl.left = pxlist->s;
  821. rcl.right = pxlist->e;
  822. DIBIndex4Clear( cfb, &rcl, clearColor );
  823. pxlist = pxlist->pnext;
  824. }
  825. pylist = pylist->pnext;
  826. }
  827. //
  828. // Union the blt region with the Clear region
  829. // and set the clear region to empty
  830. //
  831. RECTLISTOrAndClear(&gengc->rlBlt, &gengc->rlClear);
  832. }
  833. return;
  834. }
  835. if (gengc->fDirtyRegionEnabled) {
  836. //
  837. // if we come through this path then for some reason we
  838. // are clearing the entire window
  839. //
  840. RECTLISTSetEmpty(&gengc->rlClear);
  841. RECTLISTSetMax(&gengc->rlBlt);
  842. //
  843. // remember the clear color
  844. //
  845. gengc->clearColor = (GLuint)clearColor;
  846. #endif
  847. }
  848. while (bMoreRects)
  849. {
  850. // Must use MCD spans if buffer not accessible as DIB. In such a
  851. // case, window offset has been removed (see GenMcdUpdateBufferInfo),
  852. // so a window relative rectangle is required for the clear. Also,
  853. // because the driver handles clipping, we do not need to enumerate
  854. // rects.
  855. if (bUseMcdSpans) {
  856. rcl.left = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  857. rcl.right = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  858. rcl.bottom = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  859. rcl.top = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  860. bMoreRects = FALSE;
  861. } else
  862. bMoreRects = GetClearSubRectangle(cfb, &rcl, pwnd, &ClipEnumState);
  863. if (rcl.right == rcl.left)
  864. continue;
  865. // Case: no dithering, no masking
  866. if( !bMasking && !bDither ) {
  867. if (bDIB)
  868. DIBIndex4Clear( cfb, &rcl, clearColor );
  869. else if (bUseMcdSpans)
  870. Index4MaskedClear( cfb, &rcl, clearColor, NULL );
  871. else
  872. wglFillRect(gengc, pwnd, &rcl,
  873. (ULONG) clearColor & 0x0000000F);
  874. }
  875. // Case: any masking
  876. else if( bMasking ) {
  877. Index4MaskedClear( cfb, &rcl, clearColor,
  878. bDither ? (GLubyte *)ditherMatrix : NULL );
  879. }
  880. // Case: just dithering
  881. else {
  882. Index4DitherClear(cfb, &rcl, (GLubyte *)ditherMatrix, bDIB );
  883. }
  884. }
  885. }
  886. /******************************Public*Routine******************************\
  887. * Index8DitherClear
  888. *
  889. * Clear device managed surface to the dithered clear color indicated
  890. * in the __GLcolorBuffer.
  891. *
  892. * History:
  893. * 06-Dec-1993 -by- Gilman Wong [gilmanw]
  894. * Wrote it.
  895. \**************************************************************************/
  896. void
  897. Index8DitherClear(__GLcolorBuffer *cfb, RECTL *rcl, GLubyte *mDither,
  898. GLboolean bDIB)
  899. {
  900. __GLcontext *gc = cfb->buf.gc;
  901. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  902. UINT cjSpan; // length of span in bytes
  903. GLubyte *pDither; // dithered color, relative to window origin
  904. UINT i, j; // indices into the dither array
  905. GLubyte *puj, *pujStart; // pointer into span buffer
  906. GLint ySpan; // index to window row to clear
  907. GLuint dithX, dithY; // x,y offsets into dither matrix
  908. GLubyte dithQuad[4]; // dither repetion quad along a span
  909. cjSpan = rcl->right - rcl->left;
  910. if( bDIB )
  911. pujStart = (GLubyte *)
  912. ((ULONG_PTR)cfb->buf.base +
  913. (rcl->top*cfb->buf.outerWidth) + rcl->left);
  914. // calc dither offset in x,y
  915. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  916. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  917. for (j = 0; (j < 4) && ((rcl->top + j) < (UINT)rcl->bottom); j++)
  918. {
  919. // arrange the 4-pixel dither repetition pattern in x
  920. pDither = mDither + ((dithY+j)&3)*4;
  921. for( i = 0; i < 4; i ++ ) {
  922. dithQuad[i] = pDither[(dithX+i)&3];
  923. }
  924. // Copy the clear color into the span buffer.
  925. puj = gengc->ColorsBits;
  926. for (i = cjSpan / 4; i; i--)
  927. {
  928. *puj++ = dithQuad[0];
  929. *puj++ = dithQuad[1];
  930. *puj++ = dithQuad[2];
  931. *puj++ = dithQuad[3];
  932. }
  933. for (i = 0; i < (cjSpan & 3); i++)
  934. {
  935. *puj++ = dithQuad[i];
  936. }
  937. // Copy the span to the display for every 4th row of the window.
  938. //!!!XXX -- It may be worth writing a (*gengc->pfnCopyPixelsN) routine which
  939. //!!!XXX will do the loop in one call. This will save not only call
  940. //!!!XXX overhead but also other engine locking overhead. Something
  941. //!!!XXX like: (*gengc->pfnCopyPixelsN)(hdc, hbm, x, y, w, n, yDelta)
  942. if( bDIB ) {
  943. for (ySpan = rcl->top + j, puj = pujStart;
  944. ySpan < rcl->bottom;
  945. ySpan+=4,
  946. puj = (GLubyte *)((ULONG_PTR)puj + 4*cfb->buf.outerWidth) ) {
  947. RtlCopyMemory_UnalignedDst( puj, gengc->ColorsBits, cjSpan );
  948. }
  949. pujStart += cfb->buf.outerWidth;
  950. }
  951. else {
  952. for (ySpan = rcl->top + j; ySpan < rcl->bottom; ySpan+=4)
  953. {
  954. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  955. ySpan, cjSpan, TRUE);
  956. }
  957. }
  958. }
  959. }
  960. /******************************Public*Routine******************************\
  961. * Index8MaskedClear
  962. *
  963. * Clear function for Index8 Masked clears
  964. * (Also handles dithering when masking on)
  965. *
  966. * History:
  967. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  968. * Wrote it.
  969. \**************************************************************************/
  970. void
  971. Index8MaskedClear(__GLcolorBuffer *cfb, RECTL *rcl, GLubyte index,
  972. GLubyte *mDither)
  973. {
  974. GLint cSpanWidth, ySpan;
  975. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  976. GLboolean bDIB;
  977. GLubyte *puj, *puj2, *pujEnd;
  978. GLubyte result, src;
  979. GLubyte *pTrans, *pInvTrans, *clearDither;
  980. GLuint i,j;
  981. GLuint dithX, dithY; // x,y offsets into dither matrix
  982. cSpanWidth = rcl->right - rcl->left;
  983. bDIB = cfb->buf.flags & DIB_FORMAT ? TRUE : FALSE;
  984. pTrans = (GLubyte *) gengc->pajTranslateVector;
  985. pInvTrans = (GLubyte *) gengc->pajInvTranslateVector;
  986. puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base +
  987. (rcl->top*cfb->buf.outerWidth) + rcl->left)
  988. : gengc->ColorsBits;
  989. pujEnd = puj + cSpanWidth;
  990. src = (GLubyte)(index & cfb->sourceMask);
  991. if( mDither ) {
  992. // calc dither offset in x,y
  993. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  994. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  995. }
  996. for (ySpan = rcl->top, j = 0; ySpan < rcl->bottom; ySpan++, j++) {
  997. if( !bDIB ) {
  998. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  999. ySpan, cSpanWidth, FALSE);
  1000. }
  1001. if( mDither ) {
  1002. clearDither = mDither + ((dithY + j)&3)*4;
  1003. for( puj2 = puj, i = 0; puj2 < pujEnd; puj2++, i++ ) {
  1004. result = (GLubyte)(pInvTrans[*puj2] & cfb->destMask);
  1005. src = clearDither[(dithX + i)&3];
  1006. *puj2 = pTrans[result | src];
  1007. }
  1008. } else {
  1009. for( puj2 = puj, i = 0; puj2 < pujEnd; puj2++, i++ ) {
  1010. result = (GLubyte)(pInvTrans[*puj2] & cfb->destMask);
  1011. *puj2 = pTrans[result | src];
  1012. }
  1013. }
  1014. if( !bDIB )
  1015. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1016. ySpan, cSpanWidth, TRUE);
  1017. if( bDIB ) {
  1018. puj += cfb->buf.outerWidth;
  1019. pujEnd = puj + cSpanWidth;
  1020. }
  1021. }
  1022. }
  1023. /******************************Public*Routine******************************\
  1024. * DIBIndex8Clear
  1025. *
  1026. * Clear function for DIB 8-bit pixel formats
  1027. *
  1028. * History:
  1029. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1030. * Wrote it.
  1031. \**************************************************************************/
  1032. void FASTCALL DIBIndex8Clear(__GLcolorBuffer *cfb, RECTL *rcl, BYTE index)
  1033. {
  1034. int width = rcl->right - rcl->left;
  1035. int height = (rcl->bottom - rcl->top);
  1036. GLubyte *puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + rcl->left);
  1037. GLubyte *pujEnd;
  1038. if (cfb->buf.outerWidth > 0) {
  1039. if (width == cfb->buf.outerWidth) {
  1040. RtlFillMemory((PVOID) puj, width * height, index);
  1041. return;
  1042. }
  1043. } else {
  1044. if (width == -cfb->buf.outerWidth) {
  1045. RtlFillMemory(
  1046. (PVOID)((ULONG_PTR)puj - width * (height - 1)),
  1047. width * height,
  1048. index);
  1049. return;
  1050. }
  1051. }
  1052. pujEnd = (GLubyte *)((ULONG_PTR)puj + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  1053. // Note: exit condition is (pul != pulEnd) rather than (pul < pulEnd)
  1054. // because the DIB may be upside down which means that pul is moving
  1055. // "backward" in memory rather than "forward".
  1056. for ( ; puj != pujEnd; puj = (GLubyte *)((ULONG_PTR)puj + cfb->buf.outerWidth) ) {
  1057. RtlFillMemory((PVOID) puj, width, index);
  1058. }
  1059. }
  1060. /******************************Public*Routine******************************\
  1061. * Index8Clear
  1062. *
  1063. * Clear function for all 8-bit pixel formats
  1064. *
  1065. * History:
  1066. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1067. * Wrote it.
  1068. * Oct-03-1995 -by- Marc Fortier [marcfo]
  1069. * Don't translate color if masking enabled
  1070. \**************************************************************************/
  1071. void FASTCALL Index8Clear(__GLcolorBuffer *cfb)
  1072. {
  1073. __GLcontext *gc = cfb->buf.gc;
  1074. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1075. PIXELFORMATDESCRIPTOR *pfmt;
  1076. BYTE clearColor;
  1077. RECTL rcl;
  1078. GLGENwindow *pwnd;
  1079. GLboolean bMoreRects = GL_TRUE;
  1080. GLboolean bDither = GL_FALSE;
  1081. GLboolean bMasking = (cfb->buf.flags & COLORMASK_ON) != 0;
  1082. GLboolean bDIB = (cfb->buf.flags & DIB_FORMAT) != 0;
  1083. GLboolean bUseMcdSpans = gengc->pMcdState && !bDIB;
  1084. GLboolean bRGBA;
  1085. GLubyte ditherMatrix[4][4];
  1086. GLint ClipEnumState;
  1087. DBGENTRY("Index8Clear\n");
  1088. pfmt = &gengc->gsurf.pfd;
  1089. bRGBA = (pfmt->iPixelType == PFD_TYPE_RGBA);
  1090. /* if dithering enabled, see if we can ignore it, and if not,
  1091. precompute a dither matrix
  1092. */
  1093. if( gc->state.enables.general & __GL_DITHER_ENABLE ) {
  1094. bDither = CalcDitherMatrix( cfb, bRGBA, bMasking, GL_FALSE,
  1095. (GLubyte *)ditherMatrix );
  1096. }
  1097. // Convert clear value to index
  1098. if( bRGBA ) {
  1099. clearColor =
  1100. ((BYTE)(gc->state.raster.clear.r*gc->frontBuffer.redScale + __glHalf) <<
  1101. cfb->redShift) |
  1102. ((BYTE)(gc->state.raster.clear.g*gc->frontBuffer.greenScale + __glHalf) <<
  1103. cfb->greenShift) |
  1104. ((BYTE)(gc->state.raster.clear.b*gc->frontBuffer.blueScale + __glHalf) <<
  1105. cfb->blueShift);
  1106. }
  1107. else {
  1108. clearColor = (BYTE) (gc->state.raster.clearIndex + __glHalf);
  1109. clearColor &= cfb->redMax;
  1110. }
  1111. // translate color to index
  1112. if( !bMasking )
  1113. clearColor = gengc->pajTranslateVector[clearColor];
  1114. // Get clear rectangle in screen coordinates.
  1115. pwnd = cfb->bitmap->pwnd;
  1116. if (pwnd->clipComplexity == CLC_COMPLEX) {
  1117. InitClearRectangle(pwnd, &ClipEnumState);
  1118. #ifdef LATER
  1119. } else if ( !bMasking
  1120. && !bDither
  1121. && bDIB
  1122. && gengc->fDirtyRegionEnabled
  1123. && !RECTLISTIsMax(&gengc->rlClear)
  1124. && ((GLuint)clearColor == gengc->clearColor)
  1125. ) {
  1126. //
  1127. // use dirty region rects
  1128. //
  1129. if (!RECTLISTIsEmpty(&gengc->rlClear)) {
  1130. PYLIST pylist = gengc->rlClear.pylist;
  1131. while (pylist != NULL) {
  1132. PXLIST pxlist = pylist->pxlist;
  1133. rcl.top = pylist->s;
  1134. rcl.bottom = pylist->e;
  1135. while (pxlist != NULL) {
  1136. rcl.left = pxlist->s;
  1137. rcl.right = pxlist->e;
  1138. DIBIndex8Clear( cfb, &rcl, clearColor );
  1139. pxlist = pxlist->pnext;
  1140. }
  1141. pylist = pylist->pnext;
  1142. }
  1143. //
  1144. // Union the blt region with the Clear region
  1145. // and set the clear region to empty
  1146. //
  1147. RECTLISTOrAndClear(&gengc->rlBlt, &gengc->rlClear);
  1148. }
  1149. return;
  1150. }
  1151. if (gengc->fDirtyRegionEnabled) {
  1152. //
  1153. // if we come through this path then for some reason we
  1154. // are clearing the entire window
  1155. //
  1156. RECTLISTSetEmpty(&gengc->rlClear);
  1157. RECTLISTSetMax(&gengc->rlBlt);
  1158. //
  1159. // remember the clear color
  1160. //
  1161. gengc->clearColor = (GLuint)clearColor;
  1162. #endif
  1163. }
  1164. while (bMoreRects)
  1165. {
  1166. // Must use MCD spans if buffer not accessible as DIB. In such a
  1167. // case, window offset has been removed (see GenMcdUpdateBufferInfo),
  1168. // so a window relative rectangle is required for the clear. Also,
  1169. // because the driver handles clipping, we do not need to enumerate
  1170. // rects.
  1171. if (bUseMcdSpans) {
  1172. rcl.left = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  1173. rcl.right = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  1174. rcl.bottom = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  1175. rcl.top = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  1176. bMoreRects = FALSE;
  1177. } else
  1178. bMoreRects = GetClearSubRectangle(cfb, &rcl, pwnd, &ClipEnumState);
  1179. if (rcl.right == rcl.left)
  1180. continue;
  1181. // Case: no dithering, no masking
  1182. if( !bMasking && !bDither ) {
  1183. if( bDIB )
  1184. DIBIndex8Clear( cfb, &rcl, clearColor );
  1185. else if (bUseMcdSpans)
  1186. Index8MaskedClear( cfb, &rcl, clearColor, NULL );
  1187. else
  1188. wglFillRect(gengc, pwnd, &rcl,
  1189. (ULONG) clearColor & 0x000000FF);
  1190. }
  1191. // Case: masking, maybe dithering
  1192. else if( bMasking ) {
  1193. Index8MaskedClear( cfb, &rcl, clearColor,
  1194. bDither ? (GLubyte *)ditherMatrix : NULL );
  1195. }
  1196. // Case: just dithering
  1197. else {
  1198. Index8DitherClear(cfb, &rcl, (GLubyte *)ditherMatrix, bDIB );
  1199. }
  1200. }
  1201. }
  1202. /******************************Public*Routine******************************\
  1203. * RGBMaskedClear
  1204. *
  1205. * Clear function for 24-bit (RGB/BGR) Masked clears
  1206. *
  1207. * History:
  1208. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  1209. * Wrote it.
  1210. \**************************************************************************/
  1211. void
  1212. RGBMaskedClear(__GLcolorBuffer *cfb, RECTL *rcl, GLuint color, GLuint index)
  1213. {
  1214. GLint cSpanWidth, ySpan;
  1215. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  1216. __GLcontext *gc = (__GLcontext *) gengc;
  1217. PIXELFORMATDESCRIPTOR *pfmt;
  1218. GLboolean bDIB;
  1219. GLuint *destColors, *cp;
  1220. GLubyte *puj, *puj2, *pujEnd;
  1221. GLuint result, src;
  1222. GLuint *pTrans;
  1223. pfmt = &gengc->gsurf.pfd;
  1224. cSpanWidth = rcl->right - rcl->left;
  1225. bDIB = cfb->buf.flags & DIB_FORMAT ? TRUE : FALSE;
  1226. if( pfmt->iPixelType != PFD_TYPE_RGBA ) {
  1227. destColors = (GLuint *) gcTempAlloc(gc, cSpanWidth*sizeof(GLuint));
  1228. if( NULL == destColors )
  1229. return;
  1230. pTrans = (GLuint *) gengc->pajTranslateVector + 1;
  1231. }
  1232. puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base +
  1233. (rcl->top*cfb->buf.outerWidth) + (rcl->left*3))
  1234. : gengc->ColorsBits;
  1235. pujEnd = puj + 3*cSpanWidth;
  1236. for (ySpan = rcl->top; ySpan < rcl->bottom; ySpan++) {
  1237. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  1238. // fetch based on bDIB
  1239. if( !bDIB ) {
  1240. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1241. ySpan, cSpanWidth, FALSE);
  1242. }
  1243. src = color & cfb->sourceMask;
  1244. for( puj2 = puj; puj2 < pujEnd; puj2+=3 ) {
  1245. Copy3Bytes( &result, puj2 ); // get dst pixel
  1246. result = src | (result & cfb->destMask);
  1247. Copy3Bytes( puj2, &result );
  1248. }
  1249. }
  1250. else { // Color Index
  1251. ScrnRGBCIReadSpan( cfb, rcl->left, ySpan, destColors, cSpanWidth,
  1252. bDIB );
  1253. cp = destColors;
  1254. src = index & cfb->sourceMask;
  1255. for( puj2 = puj; puj2 < pujEnd; puj2+=3, cp++ ) {
  1256. result = src | (*cp & cfb->destMask);
  1257. result = pTrans[result];
  1258. Copy3Bytes( puj2, &result );
  1259. }
  1260. }
  1261. if( !bDIB )
  1262. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1263. ySpan, cSpanWidth, TRUE);
  1264. if( bDIB ) {
  1265. puj += cfb->buf.outerWidth;
  1266. pujEnd = puj + 3*cSpanWidth;
  1267. }
  1268. }
  1269. if( pfmt->iPixelType != PFD_TYPE_RGBA )
  1270. gcTempFree(gc, destColors);
  1271. }
  1272. /******************************Public*Routine******************************\
  1273. * DIBRGBClear
  1274. *
  1275. * Clear function for 24-bit (RGB/BGR) DIB pixel formats
  1276. *
  1277. * History:
  1278. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1279. * Wrote it.
  1280. \**************************************************************************/
  1281. void FASTCALL DIBRGBClear(__GLcolorBuffer *cfb, RECTL *rcl, GLubyte *color)
  1282. {
  1283. __GLcontext *gc = cfb->buf.gc;
  1284. GLint width = (rcl->right - rcl->left) * 3;
  1285. GLuint *pul = (GLuint *) (((ULONG_PTR)cfb->buf.base +
  1286. rcl->top*cfb->buf.outerWidth) + (rcl->left*3));
  1287. GLuint *pulEnd;
  1288. GLubyte clear0, clear1, clear2;
  1289. BYTE *ScanLineBuf;
  1290. ScanLineBuf = (BYTE *) gcTempAlloc (gc, width);
  1291. if (ScanLineBuf) {
  1292. // Alloc succeeds
  1293. clear0 = color[0]; clear1 = color[1]; clear2 = color[2];
  1294. RtlFillMemory24((PVOID)ScanLineBuf, width, clear0, clear1, clear2);
  1295. pulEnd = (GLuint *)((ULONG_PTR)pul +
  1296. ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  1297. // Note: exit condition is (pul != pulEnd) rather than (pul < pulEnd)
  1298. // because the DIB may be upside down which means that pul is moving
  1299. // "backward" in memory rather than "forward".
  1300. for ( ; pul != pulEnd;
  1301. pul = (GLuint *)((ULONG_PTR)pul + cfb->buf.outerWidth))
  1302. memcpy((PVOID) pul, ScanLineBuf, width);
  1303. gcTempFree(gc, ScanLineBuf);
  1304. }
  1305. }
  1306. /******************************Public*Routine******************************\
  1307. * RGBClear
  1308. *
  1309. * Clear function for all 24-bit (RGB/BGR) pixel formats
  1310. *
  1311. * History:
  1312. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1313. * Wrote it.
  1314. \**************************************************************************/
  1315. void FASTCALL RGBClear(__GLcolorBuffer *cfb)
  1316. {
  1317. __GLcontext *gc = cfb->buf.gc;
  1318. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1319. PIXELFORMATDESCRIPTOR *pfmt;
  1320. RECTL rcl;
  1321. GLuint clearColor;
  1322. GLGENwindow *pwnd;
  1323. GLboolean bMoreRects = GL_TRUE;
  1324. DWORD index;
  1325. GLint ClipEnumState;
  1326. GLboolean bMasking = (cfb->buf.flags & COLORMASK_ON) != 0;
  1327. GLboolean bDIB = (cfb->buf.flags & DIB_FORMAT) != 0;
  1328. GLboolean bUseMcdSpans = gengc->pMcdState && !bDIB;
  1329. DBGENTRY("RGBClear\n");
  1330. // Convert the clear color to individual RGB components.
  1331. pfmt = &gengc->gsurf.pfd;
  1332. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  1333. GLubyte clearR, clearG, clearB;
  1334. GLubyte *pClearColor;
  1335. clearR = (GLubyte)(gc->state.raster.clear.r*gc->frontBuffer.redScale);
  1336. clearG = (GLubyte)(gc->state.raster.clear.g*gc->frontBuffer.greenScale);
  1337. clearB = (GLubyte)(gc->state.raster.clear.b*gc->frontBuffer.blueScale);
  1338. pClearColor = (GLubyte *) &clearColor;
  1339. if( cfb->redShift == 16 ) {
  1340. // BGR mode
  1341. *pClearColor++ = clearB;
  1342. *pClearColor++ = clearG;
  1343. *pClearColor = clearR;
  1344. }
  1345. else {
  1346. // RGB mode
  1347. *pClearColor++ = clearR;
  1348. *pClearColor++ = clearG;
  1349. *pClearColor = clearB;
  1350. }
  1351. }
  1352. else {
  1353. GLuint *pTrans;
  1354. index = (DWORD) (gc->state.raster.clearIndex + 0.5F);
  1355. index &= cfb->redMax;
  1356. pTrans = (GLuint *) gengc->pajTranslateVector;
  1357. clearColor = pTrans[index+1];
  1358. }
  1359. // Get clear rectangle in screen coordinates.
  1360. pwnd = cfb->bitmap->pwnd;
  1361. if (pwnd->clipComplexity == CLC_COMPLEX) {
  1362. InitClearRectangle(pwnd, &ClipEnumState);
  1363. #ifdef LATER
  1364. } else if ( !bMasking
  1365. && bDIB
  1366. && gengc->fDirtyRegionEnabled
  1367. && !RECTLISTIsMax(&gengc->rlClear)
  1368. && ((GLuint)clearColor == gengc->clearColor)
  1369. ) {
  1370. //
  1371. // use dirty region rects
  1372. //
  1373. if (!RECTLISTIsEmpty(&gengc->rlClear)) {
  1374. PYLIST pylist = gengc->rlClear.pylist;
  1375. while (pylist != NULL) {
  1376. PXLIST pxlist = pylist->pxlist;
  1377. rcl.top = pylist->s;
  1378. rcl.bottom = pylist->e;
  1379. while (pxlist != NULL) {
  1380. rcl.left = pxlist->s;
  1381. rcl.right = pxlist->e;
  1382. DIBRGBClear( cfb, &rcl, (GLubyte *) &clearColor);
  1383. pxlist = pxlist->pnext;
  1384. }
  1385. pylist = pylist->pnext;
  1386. }
  1387. //
  1388. // Union the blt region with the Clear region
  1389. // and set the clear region to empty
  1390. //
  1391. RECTLISTOrAndClear(&gengc->rlBlt, &gengc->rlClear);
  1392. }
  1393. return;
  1394. }
  1395. if (gengc->fDirtyRegionEnabled) {
  1396. //
  1397. // if we come through this path then for some reason we
  1398. // are clearing the entire window
  1399. //
  1400. RECTLISTSetEmpty(&gengc->rlClear);
  1401. RECTLISTSetMax(&gengc->rlBlt);
  1402. //
  1403. // remember the clear color
  1404. //
  1405. gengc->clearColor = (GLuint)clearColor;
  1406. #endif
  1407. }
  1408. while (bMoreRects)
  1409. {
  1410. // Must use MCD spans if buffer not accessible as DIB. In such a
  1411. // case, window offset has been removed (see GenMcdUpdateBufferInfo),
  1412. // so a window relative rectangle is required for the clear. Also,
  1413. // because the driver handles clipping, we do not need to enumerate
  1414. // rects.
  1415. if (bUseMcdSpans) {
  1416. rcl.left = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  1417. rcl.right = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  1418. rcl.bottom = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  1419. rcl.top = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  1420. bMoreRects = FALSE;
  1421. } else
  1422. bMoreRects = GetClearSubRectangle(cfb, &rcl, pwnd, &ClipEnumState);
  1423. if (rcl.right == rcl.left)
  1424. continue;
  1425. // Call aproppriate clear function
  1426. if (bMasking || bUseMcdSpans) { // or INDEXMASK_ON
  1427. RGBMaskedClear( cfb, &rcl, clearColor, index );
  1428. }
  1429. else {
  1430. if (bDIB)
  1431. DIBRGBClear( cfb, &rcl, (GLubyte *) &clearColor);
  1432. else
  1433. wglFillRect(gengc, pwnd, &rcl,
  1434. (ULONG) clearColor & 0x00FFFFFF);
  1435. }
  1436. }
  1437. }
  1438. /******************************Public*Routine******************************\
  1439. * Bitfield16DitherClear
  1440. *
  1441. * Clear device managed surface to the dithered clear color indicated
  1442. * in the __GLcolorBuffer.
  1443. *
  1444. * History:
  1445. * 06-Dec-1993 -by- Gilman Wong [gilmanw]
  1446. * Wrote it.
  1447. \**************************************************************************/
  1448. void
  1449. Bitfield16DitherClear(__GLcolorBuffer *cfb, RECTL *rcl, GLushort *mDither,
  1450. GLboolean bDIB)
  1451. {
  1452. __GLcontext *gc = cfb->buf.gc;
  1453. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1454. GLushort *pDither; // dithered color, relative to window origin
  1455. UINT i, j;
  1456. GLushort *pus, *pusStart; // pointer into span buffer
  1457. GLint ySpan; // index to window row to clear
  1458. GLuint cSpanWidth, cSpanWidth2;
  1459. GLint outerWidth4;
  1460. GLuint dithX, dithY; // x,y offsets into dither matrix
  1461. GLushort dithQuad[4]; // dither repetion quad along a span
  1462. cSpanWidth = rcl->right - rcl->left;
  1463. if( bDIB )
  1464. {
  1465. pusStart = (GLushort *)
  1466. ((ULONG_PTR)cfb->buf.base +
  1467. (rcl->top*cfb->buf.outerWidth) + (rcl->left << 1));
  1468. /*
  1469. * Dither patterns repeat themselves every four rows
  1470. */
  1471. outerWidth4 = cfb->buf.outerWidth << 2;
  1472. /*
  1473. * cSpanWidth is in pixels, convert it to bytes
  1474. */
  1475. cSpanWidth2 = cSpanWidth << 1;
  1476. }
  1477. // calc dither offset in x,y
  1478. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  1479. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  1480. for (j = 0; (j < 4) && ((rcl->top + j) < (UINT)rcl->bottom); j++)
  1481. {
  1482. // arrange the 4-pixel dither repetition pattern in x
  1483. pDither = mDither + ((dithY+j)&3)*4;
  1484. for( i = 0; i < 4; i ++ ) {
  1485. dithQuad[i] = pDither[(dithX+i)&3];
  1486. }
  1487. // Copy the clear color into the span buffer.
  1488. pus = gengc->ColorsBits;
  1489. for (i = cSpanWidth / 4; i; i--)
  1490. {
  1491. *pus++ = dithQuad[0];
  1492. *pus++ = dithQuad[1];
  1493. *pus++ = dithQuad[2];
  1494. *pus++ = dithQuad[3];
  1495. }
  1496. for (i = 0; i < (cSpanWidth & 3); i++)
  1497. {
  1498. *pus++ = dithQuad[i];
  1499. }
  1500. // Copy the span to the display for every 4th row of the window.
  1501. if( bDIB ) {
  1502. for (ySpan = rcl->top + j, pus = pusStart;
  1503. ySpan < rcl->bottom;
  1504. ySpan+=4,
  1505. pus = (GLushort *)((ULONG_PTR)pus + outerWidth4) ) {
  1506. RtlCopyMemory_UnalignedDst( pus, gengc->ColorsBits, cSpanWidth2 );
  1507. }
  1508. pusStart = (GLushort *)((ULONG_PTR)pusStart + cfb->buf.outerWidth);
  1509. }
  1510. else {
  1511. for (ySpan = rcl->top + j; ySpan < rcl->bottom; ySpan+=4)
  1512. {
  1513. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1514. ySpan, cSpanWidth, TRUE);
  1515. }
  1516. }
  1517. }
  1518. }
  1519. /******************************Public*Routine******************************\
  1520. * Bitfield16MaskedClear
  1521. *
  1522. * Clear function for Bitfield16 Masked clears
  1523. *
  1524. * History:
  1525. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  1526. * Wrote it.
  1527. \**************************************************************************/
  1528. void
  1529. Bitfield16MaskedClear(__GLcolorBuffer *cfb, RECTL *rcl, GLushort color,
  1530. GLuint index, GLushort *mDither)
  1531. {
  1532. GLint cSpanWidth, ySpan;
  1533. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  1534. __GLcontext *gc = (__GLcontext *) gengc;
  1535. PIXELFORMATDESCRIPTOR *pfmt;
  1536. GLboolean bDIB;
  1537. GLuint *destColors, *cp;
  1538. GLushort *pus, *pus2, *pusEnd, *clearDither;
  1539. GLushort result, src;
  1540. GLuint *pTrans, i, j;
  1541. GLuint dithX, dithY; // x,y offsets into dither matrix
  1542. pfmt = &gengc->gsurf.pfd;
  1543. cSpanWidth = rcl->right - rcl->left;
  1544. bDIB = cfb->buf.flags & DIB_FORMAT ? TRUE : FALSE;
  1545. if( pfmt->iPixelType != PFD_TYPE_RGBA ) {
  1546. destColors = (GLuint *) gcTempAlloc(gc, cSpanWidth*sizeof(GLuint));
  1547. if( NULL == destColors )
  1548. return;
  1549. pTrans = (GLuint *) gengc->pajTranslateVector + 1;
  1550. }
  1551. pus = bDIB ? (GLushort *)((ULONG_PTR)cfb->buf.base +
  1552. (rcl->top*cfb->buf.outerWidth) + (rcl->left<<1))
  1553. : gengc->ColorsBits;
  1554. pusEnd = pus + cSpanWidth;
  1555. if( mDither ) {
  1556. // calc dither offset in x,y
  1557. dithX = (rcl->left - cfb->buf.xOrigin) & 3;
  1558. dithY = (rcl->top - cfb->buf.yOrigin) & 3;
  1559. }
  1560. for (ySpan = rcl->top, j = 0; ySpan < rcl->bottom; ySpan++, j++) {
  1561. if( mDither )
  1562. clearDither = mDither + ((dithY + j)&3)*4;
  1563. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  1564. // fetch based on bDIB
  1565. if( !bDIB ) {
  1566. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1567. ySpan, cSpanWidth, FALSE);
  1568. }
  1569. src = (GLushort)(color & cfb->sourceMask);
  1570. for( pus2 = pus, i = 0; pus2 < pusEnd; pus2++, i++ ) {
  1571. if( mDither )
  1572. src = clearDither[(dithX + i)&3];
  1573. *pus2 = (GLushort)(src | (*pus2 & cfb->destMask));
  1574. }
  1575. }
  1576. else { // Color Index
  1577. ScrnBitfield16CIReadSpan( cfb, rcl->left, ySpan, destColors,
  1578. cSpanWidth, bDIB );
  1579. cp = destColors;
  1580. src = (GLushort)(index & cfb->sourceMask);
  1581. for( pus2 = pus, i = 0; pus2 < pusEnd; pus2++, cp++, i++ ) {
  1582. if( mDither )
  1583. src = clearDither[(dithX + i)&3];
  1584. result = (GLushort)(src | (*cp & cfb->destMask));
  1585. result = (GLushort)pTrans[result];
  1586. *pus2 = result;
  1587. }
  1588. }
  1589. if( !bDIB )
  1590. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1591. ySpan, cSpanWidth, TRUE);
  1592. if( bDIB ) {
  1593. pus = (GLushort *)((ULONG_PTR)pus + cfb->buf.outerWidth);
  1594. pusEnd = pus + cSpanWidth;
  1595. }
  1596. }
  1597. if( pfmt->iPixelType != PFD_TYPE_RGBA )
  1598. gcTempFree(gc, destColors);
  1599. }
  1600. /******************************Public*Routine******************************\
  1601. * DIBBitfield16Clear
  1602. *
  1603. * Clear function for 16-bit DIB pixel formats
  1604. *
  1605. * History:
  1606. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1607. * Wrote it.
  1608. \**************************************************************************/
  1609. void FASTCALL DIBBitfield16Clear(__GLcolorBuffer *cfb, RECTL *rcl, GLushort clearColor)
  1610. {
  1611. GLint cSpanWidth; // span width to clear
  1612. GLushort *pus, *pusEnd; // pointers into DIB
  1613. cSpanWidth = rcl->right - rcl->left;
  1614. pus = (GLushort *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + (rcl->left<<1));
  1615. pusEnd = (GLushort *)((ULONG_PTR)pus + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  1616. // Note: exit condition is (pul != pulEnd) rather than (pul < pulEnd)
  1617. // because the DIB may be upside down which means that pul is moving
  1618. // "backward" in memory rather than "forward".
  1619. for ( ; pus != pusEnd; pus = (GLushort *)((ULONG_PTR)pus + cfb->buf.outerWidth) )
  1620. {
  1621. RtlFillMemoryUshort(pus, cSpanWidth * sizeof(GLushort), clearColor);
  1622. }
  1623. }
  1624. //!!!XXX -- don't need yet, but let's keep it around just in case
  1625. #if 0
  1626. /******************************Public*Routine******************************\
  1627. * DisplayBitfield16Clear
  1628. *
  1629. * Clear device managed surface to the clear color indicated
  1630. * in the __GLcolorBuffer.
  1631. *
  1632. * History:
  1633. * 16-Feb-1995 -by- Gilman Wong [gilmanw]
  1634. * Wrote it.
  1635. \**************************************************************************/
  1636. void
  1637. DisplayBitfield16Clear(__GLcolorBuffer *cfb, RECTL *rcl,
  1638. GLushort clearColor)
  1639. {
  1640. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  1641. GLushort *pus, *pusEnd;
  1642. GLint cSpanWidth; // in pixels
  1643. GLint ySpan;
  1644. cSpanWidth = rcl->right - rcl->left;
  1645. pus = (GLushort *) gengc->ColorsBits;
  1646. pusEnd = pus + cSpanWidth;
  1647. // Initialize a span buffer to clear color.
  1648. LocalRtlFillMemoryUshort(pus, cSpanWidth*sizeof(GLushort), clearColor);
  1649. for ( ySpan = rcl->top; ySpan < rcl->bottom; ySpan++ )
  1650. {
  1651. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1652. ySpan, cSpanWidth, TRUE);
  1653. }
  1654. }
  1655. #endif
  1656. /******************************Public*Routine******************************\
  1657. * Bitfield16Clear
  1658. *
  1659. * Clear function for all 16-bit pixel formats
  1660. *
  1661. * History:
  1662. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1663. * Wrote it.
  1664. \**************************************************************************/
  1665. void FASTCALL Bitfield16Clear(__GLcolorBuffer *cfb)
  1666. {
  1667. __GLcontext *gc = cfb->buf.gc;
  1668. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1669. PIXELFORMATDESCRIPTOR *pfmt;
  1670. GLushort clearColor;
  1671. RECTL rcl;
  1672. GLGENwindow *pwnd;
  1673. GLboolean bMoreRects = GL_TRUE;
  1674. GLboolean bDither = GL_FALSE;
  1675. GLboolean bMasking = (cfb->buf.flags & COLORMASK_ON) != 0;
  1676. GLboolean bDIB = (cfb->buf.flags & DIB_FORMAT) != 0;
  1677. GLboolean bUseMcdSpans = gengc->pMcdState && !bDIB;
  1678. GLboolean bRGBA;
  1679. GLushort ditherMatrix[4][4];
  1680. DWORD index;
  1681. GLint ClipEnumState;
  1682. DBGENTRY("Bitfield16Clear\n");
  1683. pfmt = &gengc->gsurf.pfd;
  1684. bRGBA = (pfmt->iPixelType == PFD_TYPE_RGBA);
  1685. /* if dithering enabled, see if we can ignore it, and if not,
  1686. precompute a dither matrix
  1687. */
  1688. if( gc->state.enables.general & __GL_DITHER_ENABLE ) {
  1689. bDither = CalcDitherMatrix( cfb, bRGBA, bMasking, GL_TRUE,
  1690. (GLubyte *)ditherMatrix );
  1691. }
  1692. // Convert clear value
  1693. if( bRGBA ) {
  1694. clearColor =
  1695. ((BYTE)(gc->state.raster.clear.r*gc->frontBuffer.redScale + __glHalf) <<
  1696. cfb->redShift) |
  1697. ((BYTE)(gc->state.raster.clear.g*gc->frontBuffer.greenScale + __glHalf) <<
  1698. cfb->greenShift) |
  1699. ((BYTE)(gc->state.raster.clear.b*gc->frontBuffer.blueScale + __glHalf) <<
  1700. cfb->blueShift);
  1701. if( ALPHA_IN_PIXEL( cfb ) )
  1702. clearColor |=
  1703. ((BYTE)(gc->state.raster.clear.a*gc->frontBuffer.alphaScale + __glHalf) <<
  1704. cfb->alphaShift);
  1705. }
  1706. else {
  1707. GLuint *pTrans;
  1708. index = (DWORD) (gc->state.raster.clearIndex + 0.5F);
  1709. index &= cfb->redMax;
  1710. pTrans = (GLuint *) gengc->pajTranslateVector;
  1711. clearColor = (GLushort) pTrans[index+1];
  1712. }
  1713. // Get clear rectangle in screen coordinates.
  1714. pwnd = cfb->bitmap->pwnd;
  1715. if (pwnd->clipComplexity == CLC_COMPLEX) {
  1716. InitClearRectangle(pwnd, &ClipEnumState);
  1717. #ifdef LATER
  1718. } else if ( !bMasking
  1719. && !bDither
  1720. && bDIB
  1721. && gengc->fDirtyRegionEnabled
  1722. && !RECTLISTIsMax(&gengc->rlClear)
  1723. && ((GLuint)clearColor == gengc->clearColor)
  1724. ) {
  1725. //
  1726. // use dirty region rects
  1727. //
  1728. if (!RECTLISTIsEmpty(&gengc->rlClear)) {
  1729. PYLIST pylist = gengc->rlClear.pylist;
  1730. while (pylist != NULL) {
  1731. PXLIST pxlist = pylist->pxlist;
  1732. rcl.top = pylist->s;
  1733. rcl.bottom = pylist->e;
  1734. while (pxlist != NULL) {
  1735. rcl.left = pxlist->s;
  1736. rcl.right = pxlist->e;
  1737. DIBBitfield16Clear( cfb, &rcl, clearColor );
  1738. pxlist = pxlist->pnext;
  1739. }
  1740. pylist = pylist->pnext;
  1741. }
  1742. //
  1743. // Union the blt region with the Clear region
  1744. // and set the clear region to empty
  1745. //
  1746. RECTLISTOrAndClear(&gengc->rlBlt, &gengc->rlClear);
  1747. }
  1748. return;
  1749. }
  1750. if (gengc->fDirtyRegionEnabled) {
  1751. //
  1752. // if we come through this path then for some reason we
  1753. // are clearing the entire window
  1754. //
  1755. RECTLISTSetEmpty(&gengc->rlClear);
  1756. RECTLISTSetMax(&gengc->rlBlt);
  1757. //
  1758. // remember the clear color
  1759. //
  1760. gengc->clearColor = (GLuint)clearColor;
  1761. #endif
  1762. }
  1763. while (bMoreRects)
  1764. {
  1765. // Must use MCD spans if buffer not accessible as DIB. In such a
  1766. // case, window offset has been removed (see GenMcdUpdateBufferInfo),
  1767. // so a window relative rectangle is required for the clear. Also,
  1768. // because the driver handles clipping, we do not need to enumerate
  1769. // rects.
  1770. if (bUseMcdSpans) {
  1771. rcl.left = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  1772. rcl.right = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  1773. rcl.bottom = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  1774. rcl.top = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  1775. bMoreRects = FALSE;
  1776. } else
  1777. bMoreRects = GetClearSubRectangle(cfb, &rcl, pwnd, &ClipEnumState);
  1778. if (rcl.right == rcl.left)
  1779. continue;
  1780. // Case: no dithering, no masking
  1781. if( !bMasking && !bDither) {
  1782. if (bDIB)
  1783. DIBBitfield16Clear( cfb, &rcl, clearColor );
  1784. else if (bUseMcdSpans)
  1785. Bitfield16MaskedClear( cfb, &rcl, clearColor, index, NULL );
  1786. else
  1787. wglFillRect(gengc, pwnd, &rcl,
  1788. (ULONG) clearColor & 0x0000FFFF);
  1789. }
  1790. // Case: masking, maybe dithering
  1791. else if( bMasking ) {
  1792. Bitfield16MaskedClear( cfb, &rcl, clearColor, index,
  1793. bDither ? (GLushort *)ditherMatrix : NULL );
  1794. }
  1795. // Case: just dithering
  1796. else {
  1797. Bitfield16DitherClear(cfb, &rcl, (GLushort *)ditherMatrix, bDIB );
  1798. }
  1799. }
  1800. }
  1801. /******************************Public*Routine******************************\
  1802. * Bitfield32MaskedClear
  1803. *
  1804. * Clear function for Bitfield16 Masked clears
  1805. *
  1806. * History:
  1807. * Feb-09-1994 -by- Marc Fortier [v-marcf]
  1808. * Wrote it.
  1809. \**************************************************************************/
  1810. void
  1811. Bitfield32MaskedClear(__GLcolorBuffer *cfb, RECTL *rcl, GLuint color, GLuint index)
  1812. {
  1813. GLint cSpanWidth, ySpan;
  1814. __GLGENcontext *gengc = (__GLGENcontext *) cfb->buf.gc;
  1815. __GLcontext *gc = (__GLcontext *) gengc;
  1816. PIXELFORMATDESCRIPTOR *pfmt;
  1817. GLboolean bDIB;
  1818. GLuint *destColors, *cp;
  1819. GLuint *pul, *pul2, *pulEnd;
  1820. GLuint result, src;
  1821. GLuint *pTrans;
  1822. pfmt = &gengc->gsurf.pfd;
  1823. cSpanWidth = rcl->right - rcl->left;
  1824. bDIB = cfb->buf.flags & DIB_FORMAT ? TRUE : FALSE;
  1825. if( pfmt->iPixelType != PFD_TYPE_RGBA ) {
  1826. destColors = (GLuint *) gcTempAlloc(gc, cSpanWidth*sizeof(GLuint));
  1827. if( NULL == destColors )
  1828. return;
  1829. pTrans = (GLuint *) gengc->pajTranslateVector + 1;
  1830. }
  1831. pul = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base +
  1832. (rcl->top*cfb->buf.outerWidth) + (rcl->left<<2))
  1833. : gengc->ColorsBits;
  1834. pulEnd = pul + cSpanWidth;
  1835. for (ySpan = rcl->top; ySpan < rcl->bottom; ySpan++) {
  1836. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  1837. // fetch based on bDIB
  1838. if( !bDIB ) {
  1839. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1840. ySpan, cSpanWidth, FALSE);
  1841. }
  1842. src = color & cfb->sourceMask;
  1843. for( pul2 = pul; pul2 < pulEnd; pul2++) {
  1844. *pul2 = src | (*pul2 & cfb->destMask);
  1845. }
  1846. }
  1847. else { // Color Index
  1848. ScrnBitfield32CIReadSpan( cfb, rcl->left, ySpan, destColors,
  1849. cSpanWidth, bDIB );
  1850. cp = destColors;
  1851. src = index & cfb->sourceMask;
  1852. for( pul2 = pul; pul2 < pulEnd; pul2++, cp++ ) {
  1853. result = src | (*cp & cfb->destMask);
  1854. result = pTrans[result];
  1855. *pul2 = result;
  1856. }
  1857. }
  1858. if( !bDIB )
  1859. (*gengc->pfnCopyPixels)(gengc, cfb, rcl->left,
  1860. ySpan, cSpanWidth, TRUE);
  1861. if( bDIB ) {
  1862. pul = (GLuint *)((ULONG_PTR)pul + cfb->buf.outerWidth);
  1863. pulEnd = pul + cSpanWidth;
  1864. }
  1865. }
  1866. if( pfmt->iPixelType != PFD_TYPE_RGBA )
  1867. gcTempFree(gc, destColors);
  1868. }
  1869. /******************************Public*Routine******************************\
  1870. * DIBBitfield32Clear
  1871. *
  1872. * Clear function for 32-bit DIB pixel formats
  1873. *
  1874. * History:
  1875. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1876. * Wrote it.
  1877. \**************************************************************************/
  1878. void FASTCALL DIBBitfield32Clear(__GLcolorBuffer *cfb, RECTL *rcl, GLuint clearColor)
  1879. {
  1880. GLint width = (rcl->right - rcl->left) * sizeof(ULONG);
  1881. GLint height = (rcl->bottom - rcl->top);
  1882. GLuint *pul = (GLuint *)((ULONG_PTR)cfb->buf.base + (rcl->top*cfb->buf.outerWidth) + (rcl->left<<2));
  1883. GLuint *pulEnd;
  1884. if (cfb->buf.outerWidth > 0) {
  1885. if (width == cfb->buf.outerWidth) {
  1886. RtlFillMemoryUlong((PVOID) pul, width * height, clearColor);
  1887. return;
  1888. }
  1889. } else {
  1890. if (width == -cfb->buf.outerWidth) {
  1891. RtlFillMemoryUlong(
  1892. (PVOID)((ULONG_PTR)pul - width * (height - 1)),
  1893. width * height,
  1894. clearColor);
  1895. return;
  1896. }
  1897. }
  1898. pulEnd = (GLuint *)((ULONG_PTR)pul + ((rcl->bottom-rcl->top)*cfb->buf.outerWidth));
  1899. // Note: exit condition is (pul != pulEnd) rather than (pul < pulEnd)
  1900. // because the DIB may be upside down which means that pul is moving
  1901. // "backward" in memory rather than "forward".
  1902. for ( ; pul != pulEnd; pul = (GLuint *)((ULONG_PTR)pul + cfb->buf.outerWidth))
  1903. {
  1904. RtlFillMemoryUlong((PVOID) pul, width, clearColor);
  1905. }
  1906. }
  1907. /******************************Public*Routine******************************\
  1908. * Bitfield32Clear
  1909. *
  1910. * Clear function for all 32-bit pixel formats
  1911. *
  1912. * History:
  1913. * Feb-03-1994 -by- Marc Fortier [v-marcf]
  1914. * Wrote it.
  1915. \**************************************************************************/
  1916. void FASTCALL Bitfield32Clear(__GLcolorBuffer *cfb)
  1917. {
  1918. __GLcontext *gc = cfb->buf.gc;
  1919. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1920. PIXELFORMATDESCRIPTOR *pfmt;
  1921. GLuint clearColor;
  1922. RECTL rcl;
  1923. DWORD index;
  1924. GLGENwindow *pwnd;
  1925. GLboolean bMoreRects = GL_TRUE;
  1926. GLint ClipEnumState;
  1927. GLboolean bMasking = (cfb->buf.flags & COLORMASK_ON) != 0;
  1928. GLboolean bDIB = (cfb->buf.flags & DIB_FORMAT) != 0;
  1929. GLboolean bUseMcdSpans = gengc->pMcdState && !bDIB;
  1930. DBGENTRY("Bitfield32Clear\n");
  1931. // Convert clear value
  1932. pfmt = &gengc->gsurf.pfd;
  1933. if( pfmt->iPixelType == PFD_TYPE_RGBA ) {
  1934. clearColor =
  1935. ((BYTE)(gc->state.raster.clear.r*gc->frontBuffer.redScale + __glHalf) <<
  1936. cfb->redShift) |
  1937. ((BYTE)(gc->state.raster.clear.g*gc->frontBuffer.greenScale + __glHalf) <<
  1938. cfb->greenShift) |
  1939. ((BYTE)(gc->state.raster.clear.b*gc->frontBuffer.blueScale + __glHalf) <<
  1940. cfb->blueShift);
  1941. if( ALPHA_IN_PIXEL( cfb ) )
  1942. clearColor |=
  1943. ((BYTE)(gc->state.raster.clear.a*gc->frontBuffer.alphaScale + __glHalf) <<
  1944. cfb->alphaShift);
  1945. }
  1946. else {
  1947. GLuint *pTrans;
  1948. index = (DWORD) (gc->state.raster.clearIndex + 0.5F);
  1949. index &= cfb->redMax;
  1950. pTrans = (GLuint *) gengc->pajTranslateVector;
  1951. clearColor = pTrans[index+1];
  1952. }
  1953. // Get clear rectangle in screen coordinates.
  1954. pwnd = cfb->bitmap->pwnd;
  1955. if (pwnd->clipComplexity == CLC_COMPLEX) {
  1956. InitClearRectangle(pwnd, &ClipEnumState);
  1957. #ifdef LATER
  1958. } else if ( !bMasking
  1959. && bDIB
  1960. && gengc->fDirtyRegionEnabled
  1961. && !RECTLISTIsMax(&gengc->rlClear)
  1962. && ((GLuint)clearColor == gengc->clearColor)
  1963. ) {
  1964. //
  1965. // use dirty region rects
  1966. //
  1967. if (!RECTLISTIsEmpty(&gengc->rlClear)) {
  1968. PYLIST pylist = gengc->rlClear.pylist;
  1969. while (pylist != NULL) {
  1970. PXLIST pxlist = pylist->pxlist;
  1971. rcl.top = pylist->s;
  1972. rcl.bottom = pylist->e;
  1973. while (pxlist != NULL) {
  1974. rcl.left = pxlist->s;
  1975. rcl.right = pxlist->e;
  1976. DIBBitfield32Clear( cfb, &rcl, clearColor );
  1977. pxlist = pxlist->pnext;
  1978. }
  1979. pylist = pylist->pnext;
  1980. }
  1981. //
  1982. // Union the blt region with the Clear region
  1983. // and set the clear region to empty
  1984. //
  1985. RECTLISTOrAndClear(&gengc->rlBlt, &gengc->rlClear);
  1986. }
  1987. return;
  1988. }
  1989. if (gengc->fDirtyRegionEnabled) {
  1990. //
  1991. // if we come through this path then for some reason we
  1992. // are clearing the entire window
  1993. //
  1994. RECTLISTSetEmpty(&gengc->rlClear);
  1995. RECTLISTSetMax(&gengc->rlBlt);
  1996. //
  1997. // remember the clear color
  1998. //
  1999. gengc->clearColor = (GLuint)clearColor;
  2000. #endif
  2001. }
  2002. while (bMoreRects)
  2003. {
  2004. // Must use MCD spans if buffer not accessible as DIB. In such a
  2005. // case, window offset has been removed (see GenMcdUpdateBufferInfo),
  2006. // so a window relative rectangle is required for the clear. Also,
  2007. // because the driver handles clipping, we do not need to enumerate
  2008. // rects.
  2009. if (bUseMcdSpans) {
  2010. rcl.left = __GL_UNBIAS_X(gc, gc->transform.clipX0);
  2011. rcl.right = __GL_UNBIAS_X(gc, gc->transform.clipX1);
  2012. rcl.bottom = __GL_UNBIAS_Y(gc, gc->transform.clipY1);
  2013. rcl.top = __GL_UNBIAS_Y(gc, gc->transform.clipY0);
  2014. bMoreRects = FALSE;
  2015. } else
  2016. bMoreRects = GetClearSubRectangle(cfb, &rcl, pwnd, &ClipEnumState);
  2017. if (rcl.right == rcl.left)
  2018. continue;
  2019. // Call aproppriate clear function
  2020. if (bMasking || bUseMcdSpans) { // or INDEXMASK_ON
  2021. Bitfield32MaskedClear( cfb, &rcl, clearColor, index );
  2022. }
  2023. else {
  2024. if (bDIB)
  2025. DIBBitfield32Clear( cfb, &rcl, clearColor );
  2026. else
  2027. wglFillRect(gengc, pwnd, &rcl, (ULONG) clearColor);
  2028. }
  2029. }
  2030. }