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