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.

732 lines
22 KiB

  1. /*******************************Module*Header*****************************\
  2. *
  3. * Copyright (c) 1992-1999 Microsoft Corporation
  4. * Copyright (c) 1992 Digital Equipment Corporation
  5. *
  6. * Module Name:
  7. *
  8. * tiler.cxx
  9. *
  10. * Abstract:
  11. *
  12. * This module implements code to copy a pattern to a target surface.
  13. *
  14. * Author:
  15. *
  16. * David N. Cutler (davec) 4-May-1992
  17. *
  18. * Rewritten in C by:
  19. *
  20. * Eric Rehm (rehm@zso.dec.com) 15-July-1992
  21. *
  22. * Environment:
  23. *
  24. * User mode only.
  25. *
  26. * Revision History:
  27. *
  28. \*************************************************************************/
  29. #include "precomp.hxx"
  30. VOID CopyPattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat);
  31. VOID MergePattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat);
  32. /****************************Public*Routine******************************\
  33. *
  34. * extern "C" VOID
  35. * vFetchAndCopy (
  36. * IN PFETCHFRAME pff
  37. * )
  38. *
  39. * Routine Description:
  40. *
  41. * This routine repeatedly tiles one scan line of an aligned pattern.
  42. *
  43. * Arguments:
  44. *
  45. * pff - Supplies a pointer to a fetch frame.
  46. *
  47. * Return Value:
  48. *
  49. * None.
  50. *
  51. \*************************************************************************/
  52. extern "C" VOID vFetchAndCopy
  53. (
  54. FETCHFRAME *pff
  55. )
  56. {
  57. PULONG pulTrg; // target surface address
  58. PULONG pulTrgEnd; // ending targe surface address
  59. PULONG pulPat; // base pattern address
  60. PULONG pulPatCur; // current pattern address
  61. PULONG pulPatEnd; // ending pattern address
  62. ULONG xPat; // pattern offset
  63. ULONG cxPat; // pattern width in pixels
  64. ULONG culFill; // fill size in longwords
  65. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  66. // Make copies of some things
  67. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  68. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  69. xPat = pff->xPat; // pattern offset in bytes (t2)
  70. cxPat = pff->cxPat; // pattern width in pixels (t3)
  71. culFill = pff->culFill; // Size of fill in longwords
  72. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  73. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  74. // compute current pattern address (t5)
  75. if (cxPat == 8) // check if pattern is exactly 8 pels
  76. {
  77. loPat = *pulPatCur; // get low part of 8-byte pattern
  78. if (xPat == 0)
  79. {
  80. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  81. }
  82. else
  83. {
  84. hiPat = *pulPat; // get hi part of 8-byte pattern
  85. }
  86. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  87. }
  88. else
  89. {
  90. //
  91. // The pattern is not 8 bytes in width
  92. // or cannot be moved 8 bytes at a time
  93. //
  94. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  95. // ending pattern address
  96. while (pulTrg < pulTrgEnd)
  97. {
  98. *pulTrg = *pulPatCur; // set target to 4-byte pattern value
  99. pulTrg += 1; // advance the target ptr one longword
  100. pulPatCur += 1; // advance the pattern pixel offset
  101. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  102. {
  103. pulPatCur = pulPat; // get starting pattern address
  104. }
  105. }
  106. }
  107. } // end vFetchAndCopy
  108. /****************************Public*Routine******************************\
  109. *
  110. * extern "C" VOID
  111. * vFetchShiftAndCopy (
  112. * IN PFETCHFRAME pff
  113. * )
  114. *
  115. * Routine Description:
  116. *
  117. * This routine repeatedly tiles one scan line of an unaligned pattern
  118. * using rop (P).
  119. *
  120. * Arguments:
  121. *
  122. * pff - Supplies a pointer to a fetch frame.
  123. *
  124. * Return Value:
  125. *
  126. * None.
  127. *
  128. \*************************************************************************/
  129. extern "C" VOID vFetchShiftAndCopy
  130. (
  131. FETCHFRAME *pff
  132. )
  133. {
  134. PULONG pulTrg; // target surface address
  135. PULONG pulTrgEnd; // ending targe surface address
  136. ULONG UNALIGNED *pulPat; // base pattern address
  137. ULONG UNALIGNED *pulPatCur; // current pattern address
  138. ULONG xPat; // pattern offset
  139. ULONG cxPat; // pattern width in pixels
  140. ULONG culFill; // fill size in longwords
  141. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  142. // Make copies of some things
  143. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  144. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  145. xPat = pff->xPat; // pattern offset in bytes (t2)
  146. cxPat = pff->cxPat; // pattern width in pixels (t3)
  147. culFill = pff->culFill; // Size of fill in longwords
  148. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  149. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  150. // compute current pattern address (t5)
  151. if (cxPat == 8) // check if pattern is exactly 8 pels
  152. {
  153. loPat = *pulPatCur; // get low part of 8-byte pattern
  154. xPat +=4; // get hi part of 8-byte pattern
  155. if (xPat >= cxPat)
  156. {
  157. xPat -= cxPat;
  158. }
  159. hiPat = *((ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat));
  160. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  161. }
  162. else
  163. {
  164. //
  165. // The pattern is not 8 bytes in width
  166. // or cannot be moved 8 bytes at a time
  167. //
  168. while (pulTrg < pulTrgEnd)
  169. {
  170. *pulTrg = *pulPatCur;
  171. // set target to 4-byte pattern value
  172. pulTrg += 1; // advance the target ptr one longword
  173. xPat += 4;
  174. if (xPat >= cxPat)
  175. {
  176. xPat -= cxPat;
  177. }
  178. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  179. }
  180. }
  181. } // end vFetchShiftAndCopy
  182. /****************************Public*Routine******************************\
  183. *
  184. * extern "C" VOID
  185. * vFetchNotAndCopy (
  186. * IN PFETCHFRAME pff
  187. * )
  188. *
  189. * Routine Description:
  190. *
  191. * This routine repeatedly tiles one scan line of an aligned pattern
  192. * using rop (Pn).
  193. *
  194. * Arguments:
  195. *
  196. * pff - Supplies a pointer to a fetch frame.
  197. *
  198. * Return Value:
  199. *
  200. * None.
  201. *
  202. \*************************************************************************/
  203. extern "C" VOID vFetchNotAndCopy
  204. (
  205. FETCHFRAME *pff
  206. )
  207. {
  208. PULONG pulTrg; // target surface address
  209. PULONG pulTrgEnd; // ending targe surface address
  210. PULONG pulPat; // base pattern address
  211. PULONG pulPatCur; // current pattern address
  212. PULONG pulPatEnd; // ending pattern address
  213. ULONG xPat; // pattern offset
  214. ULONG cxPat; // pattern width in pixels
  215. ULONG culFill; // fill size in longwords
  216. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  217. // Make copies of some things
  218. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  219. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  220. xPat = pff->xPat; // pattern offset in bytes (t2)
  221. cxPat = pff->cxPat; // pattern width in pixels (t3)
  222. culFill = pff->culFill; // Size of fill in longwords
  223. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  224. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  225. // compute current pattern address (t5)
  226. if (cxPat == 8) // check if pattern is exactly 8 pels
  227. {
  228. loPat = *pulPatCur; // get low part of 8-byte pattern
  229. if (xPat == 0)
  230. {
  231. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  232. }
  233. else
  234. {
  235. hiPat = *pulPat; // get hi part of 8-byte pattern
  236. }
  237. loPat = ~loPat; // complement pattern
  238. hiPat = ~hiPat;
  239. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  240. }
  241. else
  242. {
  243. //
  244. // The pattern is not 8 bytes in width
  245. // or cannot be moved 8 bytes at a time
  246. //
  247. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  248. // ending pattern address
  249. while (pulTrg < pulTrgEnd)
  250. {
  251. *pulTrg = ~(*pulPatCur);
  252. // set target to complement of 4-byte pattern value
  253. pulTrg += 1; // advance the target ptr one longword
  254. pulPatCur += 1; // advance the pattern pixel offset
  255. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  256. {
  257. pulPatCur = pulPat; // get starting pattern address
  258. }
  259. }
  260. }
  261. } // end vFetchNotAndCopy
  262. /****************************Public*Routine******************************\
  263. *
  264. * extern "C" VOID
  265. * vFetchShiftNotAndCopy (
  266. * IN PFETCHFRAME pff
  267. * )
  268. *
  269. * Routine Description:
  270. *
  271. * This routine repeatedly tiles one scan line of an unaligned pattern
  272. * using rop (Pn).
  273. *
  274. * Arguments:
  275. *
  276. * pff - Supplies a pointer to a fetch frame.
  277. *
  278. * Return Value:
  279. *
  280. * None.
  281. *
  282. \*************************************************************************/
  283. extern "C" VOID vFetchShiftNotAndCopy
  284. (
  285. FETCHFRAME *pff
  286. )
  287. {
  288. PULONG pulTrg; // target surface address
  289. PULONG pulTrgEnd; // ending targe surface address
  290. ULONG UNALIGNED *pulPat; // base pattern address
  291. ULONG UNALIGNED *pulPatCur; // current pattern address
  292. ULONG xPat; // pattern offset
  293. ULONG cxPat; // pattern width in pixels
  294. ULONG culFill; // fill size in longwords
  295. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  296. // Make copies of some things
  297. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  298. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  299. xPat = pff->xPat; // pattern offset in bytes (t2)
  300. cxPat = pff->cxPat; // pattern width in pixels (t3)
  301. culFill = pff->culFill; // Size of fill in longwords
  302. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  303. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  304. // compute current pattern address (t5)
  305. if (cxPat == 8) // check if pattern is exactly 8 pels
  306. {
  307. loPat = *pulPatCur;
  308. // get low part of 8-byte pattern
  309. xPat +=4; // get hi part of 8-byte pattern
  310. if (xPat >= cxPat)
  311. {
  312. xPat -= cxPat;
  313. }
  314. hiPat = *((ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat));
  315. loPat = ~loPat; // complement pattern
  316. hiPat = ~hiPat;
  317. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  318. }
  319. else
  320. {
  321. //
  322. // The pattern is not 8 bytes in width
  323. // or cannot be moved 8 bytes at a time
  324. //
  325. while (pulTrg < pulTrgEnd)
  326. {
  327. *pulTrg = ~(*pulPatCur);
  328. // set target to complemented 4-byte pattern value
  329. pulTrg += 1; // advance the target ptr one longword
  330. xPat += 4;
  331. if (xPat >= cxPat)
  332. {
  333. xPat -= cxPat;
  334. }
  335. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  336. }
  337. }
  338. } // end vFetchShiftNotAndCopy
  339. /****************************Private*Routine******************************\
  340. *
  341. * VOID CopyPattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat)
  342. *
  343. * Routine Description:
  344. *
  345. * This routine contains common code for copying an 8-byte pattern to
  346. * a target surface.
  347. *
  348. * Arguments:
  349. *
  350. * culFill - Supplies the size of the fill in bytes.
  351. * loPat, hiPat - Supplies the 8-byte pattern to copy.
  352. * pulTrg - Supplies the starting target surface address.
  353. *
  354. * Return Value:
  355. *
  356. * None.
  357. *
  358. *
  359. \*************************************************************************/
  360. VOID CopyPattern
  361. (
  362. PULONG pulTrg, // Starting target surface address (t0)
  363. LONG culFill, // size of fill in longwords (a1)
  364. LONG hiPat, // hi part of pattern (v1)
  365. LONG loPat // lo part of pattern (v0)
  366. )
  367. {
  368. PULONG pulTrgEnd; // ending target surface address
  369. ULONG temp; // temp for swap
  370. pulTrgEnd = pulTrg + culFill;
  371. // ending target surface address(t4)
  372. //
  373. // If the fill size is not an even multiple of 8 bytes, then move one
  374. // longword and swap the pattern value.
  375. //
  376. if ((culFill & 0x01) != 0)
  377. {
  378. *pulTrg = loPat; // store low 4 bytes of pattern
  379. pulTrg += 1; // advance target ptr one longword
  380. culFill -= 1;
  381. if (culFill == 0) // if no more to move then we're done
  382. {
  383. return;
  384. }
  385. else // otherwise, swap 8-byte pattern value
  386. {
  387. temp = loPat;
  388. loPat = hiPat;
  389. hiPat = temp;
  390. }
  391. }
  392. //
  393. // Move 8-byte pattern value to target 8 bytes at a time.
  394. //
  395. pulTrgEnd -= 2; // ending segement address
  396. if ((culFill & 0x02) != 0) // check if even multiple of 8 bytes
  397. {
  398. while (pulTrg <= pulTrgEnd) // if not, move 8 bytes at a time
  399. {
  400. *pulTrg = loPat; // store 8-byte pattern value
  401. *(pulTrg + 1) = hiPat;
  402. pulTrg += 2; // advance target address
  403. }
  404. return;
  405. }
  406. else // move 16 bytes at a time
  407. {
  408. pulTrgEnd -= 2; // ending segement address
  409. while (pulTrg <= pulTrgEnd)
  410. {
  411. *pulTrg = loPat; // store 8-byte pattern value
  412. *(pulTrg + 1) = hiPat;
  413. *(pulTrg + 2) = loPat; // store 8-byte pattern value
  414. *(pulTrg + 3) = hiPat;
  415. pulTrg += 4; // advance target address
  416. }
  417. }
  418. }
  419. /****************************Public*Routine******************************\
  420. *
  421. * extern "C" VOID
  422. * vFetchAndMerge (
  423. * IN PFETCHFRAME pff
  424. * )
  425. *
  426. * Routine Description:
  427. *
  428. * This routine repeatedly tiles one scan line of an aligned pattern
  429. * using ropt (DPx).
  430. *
  431. * Arguments:
  432. *
  433. * pff - Supplies a pointer to a fetch frame.
  434. *
  435. * Return Value:
  436. *
  437. * None.
  438. *
  439. \*************************************************************************/
  440. extern "C" VOID vFetchAndMerge
  441. (
  442. FETCHFRAME *pff
  443. )
  444. {
  445. PULONG pulTrg; // target surface address
  446. PULONG pulTrgEnd; // ending targe surface address
  447. PULONG pulPat; // base pattern address
  448. PULONG pulPatCur; // current pattern address
  449. PULONG pulPatEnd; // ending pattern address
  450. ULONG xPat; // pattern offset
  451. ULONG cxPat; // pattern width in pixels
  452. ULONG culFill; // fill size in longwords
  453. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  454. // Make copies of some things
  455. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  456. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  457. xPat = pff->xPat; // pattern offset in bytes (t2)
  458. cxPat = pff->cxPat; // pattern width in pixels (t3)
  459. culFill = pff->culFill; // Size of fill in longwords
  460. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  461. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  462. // compute current pattern address (t5)
  463. if (cxPat == 8) // check if pattern is exactly 8 pels
  464. {
  465. loPat = *pulPatCur; // get low part of 8-byte pattern
  466. if (xPat == 0)
  467. {
  468. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  469. }
  470. else
  471. {
  472. hiPat = *pulPat; // get hi part of 8-byte pattern
  473. }
  474. MergePattern( pulTrg, culFill, hiPat, loPat); //do a 4 or 8-byte copy
  475. }
  476. else
  477. {
  478. //
  479. // The pattern is not 8 bytes in width
  480. // or cannot be moved 8 bytes at a time
  481. //
  482. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  483. // ending pattern address
  484. while (pulTrg < pulTrgEnd)
  485. {
  486. *pulTrg = (*pulPatCur) ^ (*pulTrg);
  487. // XOR 4-byte target with 4-byte pattern value
  488. pulTrg += 1; // advance the target ptr one longword
  489. pulPatCur += 1; // advance the pattern pixel offset
  490. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  491. {
  492. pulPatCur = pulPat; // get starting pattern address
  493. }
  494. }
  495. }
  496. } // end vFetchAndMerge
  497. /****************************Public*Routine******************************\
  498. *
  499. * extern "C" VOID
  500. * vFetchShiftAndMerge (
  501. * IN PFETCHFRAME pff
  502. * )
  503. *
  504. * Routine Description:
  505. *
  506. * This routine repeatedly tiles one scan line of an unaligned pattern
  507. * using rop (P).
  508. *
  509. * Arguments:
  510. *
  511. * pff - Supplies a pointer to a fetch frame.
  512. *
  513. * Return Value:
  514. *
  515. * None.
  516. *
  517. \*************************************************************************/
  518. extern "C" VOID vFetchShiftAndMerge
  519. (
  520. FETCHFRAME *pff
  521. )
  522. {
  523. PULONG pulTrg; // target surface address
  524. PULONG pulTrgEnd; // ending targe surface address
  525. ULONG UNALIGNED *pulPat; // base pattern address
  526. ULONG UNALIGNED *pulPatCur; // current pattern address
  527. ULONG xPat; // pattern offset
  528. ULONG cxPat; // pattern width in pixels
  529. ULONG culFill; // fill size in longwords
  530. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  531. // Make copies of some things
  532. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  533. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  534. xPat = pff->xPat; // pattern offset in bytes (t2)
  535. cxPat = pff->cxPat; // pattern width in pixels (t3)
  536. culFill = pff->culFill; // Size of fill in longwords
  537. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  538. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  539. // compute current pattern address (t5)
  540. if (cxPat == 8) // check if pattern is exactly 8 pels
  541. {
  542. loPat = *pulPatCur;
  543. // get low part of 8-byte pattern
  544. xPat +=4; // get hi part of 8-byte pattern
  545. if (xPat >= cxPat)
  546. {
  547. xPat -= cxPat;
  548. }
  549. hiPat = *((ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat));
  550. MergePattern( pulTrg, culFill, hiPat, loPat); //do a 4 or 8-byte copy
  551. }
  552. else
  553. {
  554. //
  555. // The pattern is not 8 bytes in width
  556. // or cannot be moved 8 bytes at a time
  557. //
  558. while (pulTrg < pulTrgEnd)
  559. {
  560. *pulTrg = (*pulPatCur) ^ (*pulTrg);
  561. // XOR 4-byte target with 4-byte pattern value
  562. pulTrg += 1; // advance the target ptr one longword
  563. xPat += 4;
  564. if (xPat >= cxPat)
  565. {
  566. xPat -= cxPat;
  567. }
  568. pulPatCur = (ULONG UNALIGNED *) ((PUCHAR) pulPat + xPat);
  569. }
  570. }
  571. } // end vFetchShiftAndMerge
  572. /****************************Private*Routine******************************\
  573. *
  574. * VOID MergePattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat)
  575. *
  576. * Routine Description:
  577. *
  578. * This routine contains common code for merging an 8-byte pattern with
  579. * a target surface.
  580. *
  581. * Arguments:
  582. *
  583. * culFill - Supplies the size of the fill in bytes.
  584. * loPat, hiPat - Supplies the 8-byte pattern to merge.
  585. * pulTrg - Supplies the starting target surface address.
  586. *
  587. * Return Value:
  588. *
  589. * None.
  590. *
  591. *
  592. \*************************************************************************/
  593. VOID MergePattern
  594. (
  595. PULONG pulTrg, // Starting target surface address (t0)
  596. LONG culFill, // size of fill in longwords (a1)
  597. LONG hiPat, // hi part of pattern (v1)
  598. LONG loPat // lo part of pattern (v0)
  599. )
  600. {
  601. PULONG pulTrgEnd; // ending target surface address
  602. ULONG temp; // temp for swap
  603. pulTrgEnd = pulTrg + culFill;
  604. // ending target surface address(t4)
  605. //
  606. // If the fill size is not an even multiple of 8 bytes, then move one
  607. // longword and swap the pattern value.
  608. //
  609. if ((culFill & 0x01) != 0)
  610. {
  611. *pulTrg = loPat ^ (*pulTrg); // XOR low 4 bytes of pattern w/ target
  612. pulTrg += 1; // advance target ptr one longword
  613. culFill -= 1;
  614. if (culFill == 0) // if no more to move then we're done
  615. {
  616. return;
  617. }
  618. else // otherwise, swap 8-byte pattern value
  619. {
  620. temp = loPat;
  621. loPat = hiPat;
  622. hiPat = temp;
  623. }
  624. }
  625. //
  626. // Move 8-byte pattern value to target 8 bytes at a time.
  627. //
  628. pulTrgEnd -= 2; // ending segement address
  629. while (pulTrg <= pulTrgEnd) // if not, move 8 bytes at a time
  630. {
  631. *pulTrg = loPat ^ (*pulTrg); // XOR 4-byte pattern value
  632. pulTrg++; // advance target address
  633. *pulTrg = hiPat ^ (*pulTrg); // XOR 4-byte pattern value
  634. pulTrg++; // advance target address
  635. }
  636. return;
  637. }