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