1 /*
2 * Copyright © 2000 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
23 #ifdef HAVE_DIX_CONFIG_H
24 #include "dix-config.h"
25 #endif
26
27 #include "shadow.h"
28 #include "fb.h"
29
30 #define Get8(a) ((CARD32) READ(a))
31
32 #if BITMAP_BIT_ORDER == MSBFirst
33 #define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2))
34 #define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \
35 (WRITE((a+1), (CARD8) ((p) >> 8))), \
36 (WRITE((a+2), (CARD8) (p))))
37 #else
38 #define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16))
39 #define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \
40 (WRITE((a+1), (CARD8) ((p) >> 8))), \
41 (WRITE((a+2), (CARD8) ((p) >> 16))))
42 #endif
43
44 static void
sh24_32BltLine(CARD8 * srcLine,CARD8 * dstLine,int width)45 sh24_32BltLine(CARD8 *srcLine,
46 CARD8 *dstLine,
47 int width)
48 {
49 CARD32 *src;
50 CARD8 *dst;
51 int w;
52 CARD32 pixel;
53
54 src = (CARD32 *) srcLine;
55 dst = dstLine;
56 w = width;
57
58 while (((long)dst & 3) && w) {
59 w--;
60 pixel = READ(src++);
61 Put24(dst, pixel);
62 dst += 3;
63 }
64 /* Do four aligned pixels at a time */
65 while (w >= 4) {
66 CARD32 s0, s1;
67
68 s0 = READ(src++);
69 s1 = READ(src++);
70 #if BITMAP_BIT_ORDER == LSBFirst
71 WRITE((CARD32 *) dst, (s0 & 0xffffff) | (s1 << 24));
72 #else
73 WRITE((CARD32 *) dst, (s0 << 8) | ((s1 & 0xffffff) >> 16));
74 #endif
75 s0 = READ(src++);
76 #if BITMAP_BIT_ORDER == LSBFirst
77 WRITE((CARD32 *) (dst + 4),
78 ((s1 & 0xffffff) >> 8) | (s0 << 16));
79 #else
80 WRITE((CARD32 *) (dst + 4),
81 (s1 << 16) | ((s0 & 0xffffff) >> 8));
82 #endif
83 s1 = READ(src++);
84 #if BITMAP_BIT_ORDER == LSBFirst
85 WRITE((CARD32 *) (dst + 8),
86 ((s0 & 0xffffff) >> 16) | (s1 << 8));
87 #else
88 WRITE((CARD32 *) (dst + 8), (s0 << 24) | (s1 & 0xffffff));
89 #endif
90 dst += 12;
91 w -= 4;
92 }
93 while (w--) {
94 pixel = READ(src++);
95 Put24(dst, pixel);
96 dst += 3;
97 }
98 }
99
100 void
shadowUpdate32to24(ScreenPtr pScreen,shadowBufPtr pBuf)101 shadowUpdate32to24(ScreenPtr pScreen, shadowBufPtr pBuf)
102 {
103 RegionPtr damage = DamageRegion(pBuf->pDamage);
104 PixmapPtr pShadow = pBuf->pPixmap;
105 int nbox = RegionNumRects(damage);
106 BoxPtr pbox = RegionRects(damage);
107 FbStride shaStride;
108 int shaBpp;
109 _X_UNUSED int shaXoff, shaYoff;
110 int x, y, w, h;
111 CARD32 winSize;
112 FbBits *shaBase, *shaLine;
113 CARD8 *winBase = NULL, *winLine;
114
115 fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
116 shaYoff);
117
118 /* just get the initial window base + stride */
119 winBase = (*pBuf->window)(pScreen, 0, 0, SHADOW_WINDOW_WRITE,
120 &winSize, pBuf->closure);
121
122 while (nbox--) {
123 x = pbox->x1;
124 y = pbox->y1;
125 w = pbox->x2 - pbox->x1;
126 h = pbox->y2 - pbox->y1;
127
128 winLine = winBase + y * winSize + (x * 3);
129 shaLine = shaBase + y * shaStride + ((x * shaBpp) >> FB_SHIFT);
130
131 while (h--) {
132 sh24_32BltLine((CARD8 *)shaLine, (CARD8 *)winLine, w);
133 winLine += winSize;
134 shaLine += shaStride;
135 }
136 pbox++;
137 }
138 }
139