fbblt.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. /*
  2. * Copyright © 1998 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that
  7. * copyright notice and this permission notice appear in supporting
  8. * documentation, and that the name of Keith Packard not be used in
  9. * advertising or publicity pertaining to distribution of the software without
  10. * specific, written prior permission. Keith Packard makes no
  11. * representations about the suitability of this software for any purpose. It
  12. * is provided "as is" without express or implied warranty.
  13. *
  14. * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  20. * PERFORMANCE OF THIS SOFTWARE.
  21. */
  22. #ifdef HAVE_DIX_CONFIG_H
  23. #include <dix-config.h>
  24. #endif
  25. #include <string.h>
  26. #include "fb.h"
  27. #define InitializeShifts(sx,dx,ls,rs) { \
  28. if (sx != dx) { \
  29. if (sx > dx) { \
  30. ls = sx - dx; \
  31. rs = FB_UNIT - ls; \
  32. } else { \
  33. rs = dx - sx; \
  34. ls = FB_UNIT - rs; \
  35. } \
  36. } \
  37. }
  38. void
  39. fbBlt(FbBits * srcLine,
  40. FbStride srcStride,
  41. int srcX,
  42. FbBits * dstLine,
  43. FbStride dstStride,
  44. int dstX,
  45. int width,
  46. int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown)
  47. {
  48. FbBits *src, *dst;
  49. int leftShift, rightShift;
  50. FbBits startmask, endmask;
  51. FbBits bits, bits1;
  52. int n, nmiddle;
  53. Bool destInvarient;
  54. int startbyte, endbyte;
  55. FbDeclareMergeRop();
  56. if (alu == GXcopy && pm == FB_ALLONES &&
  57. !(srcX & 7) && !(dstX & 7) && !(width & 7))
  58. {
  59. CARD8 *src_byte = (CARD8 *) srcLine + (srcX >> 3);
  60. CARD8 *dst_byte = (CARD8 *) dstLine + (dstX >> 3);
  61. FbStride src_byte_stride = srcStride << (FB_SHIFT - 3);
  62. FbStride dst_byte_stride = dstStride << (FB_SHIFT - 3);
  63. int width_byte = (width >> 3);
  64. /* Make sure there's no overlap; we can't use memcpy in that
  65. * case as it's not well defined, so fall through to the
  66. * general code
  67. */
  68. if (src_byte + width_byte <= dst_byte ||
  69. dst_byte + width_byte <= src_byte)
  70. {
  71. int i;
  72. if (!upsidedown)
  73. for (i = 0; i < height; i++)
  74. MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride,
  75. src_byte + i * src_byte_stride,
  76. width_byte);
  77. else
  78. for (i = height - 1; i >= 0; i--)
  79. MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride,
  80. src_byte + i * src_byte_stride,
  81. width_byte);
  82. return;
  83. }
  84. }
  85. if (bpp == 24 && !FbCheck24Pix(pm)) {
  86. fbBlt24(srcLine, srcStride, srcX, dstLine, dstStride, dstX,
  87. width, height, alu, pm, reverse, upsidedown);
  88. return;
  89. }
  90. FbInitializeMergeRop(alu, pm);
  91. destInvarient = FbDestInvarientMergeRop();
  92. if (upsidedown) {
  93. srcLine += (height - 1) * (srcStride);
  94. dstLine += (height - 1) * (dstStride);
  95. srcStride = -srcStride;
  96. dstStride = -dstStride;
  97. }
  98. FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte,
  99. nmiddle, endmask, endbyte);
  100. if (reverse) {
  101. srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
  102. dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
  103. srcX = (srcX + width - 1) & FB_MASK;
  104. dstX = (dstX + width - 1) & FB_MASK;
  105. }
  106. else {
  107. srcLine += srcX >> FB_SHIFT;
  108. dstLine += dstX >> FB_SHIFT;
  109. srcX &= FB_MASK;
  110. dstX &= FB_MASK;
  111. }
  112. if (srcX == dstX) {
  113. while (height--) {
  114. src = srcLine;
  115. srcLine += srcStride;
  116. dst = dstLine;
  117. dstLine += dstStride;
  118. if (reverse) {
  119. if (endmask) {
  120. bits = READ(--src);
  121. --dst;
  122. FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
  123. }
  124. n = nmiddle;
  125. if (destInvarient) {
  126. while (n--)
  127. WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src)));
  128. }
  129. else {
  130. while (n--) {
  131. bits = READ(--src);
  132. --dst;
  133. WRITE(dst, FbDoMergeRop(bits, READ(dst)));
  134. }
  135. }
  136. if (startmask) {
  137. bits = READ(--src);
  138. --dst;
  139. FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
  140. }
  141. }
  142. else {
  143. if (startmask) {
  144. bits = READ(src++);
  145. FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
  146. dst++;
  147. }
  148. n = nmiddle;
  149. if (destInvarient) {
  150. #if 0
  151. /*
  152. * This provides some speedup on screen->screen blts
  153. * over the PCI bus, usually about 10%. But fb
  154. * isn't usually used for this operation...
  155. */
  156. if (_ca2 + 1 == 0 && _cx2 == 0) {
  157. FbBits t1, t2, t3, t4;
  158. while (n >= 4) {
  159. t1 = *src++;
  160. t2 = *src++;
  161. t3 = *src++;
  162. t4 = *src++;
  163. *dst++ = t1;
  164. *dst++ = t2;
  165. *dst++ = t3;
  166. *dst++ = t4;
  167. n -= 4;
  168. }
  169. }
  170. #endif
  171. while (n--)
  172. WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++)));
  173. }
  174. else {
  175. while (n--) {
  176. bits = READ(src++);
  177. WRITE(dst, FbDoMergeRop(bits, READ(dst)));
  178. dst++;
  179. }
  180. }
  181. if (endmask) {
  182. bits = READ(src);
  183. FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
  184. }
  185. }
  186. }
  187. }
  188. else {
  189. if (srcX > dstX) {
  190. leftShift = srcX - dstX;
  191. rightShift = FB_UNIT - leftShift;
  192. }
  193. else {
  194. rightShift = dstX - srcX;
  195. leftShift = FB_UNIT - rightShift;
  196. }
  197. while (height--) {
  198. src = srcLine;
  199. srcLine += srcStride;
  200. dst = dstLine;
  201. dstLine += dstStride;
  202. bits1 = 0;
  203. if (reverse) {
  204. if (srcX < dstX)
  205. bits1 = READ(--src);
  206. if (endmask) {
  207. bits = FbScrRight(bits1, rightShift);
  208. if (FbScrRight(endmask, leftShift)) {
  209. bits1 = READ(--src);
  210. bits |= FbScrLeft(bits1, leftShift);
  211. }
  212. --dst;
  213. FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
  214. }
  215. n = nmiddle;
  216. if (destInvarient) {
  217. while (n--) {
  218. bits = FbScrRight(bits1, rightShift);
  219. bits1 = READ(--src);
  220. bits |= FbScrLeft(bits1, leftShift);
  221. --dst;
  222. WRITE(dst, FbDoDestInvarientMergeRop(bits));
  223. }
  224. }
  225. else {
  226. while (n--) {
  227. bits = FbScrRight(bits1, rightShift);
  228. bits1 = READ(--src);
  229. bits |= FbScrLeft(bits1, leftShift);
  230. --dst;
  231. WRITE(dst, FbDoMergeRop(bits, READ(dst)));
  232. }
  233. }
  234. if (startmask) {
  235. bits = FbScrRight(bits1, rightShift);
  236. if (FbScrRight(startmask, leftShift)) {
  237. bits1 = READ(--src);
  238. bits |= FbScrLeft(bits1, leftShift);
  239. }
  240. --dst;
  241. FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
  242. }
  243. }
  244. else {
  245. if (srcX > dstX)
  246. bits1 = READ(src++);
  247. if (startmask) {
  248. bits = FbScrLeft(bits1, leftShift);
  249. if (FbScrLeft(startmask, rightShift)) {
  250. bits1 = READ(src++);
  251. bits |= FbScrRight(bits1, rightShift);
  252. }
  253. FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
  254. dst++;
  255. }
  256. n = nmiddle;
  257. if (destInvarient) {
  258. while (n--) {
  259. bits = FbScrLeft(bits1, leftShift);
  260. bits1 = READ(src++);
  261. bits |= FbScrRight(bits1, rightShift);
  262. WRITE(dst, FbDoDestInvarientMergeRop(bits));
  263. dst++;
  264. }
  265. }
  266. else {
  267. while (n--) {
  268. bits = FbScrLeft(bits1, leftShift);
  269. bits1 = READ(src++);
  270. bits |= FbScrRight(bits1, rightShift);
  271. WRITE(dst, FbDoMergeRop(bits, READ(dst)));
  272. dst++;
  273. }
  274. }
  275. if (endmask) {
  276. bits = FbScrLeft(bits1, leftShift);
  277. if (FbScrLeft(endmask, rightShift)) {
  278. bits1 = READ(src);
  279. bits |= FbScrRight(bits1, rightShift);
  280. }
  281. FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
  282. }
  283. }
  284. }
  285. }
  286. }
  287. #undef DEBUG_BLT24
  288. #ifdef DEBUG_BLT24
  289. static unsigned long
  290. getPixel(char *src, int x)
  291. {
  292. unsigned long l;
  293. l = 0;
  294. memcpy(&l, src + x * 3, 3);
  295. return l;
  296. }
  297. #endif
  298. static void
  299. fbBlt24Line(FbBits * src,
  300. int srcX,
  301. FbBits * dst, int dstX, int width, int alu, FbBits pm, Bool reverse)
  302. {
  303. #ifdef DEBUG_BLT24
  304. char *origDst = (char *) dst;
  305. FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
  306. int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
  307. int origX = dstX / 24;
  308. #endif
  309. int leftShift, rightShift;
  310. FbBits startmask, endmask;
  311. int n;
  312. FbBits bits, bits1;
  313. FbBits mask;
  314. int rot;
  315. FbDeclareMergeRop();
  316. FbInitializeMergeRop(alu, FB_ALLONES);
  317. FbMaskBits(dstX, width, startmask, n, endmask);
  318. #ifdef DEBUG_BLT24
  319. ErrorF("dstX %d width %d reverse %d\n", dstX, width, reverse);
  320. #endif
  321. if (reverse) {
  322. src += ((srcX + width - 1) >> FB_SHIFT) + 1;
  323. dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
  324. rot = FbFirst24Rot(((dstX + width - 8) & FB_MASK));
  325. rot = FbPrev24Rot(rot);
  326. #ifdef DEBUG_BLT24
  327. ErrorF("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK,
  328. rot);
  329. #endif
  330. srcX = (srcX + width - 1) & FB_MASK;
  331. dstX = (dstX + width - 1) & FB_MASK;
  332. }
  333. else {
  334. src += srcX >> FB_SHIFT;
  335. dst += dstX >> FB_SHIFT;
  336. srcX &= FB_MASK;
  337. dstX &= FB_MASK;
  338. rot = FbFirst24Rot(dstX);
  339. #ifdef DEBUG_BLT24
  340. ErrorF("dstX: %d rot: %d\n", dstX, rot);
  341. #endif
  342. }
  343. mask = FbRot24(pm, rot);
  344. #ifdef DEBUG_BLT24
  345. ErrorF("pm 0x%x mask 0x%x\n", pm, mask);
  346. #endif
  347. if (srcX == dstX) {
  348. if (reverse) {
  349. if (endmask) {
  350. bits = READ(--src);
  351. --dst;
  352. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
  353. mask = FbPrev24Pix(mask);
  354. }
  355. while (n--) {
  356. bits = READ(--src);
  357. --dst;
  358. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
  359. mask = FbPrev24Pix(mask);
  360. }
  361. if (startmask) {
  362. bits = READ(--src);
  363. --dst;
  364. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
  365. }
  366. }
  367. else {
  368. if (startmask) {
  369. bits = READ(src++);
  370. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
  371. dst++;
  372. mask = FbNext24Pix(mask);
  373. }
  374. while (n--) {
  375. bits = READ(src++);
  376. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
  377. dst++;
  378. mask = FbNext24Pix(mask);
  379. }
  380. if (endmask) {
  381. bits = READ(src);
  382. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
  383. }
  384. }
  385. }
  386. else {
  387. if (srcX > dstX) {
  388. leftShift = srcX - dstX;
  389. rightShift = FB_UNIT - leftShift;
  390. }
  391. else {
  392. rightShift = dstX - srcX;
  393. leftShift = FB_UNIT - rightShift;
  394. }
  395. bits1 = 0;
  396. if (reverse) {
  397. if (srcX < dstX)
  398. bits1 = READ(--src);
  399. if (endmask) {
  400. bits = FbScrRight(bits1, rightShift);
  401. if (FbScrRight(endmask, leftShift)) {
  402. bits1 = READ(--src);
  403. bits |= FbScrLeft(bits1, leftShift);
  404. }
  405. --dst;
  406. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
  407. mask = FbPrev24Pix(mask);
  408. }
  409. while (n--) {
  410. bits = FbScrRight(bits1, rightShift);
  411. bits1 = READ(--src);
  412. bits |= FbScrLeft(bits1, leftShift);
  413. --dst;
  414. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
  415. mask = FbPrev24Pix(mask);
  416. }
  417. if (startmask) {
  418. bits = FbScrRight(bits1, rightShift);
  419. if (FbScrRight(startmask, leftShift)) {
  420. bits1 = READ(--src);
  421. bits |= FbScrLeft(bits1, leftShift);
  422. }
  423. --dst;
  424. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
  425. }
  426. }
  427. else {
  428. if (srcX > dstX)
  429. bits1 = READ(src++);
  430. if (startmask) {
  431. bits = FbScrLeft(bits1, leftShift);
  432. bits1 = READ(src++);
  433. bits |= FbScrRight(bits1, rightShift);
  434. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
  435. dst++;
  436. mask = FbNext24Pix(mask);
  437. }
  438. while (n--) {
  439. bits = FbScrLeft(bits1, leftShift);
  440. bits1 = READ(src++);
  441. bits |= FbScrRight(bits1, rightShift);
  442. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
  443. dst++;
  444. mask = FbNext24Pix(mask);
  445. }
  446. if (endmask) {
  447. bits = FbScrLeft(bits1, leftShift);
  448. if (FbScrLeft(endmask, rightShift)) {
  449. bits1 = READ(src);
  450. bits |= FbScrRight(bits1, rightShift);
  451. }
  452. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
  453. }
  454. }
  455. }
  456. #ifdef DEBUG_BLT24
  457. {
  458. int firstx, lastx, x;
  459. firstx = origX;
  460. if (firstx)
  461. firstx--;
  462. lastx = origX + width / 24 + 1;
  463. for (x = firstx; x <= lastx; x++)
  464. ErrorF("%06x ", getPixel(origDst, x));
  465. ErrorF("\n");
  466. while (origNlw--)
  467. ErrorF("%08x ", *origLine++);
  468. ErrorF("\n");
  469. }
  470. #endif
  471. }
  472. void
  473. fbBlt24(FbBits * srcLine,
  474. FbStride srcStride,
  475. int srcX,
  476. FbBits * dstLine,
  477. FbStride dstStride,
  478. int dstX,
  479. int width,
  480. int height, int alu, FbBits pm, Bool reverse, Bool upsidedown)
  481. {
  482. if (upsidedown) {
  483. srcLine += (height - 1) * srcStride;
  484. dstLine += (height - 1) * dstStride;
  485. srcStride = -srcStride;
  486. dstStride = -dstStride;
  487. }
  488. while (height--) {
  489. fbBlt24Line(srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
  490. srcLine += srcStride;
  491. dstLine += dstStride;
  492. }
  493. #ifdef DEBUG_BLT24
  494. ErrorF("\n");
  495. #endif
  496. }
  497. #if FB_SHIFT == FB_STIP_SHIFT + 1
  498. /*
  499. * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
  500. * creating an ring of values stepped through for each line
  501. */
  502. void
  503. fbBltOdd(FbBits * srcLine,
  504. FbStride srcStrideEven,
  505. FbStride srcStrideOdd,
  506. int srcXEven,
  507. int srcXOdd,
  508. FbBits * dstLine,
  509. FbStride dstStrideEven,
  510. FbStride dstStrideOdd,
  511. int dstXEven,
  512. int dstXOdd, int width, int height, int alu, FbBits pm, int bpp)
  513. {
  514. FbBits *src;
  515. int leftShiftEven, rightShiftEven;
  516. FbBits startmaskEven, endmaskEven;
  517. int nmiddleEven;
  518. FbBits *dst;
  519. int leftShiftOdd, rightShiftOdd;
  520. FbBits startmaskOdd, endmaskOdd;
  521. int nmiddleOdd;
  522. int leftShift, rightShift;
  523. FbBits startmask, endmask;
  524. int nmiddle;
  525. int srcX, dstX;
  526. FbBits bits, bits1;
  527. int n;
  528. Bool destInvarient;
  529. Bool even;
  530. FbDeclareMergeRop();
  531. FbInitializeMergeRop(alu, pm);
  532. destInvarient = FbDestInvarientMergeRop();
  533. srcLine += srcXEven >> FB_SHIFT;
  534. dstLine += dstXEven >> FB_SHIFT;
  535. srcXEven &= FB_MASK;
  536. dstXEven &= FB_MASK;
  537. srcXOdd &= FB_MASK;
  538. dstXOdd &= FB_MASK;
  539. FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
  540. FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
  541. even = TRUE;
  542. InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
  543. InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
  544. while (height--) {
  545. src = srcLine;
  546. dst = dstLine;
  547. if (even) {
  548. srcX = srcXEven;
  549. dstX = dstXEven;
  550. startmask = startmaskEven;
  551. endmask = endmaskEven;
  552. nmiddle = nmiddleEven;
  553. leftShift = leftShiftEven;
  554. rightShift = rightShiftEven;
  555. srcLine += srcStrideEven;
  556. dstLine += dstStrideEven;
  557. even = FALSE;
  558. }
  559. else {
  560. srcX = srcXOdd;
  561. dstX = dstXOdd;
  562. startmask = startmaskOdd;
  563. endmask = endmaskOdd;
  564. nmiddle = nmiddleOdd;
  565. leftShift = leftShiftOdd;
  566. rightShift = rightShiftOdd;
  567. srcLine += srcStrideOdd;
  568. dstLine += dstStrideOdd;
  569. even = TRUE;
  570. }
  571. if (srcX == dstX) {
  572. if (startmask) {
  573. bits = READ(src++);
  574. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), startmask));
  575. dst++;
  576. }
  577. n = nmiddle;
  578. if (destInvarient) {
  579. while (n--) {
  580. bits = READ(src++);
  581. WRITE(dst, FbDoDestInvarientMergeRop(bits));
  582. dst++;
  583. }
  584. }
  585. else {
  586. while (n--) {
  587. bits = READ(src++);
  588. WRITE(dst, FbDoMergeRop(bits, READ(dst)));
  589. dst++;
  590. }
  591. }
  592. if (endmask) {
  593. bits = READ(src);
  594. WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask));
  595. }
  596. }
  597. else {
  598. bits = 0;
  599. if (srcX > dstX)
  600. bits = READ(src++);
  601. if (startmask) {
  602. bits1 = FbScrLeft(bits, leftShift);
  603. bits = READ(src++);
  604. bits1 |= FbScrRight(bits, rightShift);
  605. WRITE(dst, FbDoMaskMergeRop(bits1, READ(dst), startmask));
  606. dst++;
  607. }
  608. n = nmiddle;
  609. if (destInvarient) {
  610. while (n--) {
  611. bits1 = FbScrLeft(bits, leftShift);
  612. bits = READ(src++);
  613. bits1 |= FbScrRight(bits, rightShift);
  614. WRITE(dst, FbDoDestInvarientMergeRop(bits1));
  615. dst++;
  616. }
  617. }
  618. else {
  619. while (n--) {
  620. bits1 = FbScrLeft(bits, leftShift);
  621. bits = READ(src++);
  622. bits1 |= FbScrRight(bits, rightShift);
  623. WRITE(dst, FbDoMergeRop(bits1, READ(dst)));
  624. dst++;
  625. }
  626. }
  627. if (endmask) {
  628. bits1 = FbScrLeft(bits, leftShift);
  629. if (FbScrLeft(endmask, rightShift)) {
  630. bits = READ(src);
  631. bits1 |= FbScrRight(bits, rightShift);
  632. }
  633. WRITE(dst, FbDoMaskMergeRop(bits1, READ(dst), endmask));
  634. }
  635. }
  636. }
  637. }
  638. void
  639. fbBltOdd24(FbBits * srcLine,
  640. FbStride srcStrideEven,
  641. FbStride srcStrideOdd,
  642. int srcXEven,
  643. int srcXOdd,
  644. FbBits * dstLine,
  645. FbStride dstStrideEven,
  646. FbStride dstStrideOdd,
  647. int dstXEven, int dstXOdd, int width, int height, int alu, FbBits pm)
  648. {
  649. Bool even = TRUE;
  650. while (height--) {
  651. if (even) {
  652. fbBlt24Line(srcLine, srcXEven, dstLine, dstXEven,
  653. width, alu, pm, FALSE);
  654. srcLine += srcStrideEven;
  655. dstLine += dstStrideEven;
  656. even = FALSE;
  657. }
  658. else {
  659. fbBlt24Line(srcLine, srcXOdd, dstLine, dstXOdd,
  660. width, alu, pm, FALSE);
  661. srcLine += srcStrideOdd;
  662. dstLine += dstStrideOdd;
  663. even = TRUE;
  664. }
  665. }
  666. }
  667. #endif
  668. #if FB_STIP_SHIFT != FB_SHIFT
  669. void
  670. fbSetBltOdd(FbStip * stip,
  671. FbStride stipStride,
  672. int srcX,
  673. FbBits ** bits,
  674. FbStride * strideEven,
  675. FbStride * strideOdd, int *srcXEven, int *srcXOdd)
  676. {
  677. int srcAdjust;
  678. int strideAdjust;
  679. /*
  680. * bytes needed to align source
  681. */
  682. srcAdjust = (((int) stip) & (FB_MASK >> 3));
  683. /*
  684. * FbStip units needed to align stride
  685. */
  686. strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
  687. *bits = (FbBits *) ((char *) stip - srcAdjust);
  688. if (srcAdjust) {
  689. *strideEven = FbStipStrideToBitsStride(stipStride + 1);
  690. *strideOdd = FbStipStrideToBitsStride(stipStride);
  691. *srcXEven = srcX + (srcAdjust << 3);
  692. *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
  693. }
  694. else {
  695. *strideEven = FbStipStrideToBitsStride(stipStride);
  696. *strideOdd = FbStipStrideToBitsStride(stipStride + 1);
  697. *srcXEven = srcX;
  698. *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
  699. }
  700. }
  701. #endif
  702. void
  703. fbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */
  704. int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */
  705. int dstX, int width, int height, int alu, FbBits pm, int bpp)
  706. {
  707. #if FB_STIP_SHIFT != FB_SHIFT
  708. if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
  709. FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) {
  710. FbStride srcStrideEven, srcStrideOdd;
  711. FbStride dstStrideEven, dstStrideOdd;
  712. int srcXEven, srcXOdd;
  713. int dstXEven, dstXOdd;
  714. FbBits *s, *d;
  715. int sx, dx;
  716. src += srcX >> FB_STIP_SHIFT;
  717. srcX &= FB_STIP_MASK;
  718. dst += dstX >> FB_STIP_SHIFT;
  719. dstX &= FB_STIP_MASK;
  720. fbSetBltOdd(src, srcStride, srcX,
  721. &s, &srcStrideEven, &srcStrideOdd, &srcXEven, &srcXOdd);
  722. fbSetBltOdd(dst, dstStride, dstX,
  723. &d, &dstStrideEven, &dstStrideOdd, &dstXEven, &dstXOdd);
  724. if (bpp == 24 && !FbCheck24Pix(pm)) {
  725. fbBltOdd24(s, srcStrideEven, srcStrideOdd,
  726. srcXEven, srcXOdd,
  727. d, dstStrideEven, dstStrideOdd,
  728. dstXEven, dstXOdd, width, height, alu, pm);
  729. }
  730. else {
  731. fbBltOdd(s, srcStrideEven, srcStrideOdd,
  732. srcXEven, srcXOdd,
  733. d, dstStrideEven, dstStrideOdd,
  734. dstXEven, dstXOdd, width, height, alu, pm, bpp);
  735. }
  736. }
  737. else
  738. #endif
  739. {
  740. fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride),
  741. srcX,
  742. (FbBits *) dst, FbStipStrideToBitsStride(dstStride),
  743. dstX, width, height, alu, pm, bpp, FALSE, FALSE);
  744. }
  745. }