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