1 /*
2  * Copyright © 2004 Philip Blundell
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 Philip Blundell not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Philip Blundell 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  * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL PHILIP BLUNDELL 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 #include    <X11/X.h>
24 #include    "scrnintstr.h"
25 #include    "windowstr.h"
26 #include    "dixfontstr.h"
27 #include    "mi.h"
28 #include    "regionstr.h"
29 #include    "globals.h"
30 #include    "gcstruct.h"
31 #include    "shadow.h"
32 #include    "fb.h"
33 
34 #if ROTATE == 270
35 
36 #define WINSTEPX(stride)    (stride)
37 #define WINSTART(x,y)       (((pScreen->height - 1) - y) + (x * winStride))
38 #define WINSTEPY()	    -1
39 
40 #elif ROTATE == 90
41 
42 #define WINSTEPX(stride)    (-stride)
43 #define WINSTEPY()	    1
44 #define WINSTART(x,y)       (((pScreen->width - 1 - x) * winStride) + y)
45 
46 #else
47 
48 #error This rotation is not supported here
49 
50 #endif
51 
52 #ifdef __arm__
53 #define PREFETCH
54 #endif
55 
56 void
FUNC(ScreenPtr pScreen,shadowBufPtr pBuf)57 FUNC(ScreenPtr pScreen, shadowBufPtr pBuf)
58 {
59     RegionPtr damage = DamageRegion(pBuf->pDamage);
60     PixmapPtr pShadow = pBuf->pPixmap;
61     int nbox = RegionNumRects(damage);
62     BoxPtr pbox = RegionRects(damage);
63     FbBits *shaBits;
64     Data *shaBase, *shaLine, *sha;
65     FbStride shaStride, winStride;
66     int shaBpp;
67     _X_UNUSED int shaXoff, shaYoff;
68     int x, y, w, h;
69     Data *winBase, *win, *winLine;
70     CARD32 winSize;
71 
72     fbGetDrawable(&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff,
73                   shaYoff);
74     shaBase = (Data *) shaBits;
75     shaStride = shaStride * sizeof(FbBits) / sizeof(Data);
76 
77     winBase = (Data *) (*pBuf->window) (pScreen, 0, 0,
78                                         SHADOW_WINDOW_WRITE,
79                                         &winSize, pBuf->closure);
80     winStride = (Data *) (*pBuf->window) (pScreen, 1, 0,
81                                           SHADOW_WINDOW_WRITE,
82                                           &winSize, pBuf->closure) - winBase;
83 
84     while (nbox--) {
85         x = pbox->x1;
86         y = pbox->y1;
87         w = (pbox->x2 - pbox->x1);
88         h = pbox->y2 - pbox->y1;
89 
90         shaLine = shaBase + (y * shaStride) + x;
91 #ifdef PREFETCH
92         __builtin_prefetch(shaLine);
93 #endif
94         winLine = winBase + WINSTART(x, y);
95 
96         while (h--) {
97             sha = shaLine;
98             win = winLine;
99 
100             while (sha < (shaLine + w - 16)) {
101 #ifdef PREFETCH
102                 __builtin_prefetch(sha + shaStride);
103 #endif
104                 *win = *sha++;
105                 win += WINSTEPX(winStride);
106                 *win = *sha++;
107                 win += WINSTEPX(winStride);
108                 *win = *sha++;
109                 win += WINSTEPX(winStride);
110                 *win = *sha++;
111                 win += WINSTEPX(winStride);
112 
113                 *win = *sha++;
114                 win += WINSTEPX(winStride);
115                 *win = *sha++;
116                 win += WINSTEPX(winStride);
117                 *win = *sha++;
118                 win += WINSTEPX(winStride);
119                 *win = *sha++;
120                 win += WINSTEPX(winStride);
121 
122                 *win = *sha++;
123                 win += WINSTEPX(winStride);
124                 *win = *sha++;
125                 win += WINSTEPX(winStride);
126                 *win = *sha++;
127                 win += WINSTEPX(winStride);
128                 *win = *sha++;
129                 win += WINSTEPX(winStride);
130 
131                 *win = *sha++;
132                 win += WINSTEPX(winStride);
133                 *win = *sha++;
134                 win += WINSTEPX(winStride);
135                 *win = *sha++;
136                 win += WINSTEPX(winStride);
137                 *win = *sha++;
138                 win += WINSTEPX(winStride);
139             }
140 
141             while (sha < (shaLine + w)) {
142                 *win = *sha++;
143                 win += WINSTEPX(winStride);
144             }
145 
146             y++;
147             shaLine += shaStride;
148             winLine += WINSTEPY();
149         }
150         pbox++;
151     }                           /*  nbox */
152 }
153