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.

671 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: srcblt32.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt to a 32 bit/pel
  5. * DIB surface.
  6. *
  7. * Created: 07-Feb-1991 19:27:49
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * Copyright (c) 1990-1999 Microsoft Corporation
  11. *
  12. \**************************************************************************/
  13. #include "precomp.hxx"
  14. // Turn off validations
  15. #if 1
  16. // On free builds, don't call any verification code:
  17. #define VERIFYS16D32(psb)
  18. #define VERIFYS24D32(psb)
  19. #else
  20. // On checked builds, verify the RGB conversions:
  21. VOID VERIFYS16D32(PBLTINFO psb)
  22. {
  23. // We assume we are doing left to right top to bottom blting
  24. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D32 - direction not left to right");
  25. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D32 - direction not up to down");
  26. // These are our holding variables
  27. PUSHORT pusSrcTemp;
  28. PULONG pulDstTemp;
  29. ULONG cxTemp;
  30. PUSHORT pusSrc = (PUSHORT) (psb->pjSrc + (2 * psb->xSrcStart));
  31. PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  32. ULONG cx = psb->cx;
  33. ULONG cy = psb->cy;
  34. XLATE *pxlo = psb->pxlo;
  35. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  36. while(1)
  37. {
  38. pusSrcTemp = pusSrc;
  39. pulDstTemp = pulDst;
  40. cxTemp = cx;
  41. while(cxTemp--)
  42. {
  43. if (*(pulDstTemp++) != pxlo->ulTranslate((ULONG) *(pusSrcTemp++)))
  44. RIP("RGB mis-match");
  45. }
  46. if (--cy)
  47. {
  48. pusSrc = (PUSHORT) (((PBYTE) pusSrc) + psb->lDeltaSrc);
  49. pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
  50. }
  51. else
  52. break;
  53. }
  54. }
  55. VOID VERIFYS24D32(PBLTINFO psb)
  56. {
  57. // We assume we are doing left to right top to bottom blting
  58. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D32 - direction not left to right");
  59. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D32 - direction not up to down");
  60. // These are our holding variables
  61. ULONG ulDink; // variable to dink around with the bytes in
  62. PBYTE pjSrcTemp;
  63. PULONG pulDstTemp;
  64. ULONG cxTemp;
  65. PBYTE pjSrc = psb->pjSrc + (3 * psb->xSrcStart);
  66. PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  67. ULONG cx = psb->cx;
  68. ULONG cy = psb->cy;
  69. XLATE *pxlo = psb->pxlo;
  70. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  71. while(1)
  72. {
  73. pjSrcTemp = pjSrc;
  74. pulDstTemp = pulDst;
  75. cxTemp = cx;
  76. while(cxTemp--)
  77. {
  78. ulDink = *(pjSrcTemp + 2);
  79. ulDink = ulDink << 8;
  80. ulDink |= (ULONG) *(pjSrcTemp + 1);
  81. ulDink = ulDink << 8;
  82. ulDink |= (ULONG) *pjSrcTemp;
  83. if (*pulDstTemp != pxlo->ulTranslate(ulDink))
  84. RIP("RGB mis-match");
  85. pulDstTemp++;
  86. pjSrcTemp += 3;
  87. }
  88. if (--cy)
  89. {
  90. pjSrc += psb->lDeltaSrc;
  91. pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
  92. }
  93. else
  94. break;
  95. }
  96. }
  97. #endif
  98. /*******************Public*Routine*****************\
  99. * vSrcCopyS1D32
  100. *
  101. * This function loops through all the lines copying
  102. * each one in three phases according to source
  103. * alignment. The outer loop in x loops through
  104. * the bits in the incomplete bytes (which might
  105. * happen in the begining or the end of the sequence).
  106. * When it comes to the first full byte, it
  107. * goes into an internal x loop that copies 8
  108. * bytes at a time, avoiding some branches, and
  109. * allowing the processor to paraleliza these
  110. * instructions, since there are no dependencies.
  111. *
  112. *
  113. * History:
  114. * 17-Nov-1998 -by- Andre Matos [amatos]
  115. * Wrote it.
  116. *
  117. \**************************************************/
  118. VOID vSrcCopyS1D32(PBLTINFO psb)
  119. {
  120. PBYTE pjSrc;
  121. PBYTE pjDst;
  122. ULONG cx = psb->cx;
  123. ULONG cy = psb->cy;
  124. PBYTE pjSrcTemp;
  125. PULONG pjDstTemp;
  126. ULONG cxTemp;
  127. BYTE jSrc;
  128. ULONG aulTable[2];
  129. BYTE iPosSrc;
  130. // We assume we are doing left to right top to bottom blting
  131. ASSERTGDI(psb->xDir == 1, "vSrcCopyS1D32 - direction not left to right");
  132. ASSERTGDI(psb->yDir == 1, "vSrcCopyS1D32 - direction not up to down");
  133. // We shouldn't be called with an empty rectangle
  134. ASSERTGDI( cx != 0 && cy != 0, "vSrcCopyS1D32 - called with an empty rectangle");
  135. // Generate aulTable. 2 entries.
  136. aulTable[0] = (ULONG)(psb->pxlo->pulXlate[0]);
  137. aulTable[1] = (ULONG)(psb->pxlo->pulXlate[1]);
  138. pjSrc = psb->pjSrc + (psb->xSrcStart >> 3);
  139. pjDst = psb->pjDst + 4*psb->xDstStart;
  140. while(cy--)
  141. {
  142. pjSrcTemp = pjSrc;
  143. pjDstTemp = (PULONG)pjDst;
  144. cxTemp = cx;
  145. iPosSrc = (BYTE)(psb->xSrcStart & 0x07);
  146. if( !iPosSrc )
  147. {
  148. // Decrement this since it will be
  149. // incremented up front ahead
  150. pjSrcTemp--;
  151. }
  152. else
  153. {
  154. jSrc = *pjSrcTemp << iPosSrc;
  155. }
  156. while (cxTemp)
  157. {
  158. if (!iPosSrc)
  159. {
  160. pjSrcTemp++;
  161. if (cxTemp>=8)
  162. {
  163. while(cxTemp>= 8)
  164. {
  165. jSrc = *pjSrcTemp;
  166. pjDstTemp[0] = aulTable[jSrc >> 7];
  167. pjDstTemp[1] = aulTable[(jSrc >> 6) & 1];
  168. pjDstTemp[2] = aulTable[(jSrc >> 5) & 1];
  169. pjDstTemp[3] = aulTable[(jSrc >> 4) & 1];
  170. pjDstTemp[4] = aulTable[(jSrc >> 3) & 1];
  171. pjDstTemp[5] = aulTable[(jSrc >> 2) & 1];
  172. pjDstTemp[6] = aulTable[(jSrc >> 1) & 1];
  173. pjDstTemp[7] = aulTable[(jSrc & 1)];
  174. pjSrcTemp++;
  175. pjDstTemp += 8;
  176. cxTemp -= 8;
  177. }
  178. pjSrcTemp--;
  179. continue;
  180. }
  181. else
  182. {
  183. jSrc = *pjSrcTemp;
  184. }
  185. }
  186. *pjDstTemp = aulTable[(jSrc >> 7) & 1];
  187. jSrc <<= 1;
  188. iPosSrc++;
  189. iPosSrc &= 7;
  190. pjDstTemp++;
  191. cxTemp--;
  192. }
  193. pjSrc = pjSrc + psb->lDeltaSrc;
  194. pjDst = pjDst + psb->lDeltaDst;
  195. }
  196. }
  197. /******************************Public*Routine******************************\
  198. * vSrcCopyS4D32
  199. *
  200. *
  201. * History:
  202. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  203. * Wrote it.
  204. \**************************************************************************/
  205. VOID vSrcCopyS4D32(PBLTINFO psb)
  206. {
  207. // We assume we are doing left to right top to bottom blting
  208. ASSERTGDI(psb->xDir == 1, "vSrcCopyS4D32 - direction not left to right");
  209. ASSERTGDI(psb->yDir == 1, "vSrcCopyS4D32 - direction not up to down");
  210. BYTE jSrc;
  211. LONG i;
  212. PULONG pulDst;
  213. PBYTE pjSrc;
  214. PULONG pulDstHolder = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  215. PBYTE pjSrcHolder = psb->pjSrc + (psb->xSrcStart >> 1);
  216. ULONG cy = psb->cy;
  217. PULONG pulXlate = psb->pxlo->pulXlate;
  218. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  219. while(1)
  220. {
  221. pulDst = pulDstHolder;
  222. pjSrc = pjSrcHolder;
  223. i = psb->xSrcStart;
  224. if (i & 0x00000001)
  225. jSrc = *(pjSrc++);
  226. while(i != psb->xSrcEnd)
  227. {
  228. if (i & 0x00000001)
  229. *(pulDst++) = pulXlate[jSrc & 0x0F];
  230. else
  231. {
  232. // We need a new byte
  233. jSrc = *(pjSrc++);
  234. *(pulDst++) = pulXlate[(((ULONG) (jSrc & 0xF0)) >> 4)];
  235. }
  236. ++i;
  237. }
  238. if (--cy)
  239. {
  240. pjSrcHolder += psb->lDeltaSrc;
  241. pulDstHolder = (PULONG) (((PBYTE) pulDstHolder) + psb->lDeltaDst);
  242. }
  243. else
  244. break;
  245. }
  246. }
  247. /******************************Public*Routine******************************\
  248. * vSrcCopyS8D32
  249. *
  250. *
  251. * History:
  252. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  253. * Wrote it.
  254. \**************************************************************************/
  255. VOID vSrcCopyS8D32(PBLTINFO psb)
  256. {
  257. // We assume we are doing left to right top to bottom blting
  258. ASSERTGDI(psb->xDir == 1, "vSrcCopyS8D32 - direction not left to right");
  259. ASSERTGDI(psb->yDir == 1, "vSrcCopyS8D32 - direction not up to down");
  260. // These are our holding variables
  261. PBYTE pjSrcTemp;
  262. PULONG pulDstTemp;
  263. ULONG cxTemp;
  264. PBYTE pjSrc = psb->pjSrc + psb->xSrcStart;
  265. PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  266. ULONG cx = psb->cx;
  267. ULONG cy = psb->cy;
  268. PULONG pulXlate = psb->pxlo->pulXlate;
  269. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  270. while(1)
  271. {
  272. pjSrcTemp = pjSrc;
  273. pulDstTemp = pulDst;
  274. cxTemp = cx;
  275. while(cxTemp--)
  276. {
  277. *(pulDstTemp++) = pulXlate[((ULONG) *(pjSrcTemp++))];
  278. }
  279. if (--cy)
  280. {
  281. pjSrc += psb->lDeltaSrc;
  282. pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
  283. }
  284. else
  285. break;
  286. }
  287. }
  288. /******************************Public*Routine******************************\
  289. * vSrcCopyS16D32
  290. *
  291. *
  292. * History:
  293. * 07-Feb-1991 -by- Patrick Haluptzok patrickh
  294. * Wrote it.
  295. \**************************************************************************/
  296. VOID vSrcCopyS16D32(PBLTINFO psb)
  297. {
  298. // We assume we are doing left to right top to bottom blting
  299. ASSERTGDI(psb->xDir == 1, "vSrcCopyS16D32 - direction not left to right");
  300. ASSERTGDI(psb->yDir == 1, "vSrcCopyS16D32 - direction not up to down");
  301. // These are our holding variables
  302. PBYTE pjSrc = psb->pjSrc + (2 * psb->xSrcStart);
  303. PBYTE pjDst = psb->pjDst + (4 * psb->xDstStart);
  304. ULONG cx = psb->cx;
  305. ULONG cy = psb->cy;
  306. LONG lSrcSkip = psb->lDeltaSrc - (cx * 2);
  307. LONG lDstSkip = psb->lDeltaDst - (cx * 4);
  308. XLATE *pxlo = psb->pxlo;
  309. XEPALOBJ palSrc(pxlo->ppalSrc);
  310. XEPALOBJ palDst(pxlo->ppalDst);
  311. ULONG ul;
  312. ULONG ul0;
  313. ULONG ul1;
  314. LONG i;
  315. ASSERTGDI(cy != 0,
  316. "ERROR: Src Move cy == 0");
  317. ASSERTGDI(palSrc.bIsBitfields(),
  318. "ERROR: destination not bitfields");
  319. // First, try to optimize 5-6-5 to BGR:
  320. if ((palSrc.flBlu() == 0x001f) &&
  321. (palSrc.flGre() == 0x07e0) &&
  322. (palSrc.flRed() == 0xf800) &&
  323. (palDst.bIsBGR()))
  324. {
  325. while (1)
  326. {
  327. i = cx;
  328. do {
  329. ul = *((USHORT*) pjSrc);
  330. *((ULONG*) pjDst) = ((ul << 8) & 0xf80000)
  331. | ((ul << 3) & 0x070000)
  332. | ((ul << 5) & 0x00fc00)
  333. | ((ul >> 1) & 0x000300)
  334. | ((ul << 3) & 0x0000f8)
  335. | ((ul >> 2) & 0x000007);
  336. pjSrc += 2;
  337. pjDst += 4;
  338. } while (--i != 0);
  339. if (--cy == 0)
  340. break;
  341. pjSrc += lSrcSkip;
  342. pjDst += lDstSkip;
  343. }
  344. VERIFYS16D32(psb);
  345. return;
  346. }
  347. // Next, try to optimize 5-5-5 to BGR:
  348. if ((palSrc.flBlu() == 0x001f) &&
  349. (palSrc.flGre() == 0x03e0) &&
  350. (palSrc.flRed() == 0x7c00) &&
  351. (palDst.bIsBGR()))
  352. {
  353. while (1)
  354. {
  355. i = cx;
  356. do {
  357. ul = *((USHORT*) pjSrc);
  358. *((ULONG*) pjDst) = ((ul << 9) & 0xf80000)
  359. | ((ul << 4) & 0x070000)
  360. | ((ul << 6) & 0x00f800)
  361. | ((ul << 1) & 0x000700)
  362. | ((ul << 3) & 0x0000f8)
  363. | ((ul >> 2) & 0x000007);
  364. pjSrc += 2;
  365. pjDst += 4;
  366. } while (--i != 0);
  367. if (--cy == 0)
  368. break;
  369. pjSrc += lSrcSkip;
  370. pjDst += lDstSkip;
  371. }
  372. VERIFYS16D32(psb);
  373. return;
  374. }
  375. // Finally, fall back to the generic case:
  376. while (1)
  377. {
  378. i = cx;
  379. do {
  380. *((ULONG*) pjDst) = pxlo->ulTranslate(*((USHORT*) pjSrc));
  381. pjSrc += 2;
  382. pjDst += 4;
  383. } while (--i != 0);
  384. if (--cy == 0)
  385. break;
  386. pjSrc += lSrcSkip;
  387. pjDst += lDstSkip;
  388. }
  389. VERIFYS16D32(psb);
  390. }
  391. /******************************Public*Routine******************************\
  392. * vSrcCopyS24D32
  393. *
  394. *
  395. * History:
  396. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  397. * Wrote it.
  398. \**************************************************************************/
  399. VOID vSrcCopyS24D32(PBLTINFO psb)
  400. {
  401. // We assume we are doing left to right top to bottom blting
  402. ASSERTGDI(psb->xDir == 1, "vSrcCopyS24D32 - direction not left to right");
  403. ASSERTGDI(psb->yDir == 1, "vSrcCopyS24D32 - direction not up to down");
  404. // These are our holding variables
  405. PBYTE pjSrc = psb->pjSrc + (3 * psb->xSrcStart);
  406. PBYTE pjDst = psb->pjDst + (4 * psb->xDstStart);
  407. ULONG cx = psb->cx;
  408. ULONG cy = psb->cy;
  409. LONG lSrcSkip = psb->lDeltaSrc - (cx * 3);
  410. LONG lDstSkip = psb->lDeltaDst - (cx * 4);
  411. PFN_pfnXlate pfnXlate;
  412. XLATE *pxlo = psb->pxlo;
  413. XEPALOBJ palSrc(pxlo->ppalSrc);
  414. XEPALOBJ palDst(pxlo->ppalDst);
  415. ULONG ul;
  416. LONG i;
  417. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  418. // Try to optimize BGR to BGR:
  419. if (palSrc.bIsBGR() && palDst.bIsBGR())
  420. {
  421. while (1)
  422. {
  423. i = cx;
  424. do {
  425. *((ULONG*) pjDst) = (*(pjSrc))
  426. | (*(pjSrc + 1) << 8)
  427. | (*(pjSrc + 2) << 16);
  428. pjDst += 4;
  429. pjSrc += 3;
  430. } while (--i != 0);
  431. if (--cy == 0)
  432. break;
  433. pjSrc += lSrcSkip;
  434. pjDst += lDstSkip;
  435. }
  436. VERIFYS24D32(psb);
  437. return;
  438. }
  439. // Fall back to the generic case:
  440. pfnXlate = pxlo->pfnXlateBetweenBitfields();
  441. while (1)
  442. {
  443. i = cx;
  444. do {
  445. ul = ((ULONG) *(pjSrc))
  446. | ((ULONG) *(pjSrc + 1) << 8)
  447. | ((ULONG) *(pjSrc + 2) << 16);
  448. *((ULONG*) pjDst) = pfnXlate(pxlo, ul);
  449. pjDst += 4;
  450. pjSrc += 3;
  451. } while (--i != 0);
  452. if (--cy == 0)
  453. break;
  454. pjSrc += lSrcSkip;
  455. pjDst += lDstSkip;
  456. }
  457. VERIFYS24D32(psb);
  458. }
  459. /******************************Public*Routine******************************\
  460. * vSrcCopyS32D32
  461. *
  462. *
  463. * History:
  464. * 07-Feb-1991 -by- Patrick Haluptzok patrickh
  465. * Wrote it.
  466. \**************************************************************************/
  467. VOID vSrcCopyS32D32(PBLTINFO psb)
  468. {
  469. // We assume we are doing left to right top to bottom blting.
  470. // If it was on the same surface it would be the identity case.
  471. ASSERTGDI(psb->xDir == 1, "vSrcCopyS32D32 - direction not left to right");
  472. ASSERTGDI(psb->yDir == 1, "vSrcCopyS32D32 - direction not up to down");
  473. // These are our holding variables
  474. PULONG pulSrcTemp;
  475. PULONG pulDstTemp;
  476. ULONG cxTemp;
  477. PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
  478. PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  479. ULONG cx = psb->cx;
  480. ULONG cy = psb->cy;
  481. XLATE *pxlo = psb->pxlo;
  482. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  483. while(1)
  484. {
  485. pulSrcTemp = pulSrc;
  486. pulDstTemp = pulDst;
  487. cxTemp = cx;
  488. while(cxTemp--)
  489. {
  490. *(pulDstTemp++) = pxlo->ulTranslate(*(pulSrcTemp++));
  491. }
  492. if (--cy)
  493. {
  494. pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
  495. pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
  496. }
  497. else
  498. break;
  499. }
  500. }
  501. /******************************Public*Routine******************************\
  502. * vSrcCopyS32D32Identity
  503. *
  504. * This is the special case no translate blting. All the SmDn should have
  505. * them if m==n. Identity xlates only occur amoung matching format bitmaps.
  506. *
  507. * History:
  508. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  509. * Wrote it.
  510. \**************************************************************************/
  511. VOID vSrcCopyS32D32Identity(PBLTINFO psb)
  512. {
  513. // These are our holding variables
  514. PULONG pulSrc = (PULONG) (psb->pjSrc + (4 * psb->xSrcStart));
  515. PULONG pulDst = (PULONG) (psb->pjDst + (4 * psb->xDstStart));
  516. ULONG cx = psb->cx;
  517. ULONG cy = psb->cy;
  518. ASSERTGDI(cy != 0, "ERROR: Src Move cy == 0");
  519. if (psb->xDir < 0)
  520. {
  521. pulSrc -= (cx - 1);
  522. pulDst -= (cx - 1);
  523. }
  524. cx = cx << 2;
  525. while(1)
  526. {
  527. if(psb->fSrcAlignedRd)
  528. vSrcAlignCopyMemory((PBYTE)pulDst, (PBYTE)pulSrc, cx);
  529. else
  530. RtlMoveMemory((PVOID)pulDst, (PVOID)pulSrc, cx);
  531. if (--cy)
  532. {
  533. pulSrc = (PULONG) (((PBYTE) pulSrc) + psb->lDeltaSrc);
  534. pulDst = (PULONG) (((PBYTE) pulDst) + psb->lDeltaDst);
  535. }
  536. else
  537. break;
  538. }
  539. }