s3v_shadow.c revision ec713c28
1
2/*
3Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
4
5Permission is hereby granted, free of charge, to any person obtaining a copy of
6this software and associated documentation files (the "Software"), to deal in
7the Software without restriction, including without limitation the rights to
8use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9of the Software, and to permit persons to whom the Software is furnished to do
10so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
17NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of the XFree86 Project shall not
23be used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from the XFree86 Project.
25*/
26
27/*
28Copyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
29
30Permission is hereby granted, free of charge, to any person obtaining a copy of
31this software and associated documentation files (the "Software"), to deal in
32the Software without restriction, including without limitation the rights to
33use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
34of the Software, and to permit persons to whom the Software is furnished to do
35so, subject to the following conditions:
36
37The above copyright notice and this permission notice shall be included in all
38copies or substantial portions of the Software.
39
40THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
42NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
43XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
44AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
45WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
47Except as contained in this notice, the name of the XFree86 Project shall not
48be used in advertising or otherwise to promote the sale, use or other dealings
49in this Software without prior written authorization from the XFree86 Project.
50*/
51
52/*
53   Copyright (c) 1999,2000  The XFree86 Project Inc.
54   based on code written by Mark Vojkovich <markv@valinux.com>
55*/
56
57#ifdef HAVE_CONFIG_H
58#include "config.h"
59#endif
60
61#include "xf86.h"
62#include "xf86_OSproc.h"
63#include "xf86PciInfo.h"
64#include "xf86Pci.h"
65#include "shadowfb.h"
66#include "servermd.h"
67#include "s3v.h"
68
69
70void
71s3vRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
72{
73    S3VPtr ps3v = S3VPTR(pScrn);
74    int width, height, Bpp, FBPitch;
75    unsigned char *src, *dst;
76
77    Bpp = pScrn->bitsPerPixel >> 3;
78    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
79
80    while(num--) {
81	width = (pbox->x2 - pbox->x1) * Bpp;
82	height = pbox->y2 - pbox->y1;
83	src = ps3v->ShadowPtr + (pbox->y1 * ps3v->ShadowPitch) +
84						(pbox->x1 * Bpp);
85	dst = ps3v->FBStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
86
87	while(height--) {
88	    memcpy(dst, src, width);
89	    dst += FBPitch;
90	    src += ps3v->ShadowPitch;
91	}
92
93	pbox++;
94    }
95}
96
97void
98s3vPointerMoved(int index, int x, int y)
99{
100    ScrnInfoPtr pScrn = xf86Screens[index];
101    S3VPtr ps3v = S3VPTR(pScrn);
102    int newX, newY;
103
104    if(ps3v->rotate == 1) {
105	newX = pScrn->pScreen->height - y - 1;
106	newY = x;
107    } else {
108	newX = y;
109	newY = pScrn->pScreen->width - x - 1;
110    }
111
112    (*ps3v->PointerMoved)(index, newX, newY);
113}
114
115void
116s3vRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
117{
118    S3VPtr ps3v = S3VPTR(pScrn);
119    int count, width, height, y1, y2, dstPitch, srcPitch;
120    CARD8 *dstPtr, *srcPtr, *src;
121    CARD32 *dst;
122
123    dstPitch = pScrn->displayWidth;
124    srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
125
126    while(num--) {
127	width = pbox->x2 - pbox->x1;
128	y1 = pbox->y1 & ~3;
129	y2 = (pbox->y2 + 3) & ~3;
130	height = (y2 - y1) >> 2;  /* in dwords */
131
132	if(ps3v->rotate == 1) {
133	    dstPtr = ps3v->FBStart +
134			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
135	    srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
136	} else {
137	    dstPtr = ps3v->FBStart +
138			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
139	    srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
140	}
141
142	while(width--) {
143	    src = srcPtr;
144	    dst = (CARD32*)dstPtr;
145	    count = height;
146	    while(count--) {
147		*(dst++) = src[0] | (src[srcPitch] << 8) |
148					(src[srcPitch * 2] << 16) |
149					(src[srcPitch * 3] << 24);
150		src += srcPitch * 4;
151	    }
152	    srcPtr += ps3v->rotate;
153	    dstPtr += dstPitch;
154	}
155
156	pbox++;
157    }
158}
159
160
161void
162s3vRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
163{
164    S3VPtr ps3v = S3VPTR(pScrn);
165    int count, width, height, y1, y2, dstPitch, srcPitch;
166    CARD16 *dstPtr, *srcPtr, *src;
167    CARD32 *dst;
168
169    dstPitch = pScrn->displayWidth;
170    srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 1;
171
172    while(num--) {
173	width = pbox->x2 - pbox->x1;
174	y1 = pbox->y1 & ~1;
175	y2 = (pbox->y2 + 1) & ~1;
176	height = (y2 - y1) >> 1;  /* in dwords */
177
178	if(ps3v->rotate == 1) {
179	    dstPtr = (CARD16*)ps3v->FBStart +
180			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
181	    srcPtr = (CARD16*)ps3v->ShadowPtr +
182			((1 - y2) * srcPitch) + pbox->x1;
183	} else {
184	    dstPtr = (CARD16*)ps3v->FBStart +
185			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
186	    srcPtr = (CARD16*)ps3v->ShadowPtr +
187			(y1 * srcPitch) + pbox->x2 - 1;
188	}
189
190	while(width--) {
191	    src = srcPtr;
192	    dst = (CARD32*)dstPtr;
193	    count = height;
194	    while(count--) {
195		*(dst++) = src[0] | (src[srcPitch] << 16);
196		src += srcPitch * 2;
197	    }
198	    srcPtr += ps3v->rotate;
199	    dstPtr += dstPitch;
200	}
201
202	pbox++;
203    }
204}
205
206
207/* this one could be faster */
208void
209s3vRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
210{
211    S3VPtr ps3v = S3VPTR(pScrn);
212    int count, width, height, y1, y2, dstPitch, srcPitch;
213    CARD8 *dstPtr, *srcPtr, *src;
214    CARD32 *dst;
215
216    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
217    srcPitch = -ps3v->rotate * ps3v->ShadowPitch;
218
219    while(num--) {
220        width = pbox->x2 - pbox->x1;
221        y1 = pbox->y1 & ~3;
222        y2 = (pbox->y2 + 3) & ~3;
223        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
224
225	if(ps3v->rotate == 1) {
226	    dstPtr = ps3v->FBStart +
227			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
228	    srcPtr = ps3v->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
229	} else {
230	    dstPtr = ps3v->FBStart +
231			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
232	    srcPtr = ps3v->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
233	}
234
235	while(width--) {
236	    src = srcPtr;
237	    dst = (CARD32*)dstPtr;
238	    count = height;
239	    while(count--) {
240		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
241				(src[srcPitch] << 24);
242		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
243				(src[srcPitch * 2] << 16) |
244				(src[(srcPitch * 2) + 1] << 24);
245		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
246				(src[(srcPitch * 3) + 1] << 16) |
247				(src[(srcPitch * 3) + 2] << 24);
248		dst += 3;
249		src += srcPitch * 4;
250	    }
251	    srcPtr += ps3v->rotate * 3;
252	    dstPtr += dstPitch;
253	}
254
255	pbox++;
256    }
257}
258
259void
260s3vRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
261{
262    S3VPtr ps3v = S3VPTR(pScrn);
263    int count, width, height, dstPitch, srcPitch;
264    CARD32 *dstPtr, *srcPtr, *src, *dst;
265
266    dstPitch = pScrn->displayWidth;
267    srcPitch = -ps3v->rotate * ps3v->ShadowPitch >> 2;
268
269    while(num--) {
270	width = pbox->x2 - pbox->x1;
271	height = pbox->y2 - pbox->y1;
272
273	if(ps3v->rotate == 1) {
274	    dstPtr = (CARD32*)ps3v->FBStart +
275			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
276	    srcPtr = (CARD32*)ps3v->ShadowPtr +
277			((1 - pbox->y2) * srcPitch) + pbox->x1;
278	} else {
279	    dstPtr = (CARD32*)ps3v->FBStart +
280			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
281	    srcPtr = (CARD32*)ps3v->ShadowPtr +
282			(pbox->y1 * srcPitch) + pbox->x2 - 1;
283	}
284
285	while(width--) {
286	    src = srcPtr;
287	    dst = dstPtr;
288	    count = height;
289	    while(count--) {
290		*(dst++) = *src;
291		src += srcPitch;
292	    }
293	    srcPtr += ps3v->rotate;
294	    dstPtr += dstPitch;
295	}
296
297	pbox++;
298    }
299}
300
301
302
303