]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/xserver.git/blob - miext/shadow/shrotate.c
Imported Upstream version 1.11.4
[glsdk/xserver.git] / miext / shadow / shrotate.c
1 /*
2  *
3  * Copyright © 2001 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
10  * advertising or publicity pertaining to distribution of the software without
11  * specific, written prior permission.  Keith Packard makes no
12  * representations about the suitability of this software for any purpose.  It
13  * is provided "as is" without express or implied warranty.
14  *
15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21  * PERFORMANCE OF THIS SOFTWARE.
22  */
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
28 #include    <X11/X.h>
29 #include    "scrnintstr.h"
30 #include    "windowstr.h"
31 #include    <X11/fonts/font.h>
32 #include    "dixfontstr.h"
33 #include    <X11/fonts/fontstruct.h>
34 #include    "mi.h"
35 #include    "regionstr.h"
36 #include    "globals.h"
37 #include    "gcstruct.h"
38 #include    "shadow.h"
39 #include    "fb.h"
41 /*
42  * These indicate which way the source (shadow) is scanned when
43  * walking the screen in a particular direction
44  */
46 #define LEFT_TO_RIGHT   1
47 #define RIGHT_TO_LEFT   -1
48 #define TOP_TO_BOTTOM   2
49 #define BOTTOM_TO_TOP   -2
51 void
52 shadowUpdateRotatePacked (ScreenPtr     pScreen,
53                           shadowBufPtr  pBuf)
54 {
55     RegionPtr   damage = shadowDamage (pBuf);
56     PixmapPtr   pShadow = pBuf->pPixmap;
57     int         nbox = RegionNumRects (damage);
58     BoxPtr      pbox = RegionRects (damage);
59     FbBits      *shaBits;
60     FbStride    shaStride;
61     int         shaBpp;
62     _X_UNUSED int       shaXoff, shaYoff;
63     int         box_x1, box_x2, box_y1, box_y2;
64     int         sha_x1 = 0, sha_y1 = 0;
65     int         scr_x1 = 0, scr_x2 = 0, scr_y1 = 0, scr_y2 = 0, scr_w, scr_h;
66     int         scr_x, scr_y;
67     int         w;
68     int         pixelsPerBits;
69     int         pixelsMask;
70     FbStride    shaStepOverY = 0, shaStepDownY = 0;
71     FbStride    shaStepOverX = 0, shaStepDownX = 0;
72     FbBits      *shaLine, *sha;
73     int         shaHeight = pShadow->drawable.height;
74     int         shaWidth = pShadow->drawable.width;
75     FbBits      shaMask;
76     int         shaFirstShift, shaShift;
77     int         o_x_dir;
78     int         o_y_dir;
79     int         x_dir;
80     int         y_dir;
82     fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp, shaXoff, shaYoff);
83     pixelsPerBits = (sizeof (FbBits) * 8) / shaBpp;
84     pixelsMask = ~(pixelsPerBits - 1);
85     shaMask = FbBitsMask (FB_UNIT-shaBpp, shaBpp);
86     /*
87      * Compute rotation related constants to walk the shadow
88      */
89     o_x_dir = LEFT_TO_RIGHT;
90     o_y_dir = TOP_TO_BOTTOM;
91     if (pBuf->randr & SHADOW_REFLECT_X)
92         o_x_dir = -o_x_dir;
93     if (pBuf->randr & SHADOW_REFLECT_Y)
94         o_y_dir = -o_y_dir;
95     switch (pBuf->randr & (SHADOW_ROTATE_ALL)) {
96     case SHADOW_ROTATE_0:       /* upper left shadow -> upper left screen */
97     default:
98         x_dir = o_x_dir;
99         y_dir = o_y_dir;
100         break;
101     case SHADOW_ROTATE_90:      /* upper right shadow -> upper left screen */
102         x_dir = o_y_dir;
103         y_dir = -o_x_dir;
104         break;
105     case SHADOW_ROTATE_180:     /* lower right shadow -> upper left screen */
106         x_dir = -o_x_dir;
107         y_dir = -o_y_dir;
108         break;
109     case SHADOW_ROTATE_270:     /* lower left shadow -> upper left screen */
110         x_dir = -o_y_dir;
111         y_dir = o_x_dir;
112         break;
113     }
114     switch (x_dir) {
115     case LEFT_TO_RIGHT:
116         shaStepOverX = shaBpp;
117         shaStepOverY = 0;
118         break;
119     case TOP_TO_BOTTOM:
120         shaStepOverX = 0;
121         shaStepOverY = shaStride;
122         break;
123     case RIGHT_TO_LEFT:
124         shaStepOverX = -shaBpp;
125         shaStepOverY = 0;
126         break;
127     case BOTTOM_TO_TOP:
128         shaStepOverX = 0;
129         shaStepOverY = -shaStride;
130         break;
131     }
132     switch (y_dir) {
133     case TOP_TO_BOTTOM:
134         shaStepDownX = 0;
135         shaStepDownY = shaStride;
136         break;
137     case RIGHT_TO_LEFT:
138         shaStepDownX = -shaBpp;
139         shaStepDownY = 0;
140         break;
141     case BOTTOM_TO_TOP:
142         shaStepDownX = 0;
143         shaStepDownY = -shaStride;
144         break;
145     case LEFT_TO_RIGHT:
146         shaStepDownX = shaBpp;
147         shaStepDownY = 0;
148         break;
149     }
150     
151     while (nbox--)
152     {
153         box_x1 = pbox->x1;
154         box_y1 = pbox->y1;
155         box_x2 = pbox->x2;
156         box_y2 = pbox->y2;
157         pbox++;
159         /*
160          * Compute screen and shadow locations for this box
161          */
162         switch (x_dir) {
163         case LEFT_TO_RIGHT:
164             scr_x1 = box_x1 & pixelsMask;
165             scr_x2 = (box_x2 + pixelsPerBits - 1) & pixelsMask;
166             
167             sha_x1 = scr_x1;
168             break;
169         case TOP_TO_BOTTOM:
170             scr_x1 = box_y1 & pixelsMask;
171             scr_x2 = (box_y2 + pixelsPerBits - 1) & pixelsMask;
173             sha_y1 = scr_x1;
174             break;
175         case RIGHT_TO_LEFT:
176             scr_x1 = (shaWidth - box_x2) & pixelsMask;
177             scr_x2 = (shaWidth - box_x1 + pixelsPerBits - 1) & pixelsMask;
179             sha_x1 = (shaWidth - scr_x1 - 1);
180             break;
181         case BOTTOM_TO_TOP:
182             scr_x1 = (shaHeight - box_y2) & pixelsMask;
183             scr_x2 = (shaHeight - box_y1 + pixelsPerBits - 1) & pixelsMask;
184             
185             sha_y1 = (shaHeight - scr_x1 - 1);
186             break;
187         }
188         switch (y_dir) {
189         case TOP_TO_BOTTOM:
190             scr_y1 = box_y1;
191             scr_y2 = box_y2;
193             sha_y1 = scr_y1;
194             break;
195         case RIGHT_TO_LEFT:
196             scr_y1 = (shaWidth - box_x2);
197             scr_y2 = (shaWidth - box_x1);
199             sha_x1 = box_x2 - 1;
200             break;
201         case BOTTOM_TO_TOP:
202             scr_y1 = shaHeight - box_y2;
203             scr_y2 = shaHeight - box_y1;
204             
205             sha_y1 = box_y2 - 1;
206             break;
207         case LEFT_TO_RIGHT:
208             scr_y1 = box_x1;
209             scr_y2 = box_x2;
211             sha_x1 = box_x1;
212             break;
213         }
214         scr_w = ((scr_x2 - scr_x1) * shaBpp) >> FB_SHIFT;
215         scr_h = scr_y2 - scr_y1;
216         scr_y = scr_y1;
218         /* shift amount for first pixel on screen */ 
219         shaFirstShift = FB_UNIT - ((sha_x1 * shaBpp) & FB_MASK) - shaBpp;
220         
221         /* pointer to shadow data first placed on screen */
222         shaLine = (shaBits + 
223                    sha_y1 * shaStride + 
224                    ((sha_x1 * shaBpp) >> FB_SHIFT));
226         /*
227          * Copy the bits, always write across the physical frame buffer
228          * to take advantage of write combining.
229          */
230         while (scr_h--)
231         {
232             int     p;
233             FbBits  bits;
234             FbBits  *win;
235             int     i;
236             CARD32  winSize;
237             
238             sha = shaLine;
239             shaShift = shaFirstShift;
240             w = scr_w;
241             scr_x = scr_x1 * shaBpp >> FB_SHIFT;
243             while (w)
244             {
245                 /*
246                  * Map some of this line
247                  */
248                 win = (FbBits *) (*pBuf->window) (pScreen,
249                                                   scr_y,
250                                                   scr_x << 2,
251                                                   SHADOW_WINDOW_WRITE,
252                                                   &winSize,
253                                                   pBuf->closure);
254                 i = (winSize >> 2);
255                 if (i > w)
256                     i = w;
257                 w -= i;
258                 scr_x += i;
259                 /*
260                  * Copy the portion of the line mapped
261                  */
262                 while (i--)
263                 {
264                     bits = 0;
265                     p = pixelsPerBits;
266                     /*
267                      * Build one word of output from multiple inputs
268                      * 
269                      * Note that for 90/270 rotations, this will walk
270                      * down the shadow hitting each scanline once.
271                      * This is probably not very efficient.
272                      */
273                     while (p--)
274                     {
275                         bits = FbScrLeft(bits, shaBpp);
276                         bits |= FbScrRight (*sha, shaShift) & shaMask;
278                         shaShift -= shaStepOverX;
279                         if (shaShift >= FB_UNIT)
280                         {
281                             shaShift -= FB_UNIT;
282                             sha--;
283                         }
284                         else if (shaShift < 0)
285                         {
286                             shaShift += FB_UNIT;
287                             sha++;
288                         }
289                         sha += shaStepOverY;
290                     }
291                     *win++ = bits;
292                 }
293             }
294             scr_y++;
295             shaFirstShift -= shaStepDownX;
296             if (shaFirstShift >= FB_UNIT)
297             {
298                 shaFirstShift -= FB_UNIT;
299                 shaLine--;
300             }
301             else if (shaFirstShift < 0)
302             {
303                 shaFirstShift += FB_UNIT;
304                 shaLine++;
305             }
306             shaLine += shaStepDownY;
307         }
308     }
311 shadowUpdateProc shadowUpdateRotatePackedWeak(void) {
312     return shadowUpdateRotatePacked;