fb24_32.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. *
  3. * Copyright © 2000 SuSE, Inc.
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and its
  6. * documentation for any purpose is hereby granted without fee, provided that
  7. * the above copyright notice appear in all copies and that both that
  8. * copyright notice and this permission notice appear in supporting
  9. * documentation, and that the name of SuSE not be used in advertising or
  10. * publicity pertaining to distribution of the software without specific,
  11. * written prior permission. SuSE makes no representations about the
  12. * suitability of this software for any purpose. It is provided "as is"
  13. * without express or implied warranty.
  14. *
  15. * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
  17. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21. *
  22. * Author: Keith Packard, SuSE, Inc.
  23. */
  24. #ifdef HAVE_DIX_CONFIG_H
  25. #include <dix-config.h>
  26. #endif
  27. #include <string.h>
  28. #include "fb.h"
  29. /* X apps don't like 24bpp images, this code exposes 32bpp images */
  30. /*
  31. * These two functions do a full CopyArea while reformatting
  32. * the data between 24 and 32bpp. They try to go a bit faster
  33. * by reading/writing aligned CARD32s where it's easy
  34. */
  35. #define Get8(a) ((CARD32) *(a))
  36. #if BITMAP_BIT_ORDER == MSBFirst
  37. #define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
  38. #define Put24(a,p) (((a)[0] = (CARD8) ((p) >> 16)), \
  39. ((a)[1] = (CARD8) ((p) >> 8)), \
  40. ((a)[2] = (CARD8) (p)))
  41. #else
  42. #define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
  43. #define Put24(a,p) (((a)[0] = (CARD8) (p)), \
  44. ((a)[1] = (CARD8) ((p) >> 8)), \
  45. ((a)[2] = (CARD8) ((p) >> 16)))
  46. #endif
  47. typedef void (*fb24_32BltFunc) (CARD8 *srcLine,
  48. FbStride srcStride,
  49. int srcX,
  50. CARD8 *dstLine,
  51. FbStride dstStride,
  52. int dstX,
  53. int width, int height, int alu, FbBits pm);
  54. static void
  55. fb24_32BltDown(CARD8 *srcLine,
  56. FbStride srcStride,
  57. int srcX,
  58. CARD8 *dstLine,
  59. FbStride dstStride,
  60. int dstX, int width, int height, int alu, FbBits pm)
  61. {
  62. CARD32 *src;
  63. CARD8 *dst;
  64. int w;
  65. Bool destInvarient;
  66. CARD32 pixel, dpixel;
  67. FbDeclareMergeRop();
  68. srcLine += srcX * 4;
  69. dstLine += dstX * 3;
  70. FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff));
  71. destInvarient = FbDestInvarientMergeRop();
  72. while (height--) {
  73. src = (CARD32 *) srcLine;
  74. dst = dstLine;
  75. srcLine += srcStride;
  76. dstLine += dstStride;
  77. w = width;
  78. if (destInvarient) {
  79. while (((long) dst & 3) && w) {
  80. w--;
  81. pixel = *src++;
  82. pixel = FbDoDestInvarientMergeRop(pixel);
  83. Put24(dst, pixel);
  84. dst += 3;
  85. }
  86. /* Do four aligned pixels at a time */
  87. while (w >= 4) {
  88. CARD32 s0, s1;
  89. s0 = *src++;
  90. s0 = FbDoDestInvarientMergeRop(s0);
  91. s1 = *src++;
  92. s1 = FbDoDestInvarientMergeRop(s1);
  93. #if BITMAP_BIT_ORDER == LSBFirst
  94. *(CARD32 *) (dst) = (s0 & 0xffffff) | (s1 << 24);
  95. #else
  96. *(CARD32 *) (dst) = (s0 << 8) | ((s1 & 0xffffff) >> 16);
  97. #endif
  98. s0 = *src++;
  99. s0 = FbDoDestInvarientMergeRop(s0);
  100. #if BITMAP_BIT_ORDER == LSBFirst
  101. *(CARD32 *) (dst + 4) = ((s1 & 0xffffff) >> 8) | (s0 << 16);
  102. #else
  103. *(CARD32 *) (dst + 4) = (s1 << 16) | ((s0 & 0xffffff) >> 8);
  104. #endif
  105. s1 = *src++;
  106. s1 = FbDoDestInvarientMergeRop(s1);
  107. #if BITMAP_BIT_ORDER == LSBFirst
  108. *(CARD32 *) (dst + 8) = ((s0 & 0xffffff) >> 16) | (s1 << 8);
  109. #else
  110. *(CARD32 *) (dst + 8) = (s0 << 24) | (s1 & 0xffffff);
  111. #endif
  112. dst += 12;
  113. w -= 4;
  114. }
  115. while (w--) {
  116. pixel = *src++;
  117. pixel = FbDoDestInvarientMergeRop(pixel);
  118. Put24(dst, pixel);
  119. dst += 3;
  120. }
  121. }
  122. else {
  123. while (w--) {
  124. pixel = *src++;
  125. dpixel = Get24(dst);
  126. pixel = FbDoMergeRop(pixel, dpixel);
  127. Put24(dst, pixel);
  128. dst += 3;
  129. }
  130. }
  131. }
  132. }
  133. static void
  134. fb24_32BltUp(CARD8 *srcLine,
  135. FbStride srcStride,
  136. int srcX,
  137. CARD8 *dstLine,
  138. FbStride dstStride,
  139. int dstX, int width, int height, int alu, FbBits pm)
  140. {
  141. CARD8 *src;
  142. CARD32 *dst;
  143. int w;
  144. Bool destInvarient;
  145. CARD32 pixel;
  146. FbDeclareMergeRop();
  147. FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff)));
  148. destInvarient = FbDestInvarientMergeRop();
  149. srcLine += srcX * 3;
  150. dstLine += dstX * 4;
  151. while (height--) {
  152. w = width;
  153. src = srcLine;
  154. dst = (CARD32 *) dstLine;
  155. srcLine += srcStride;
  156. dstLine += dstStride;
  157. if (destInvarient) {
  158. while (((long) src & 3) && w) {
  159. w--;
  160. pixel = Get24(src);
  161. src += 3;
  162. *dst++ = FbDoDestInvarientMergeRop(pixel);
  163. }
  164. /* Do four aligned pixels at a time */
  165. while (w >= 4) {
  166. CARD32 s0, s1;
  167. s0 = *(CARD32 *) (src);
  168. #if BITMAP_BIT_ORDER == LSBFirst
  169. pixel = s0 & 0xffffff;
  170. #else
  171. pixel = s0 >> 8;
  172. #endif
  173. *dst++ = FbDoDestInvarientMergeRop(pixel);
  174. s1 = *(CARD32 *) (src + 4);
  175. #if BITMAP_BIT_ORDER == LSBFirst
  176. pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff);
  177. #else
  178. pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16);
  179. #endif
  180. *dst++ = FbDoDestInvarientMergeRop(pixel);
  181. s0 = *(CARD32 *) (src + 8);
  182. #if BITMAP_BIT_ORDER == LSBFirst
  183. pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff);
  184. #else
  185. pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24);
  186. #endif
  187. *dst++ = FbDoDestInvarientMergeRop(pixel);
  188. #if BITMAP_BIT_ORDER == LSBFirst
  189. pixel = s0 >> 8;
  190. #else
  191. pixel = s0 & 0xffffff;
  192. #endif
  193. *dst++ = FbDoDestInvarientMergeRop(pixel);
  194. src += 12;
  195. w -= 4;
  196. }
  197. while (w) {
  198. w--;
  199. pixel = Get24(src);
  200. src += 3;
  201. *dst++ = FbDoDestInvarientMergeRop(pixel);
  202. }
  203. }
  204. else {
  205. while (w--) {
  206. pixel = Get24(src);
  207. src += 3;
  208. *dst = FbDoMergeRop(pixel, *dst);
  209. dst++;
  210. }
  211. }
  212. }
  213. }
  214. /*
  215. * Spans functions; probably unused.
  216. */
  217. void
  218. fb24_32GetSpans(DrawablePtr pDrawable,
  219. int wMax,
  220. DDXPointPtr ppt, int *pwidth, int nspans, char *pchardstStart)
  221. {
  222. FbBits *srcBits;
  223. CARD8 *src;
  224. FbStride srcStride;
  225. int srcBpp;
  226. int srcXoff, srcYoff;
  227. CARD8 *dst;
  228. fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
  229. src = (CARD8 *) srcBits;
  230. srcStride *= sizeof(FbBits);
  231. while (nspans--) {
  232. dst = (CARD8 *) pchardstStart;
  233. fb24_32BltUp(src + (ppt->y + srcYoff) * srcStride, srcStride,
  234. ppt->x + srcXoff,
  235. dst, 1, 0, *pwidth, 1, GXcopy, FB_ALLONES);
  236. pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth);
  237. ppt++;
  238. pwidth++;
  239. }
  240. }
  241. void
  242. fb24_32SetSpans(DrawablePtr pDrawable,
  243. GCPtr pGC,
  244. char *src,
  245. DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
  246. {
  247. FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
  248. RegionPtr pClip = fbGetCompositeClip(pGC);
  249. FbBits *dstBits;
  250. CARD8 *dst, *d, *s;
  251. FbStride dstStride;
  252. int dstBpp;
  253. int dstXoff, dstYoff;
  254. BoxPtr pbox;
  255. int n;
  256. int x1, x2;
  257. fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
  258. dst = (CARD8 *) dstBits;
  259. dstStride *= sizeof(FbBits);
  260. while (nspans--) {
  261. d = dst + (ppt->y + dstYoff) * dstStride;
  262. s = (CARD8 *) src;
  263. n = REGION_NUM_RECTS(pClip);
  264. pbox = REGION_RECTS(pClip);
  265. while (n--) {
  266. if (pbox->y1 > ppt->y)
  267. break;
  268. if (pbox->y2 > ppt->y) {
  269. x1 = ppt->x;
  270. x2 = x1 + *pwidth;
  271. if (pbox->x1 > x1)
  272. x1 = pbox->x1;
  273. if (pbox->x2 < x2)
  274. x2 = pbox->x2;
  275. if (x1 < x2)
  276. fb24_32BltDown(s,
  277. 0,
  278. (x1 - ppt->x),
  279. d,
  280. dstStride,
  281. x1 + dstXoff,
  282. (x2 - x1), 1, pGC->alu, pPriv->pm);
  283. }
  284. }
  285. src += PixmapBytePad(*pwidth, pDrawable->depth);
  286. ppt++;
  287. pwidth++;
  288. }
  289. }
  290. /*
  291. * Clip and put 32bpp Z-format images to a 24bpp drawable
  292. */
  293. void
  294. fb24_32PutZImage(DrawablePtr pDrawable,
  295. RegionPtr pClip,
  296. int alu,
  297. FbBits pm,
  298. int x,
  299. int y, int width, int height, CARD8 *src, FbStride srcStride)
  300. {
  301. FbBits *dstBits;
  302. CARD8 *dst;
  303. FbStride dstStride;
  304. int dstBpp;
  305. int dstXoff, dstYoff;
  306. int nbox;
  307. BoxPtr pbox;
  308. int x1, y1, x2, y2;
  309. fbGetDrawable(pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
  310. dstStride *= sizeof(FbBits);
  311. dst = (CARD8 *) dstBits;
  312. for (nbox = REGION_NUM_RECTS(pClip),
  313. pbox = REGION_RECTS(pClip); nbox--; pbox++) {
  314. x1 = x;
  315. y1 = y;
  316. x2 = x + width;
  317. y2 = y + height;
  318. if (x1 < pbox->x1)
  319. x1 = pbox->x1;
  320. if (y1 < pbox->y1)
  321. y1 = pbox->y1;
  322. if (x2 > pbox->x2)
  323. x2 = pbox->x2;
  324. if (y2 > pbox->y2)
  325. y2 = pbox->y2;
  326. if (x1 >= x2 || y1 >= y2)
  327. continue;
  328. fb24_32BltDown(src + (y1 - y) * srcStride,
  329. srcStride,
  330. (x1 - x),
  331. dst + (y1 + dstYoff) * dstStride,
  332. dstStride, x1 + dstXoff, (x2 - x1), (y2 - y1), alu, pm);
  333. }
  334. }
  335. void
  336. fb24_32GetImage(DrawablePtr pDrawable,
  337. int x,
  338. int y,
  339. int w,
  340. int h, unsigned int format, unsigned long planeMask, char *d)
  341. {
  342. FbBits *srcBits;
  343. CARD8 *src;
  344. FbStride srcStride;
  345. int srcBpp;
  346. int srcXoff, srcYoff;
  347. FbStride dstStride;
  348. FbBits pm;
  349. fbGetDrawable(pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
  350. src = (CARD8 *) srcBits;
  351. srcStride *= sizeof(FbBits);
  352. x += pDrawable->x;
  353. y += pDrawable->y;
  354. pm = fbReplicatePixel(planeMask, 32);
  355. dstStride = PixmapBytePad(w, pDrawable->depth);
  356. if (pm != FB_ALLONES)
  357. memset(d, 0, dstStride * h);
  358. fb24_32BltUp(src + (y + srcYoff) * srcStride, srcStride, x + srcXoff,
  359. (CARD8 *) d, dstStride, 0, w, h, GXcopy, pm);
  360. }
  361. void
  362. fb24_32CopyMtoN(DrawablePtr pSrcDrawable,
  363. DrawablePtr pDstDrawable,
  364. GCPtr pGC,
  365. BoxPtr pbox,
  366. int nbox,
  367. int dx,
  368. int dy,
  369. Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
  370. {
  371. FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
  372. FbBits *srcBits;
  373. CARD8 *src;
  374. FbStride srcStride;
  375. int srcBpp;
  376. FbBits *dstBits;
  377. CARD8 *dst;
  378. FbStride dstStride;
  379. int dstBpp;
  380. fb24_32BltFunc blt;
  381. int srcXoff, srcYoff;
  382. int dstXoff, dstYoff;
  383. fbGetDrawable(pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
  384. src = (CARD8 *) srcBits;
  385. srcStride *= sizeof(FbBits);
  386. fbGetDrawable(pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
  387. dst = (CARD8 *) dstBits;
  388. dstStride *= sizeof(FbBits);
  389. if (srcBpp == 24)
  390. blt = fb24_32BltUp;
  391. else
  392. blt = fb24_32BltDown;
  393. while (nbox--) {
  394. (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride,
  395. srcStride,
  396. (pbox->x1 + dx + srcXoff),
  397. dst + (pbox->y1 + dstYoff) * dstStride,
  398. dstStride,
  399. (pbox->x1 + dstXoff),
  400. (pbox->x2 - pbox->x1),
  401. (pbox->y2 - pbox->y1), pGC->alu, pPriv->pm);
  402. pbox++;
  403. }
  404. }
  405. PixmapPtr
  406. fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel)
  407. {
  408. ScreenPtr pScreen = pOldTile->drawable.pScreen;
  409. PixmapPtr pNewTile;
  410. FbBits *old, *new;
  411. FbStride oldStride, newStride;
  412. int oldBpp, newBpp;
  413. fb24_32BltFunc blt;
  414. int oldXoff _X_UNUSED, oldYoff _X_UNUSED;
  415. int newXoff _X_UNUSED, newYoff _X_UNUSED;
  416. pNewTile = fbCreatePixmapBpp(pScreen,
  417. pOldTile->drawable.width,
  418. pOldTile->drawable.height,
  419. pOldTile->drawable.depth, bitsPerPixel);
  420. if (!pNewTile)
  421. return 0;
  422. fbGetDrawable(&pOldTile->drawable,
  423. old, oldStride, oldBpp, oldXoff, oldYoff);
  424. fbGetDrawable(&pNewTile->drawable,
  425. new, newStride, newBpp, newXoff, newYoff);
  426. if (oldBpp == 24)
  427. blt = fb24_32BltUp;
  428. else
  429. blt = fb24_32BltDown;
  430. (*blt) ((CARD8 *) old,
  431. oldStride * sizeof(FbBits),
  432. 0,
  433. (CARD8 *) new,
  434. newStride * sizeof(FbBits),
  435. 0,
  436. pOldTile->drawable.width,
  437. pOldTile->drawable.height, GXcopy, FB_ALLONES);
  438. return pNewTile;
  439. }
  440. typedef struct {
  441. pointer pbits;
  442. int width;
  443. } miScreenInitParmsRec, *miScreenInitParmsPtr;
  444. Bool
  445. fb24_32CreateScreenResources(ScreenPtr pScreen)
  446. {
  447. miScreenInitParmsPtr pScrInitParms;
  448. int pitch;
  449. Bool retval;
  450. /* get the pitch before mi destroys it */
  451. pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate;
  452. pitch = BitmapBytePad(pScrInitParms->width * 24);
  453. if ((retval = miCreateScreenResources(pScreen))) {
  454. /* fix the screen pixmap */
  455. PixmapPtr pPix = (PixmapPtr) pScreen->devPrivate;
  456. pPix->drawable.bitsPerPixel = 24;
  457. pPix->devKind = pitch;
  458. }
  459. return retval;
  460. }
  461. Bool
  462. fb24_32ModifyPixmapHeader(PixmapPtr pPixmap,
  463. int width,
  464. int height,
  465. int depth,
  466. int bitsPerPixel, int devKind, pointer pPixData)
  467. {
  468. int bpp, w;
  469. if (!pPixmap)
  470. return FALSE;
  471. bpp = bitsPerPixel;
  472. if (bpp <= 0)
  473. bpp = pPixmap->drawable.bitsPerPixel;
  474. if (bpp == 24) {
  475. if (devKind < 0) {
  476. w = width;
  477. if (w <= 0)
  478. w = pPixmap->drawable.width;
  479. devKind = BitmapBytePad(w * 24);
  480. }
  481. }
  482. return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel,
  483. devKind, pPixData);
  484. }