neo_shadow.c revision 692f60a7
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.2 2000/11/03 18:46:11 eich Exp $ */
2
3/*
4   Copyright (c) 1999, 2000 The XFree86 Project Inc.
5   based on code written by Mark Vojkovich <markv@valinux.com>
6*/
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "xf86.h"
13#include "xf86_OSproc.h"
14#include "xf86Resources.h"
15#include "xf86PciInfo.h"
16#include "xf86Pci.h"
17#include "shadowfb.h"
18#include "servermd.h"
19#include "neo.h"
20
21void
22neoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
23{
24    RegionPtr damage = &pBuf->damage;
25    ScrnInfoPtr pScrn;
26    pScrn = xf86Screens[pScreen->myNum];
27
28    (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage),
29				      REGION_RECTS(damage));
30}
31
32void
33neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
34{
35    NEOPtr nPtr = NEOPTR(pScrn);
36    int width, height, Bpp, FBPitch;
37    unsigned char *src, *dst;
38
39    Bpp = pScrn->bitsPerPixel >> 3;
40    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
41
42    while(num--) {
43	width = (pbox->x2 - pbox->x1) * Bpp;
44	height = pbox->y2 - pbox->y1;
45	src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) +
46						(pbox->x1 * Bpp);
47	dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
48
49	while(height--) {
50	    memcpy(dst, src, width);
51	    dst += FBPitch;
52	    src += nPtr->ShadowPitch;
53	}
54
55	pbox++;
56    }
57}
58
59void
60neoPointerMoved(int index, int x, int y)
61{
62    ScrnInfoPtr pScrn = xf86Screens[index];
63    NEOPtr nPtr = NEOPTR(pScrn);
64    int newX, newY;
65
66    if(nPtr->rotate == 1) {
67	newX = pScrn->pScreen->height - y - 1;
68	newY = x;
69    } else {
70	newX = y;
71	newY = pScrn->pScreen->width - x - 1;
72    }
73
74    (*nPtr->PointerMoved)(index, newX, newY);
75}
76
77void
78neoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
79{
80    NEOPtr nPtr = NEOPTR(pScrn);
81    int count, width, height, y1, y2, dstPitch, srcPitch;
82    CARD8 *dstPtr, *srcPtr, *src;
83    CARD32 *dst;
84
85    dstPitch = pScrn->displayWidth;
86    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
87
88    while(num--) {
89	width = pbox->x2 - pbox->x1;
90	y1 = pbox->y1 & ~3;
91	y2 = (pbox->y2 + 3) & ~3;
92	height = (y2 - y1) >> 2;  /* in dwords */
93
94	if(nPtr->rotate == 1) {
95	    dstPtr = nPtr->NeoFbBase +
96			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
97	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
98	} else {
99	    dstPtr = nPtr->NeoFbBase +
100			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
101	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
102	}
103
104	while(width--) {
105	    src = srcPtr;
106	    dst = (CARD32*)dstPtr;
107	    count = height;
108	    while(count--) {
109		*(dst++) = src[0] | (src[srcPitch] << 8) |
110					(src[srcPitch * 2] << 16) |
111					(src[srcPitch * 3] << 24);
112		src += srcPitch * 4;
113	    }
114	    srcPtr += nPtr->rotate;
115	    dstPtr += dstPitch;
116	}
117
118	pbox++;
119    }
120}
121
122
123void
124neoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
125{
126    NEOPtr nPtr = NEOPTR(pScrn);
127    int count, width, height, y1, y2, dstPitch, srcPitch;
128    CARD16 *dstPtr, *srcPtr, *src;
129    CARD32 *dst;
130
131    dstPitch = pScrn->displayWidth;
132    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 1;
133
134    while(num--) {
135	width = pbox->x2 - pbox->x1;
136	y1 = pbox->y1 & ~1;
137	y2 = (pbox->y2 + 1) & ~1;
138	height = (y2 - y1) >> 1;  /* in dwords */
139
140	if(nPtr->rotate == 1) {
141	    dstPtr = (CARD16*)nPtr->NeoFbBase +
142			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
143	    srcPtr = (CARD16*)nPtr->ShadowPtr +
144			((1 - y2) * srcPitch) + pbox->x1;
145	} else {
146	    dstPtr = (CARD16*)nPtr->NeoFbBase +
147			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
148	    srcPtr = (CARD16*)nPtr->ShadowPtr +
149			(y1 * srcPitch) + pbox->x2 - 1;
150	}
151
152	while(width--) {
153	    src = srcPtr;
154	    dst = (CARD32*)dstPtr;
155	    count = height;
156	    while(count--) {
157		*(dst++) = src[0] | (src[srcPitch] << 16);
158		src += srcPitch * 2;
159	    }
160	    srcPtr += nPtr->rotate;
161	    dstPtr += dstPitch;
162	}
163
164	pbox++;
165    }
166}
167
168
169/* this one could be faster */
170void
171neoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
172{
173    NEOPtr nPtr = NEOPTR(pScrn);
174    int count, width, height, y1, y2, dstPitch, srcPitch;
175    CARD8 *dstPtr, *srcPtr, *src;
176    CARD32 *dst;
177
178    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
179    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
180
181    while(num--) {
182        width = pbox->x2 - pbox->x1;
183        y1 = pbox->y1 & ~3;
184        y2 = (pbox->y2 + 3) & ~3;
185        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
186
187	if(nPtr->rotate == 1) {
188	    dstPtr = nPtr->NeoFbBase +
189			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
190	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
191	} else {
192	    dstPtr = nPtr->NeoFbBase +
193			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
194	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
195	}
196
197	while(width--) {
198	    src = srcPtr;
199	    dst = (CARD32*)dstPtr;
200	    count = height;
201	    while(count--) {
202		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
203				(src[srcPitch] << 24);
204		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
205				(src[srcPitch * 2] << 16) |
206				(src[(srcPitch * 2) + 1] << 24);
207		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
208				(src[(srcPitch * 3) + 1] << 16) |
209				(src[(srcPitch * 3) + 2] << 24);
210		dst += 3;
211		src += srcPitch * 4;
212	    }
213	    srcPtr += nPtr->rotate * 3;
214	    dstPtr += dstPitch;
215	}
216
217	pbox++;
218    }
219}
220
221void
222neoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
223{
224    NEOPtr nPtr = NEOPTR(pScrn);
225    int count, width, height, dstPitch, srcPitch;
226    CARD32 *dstPtr, *srcPtr, *src, *dst;
227
228    dstPitch = pScrn->displayWidth;
229    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 2;
230
231    while(num--) {
232	width = pbox->x2 - pbox->x1;
233	height = pbox->y2 - pbox->y1;
234
235	if(nPtr->rotate == 1) {
236	    dstPtr = (CARD32*)nPtr->NeoFbBase +
237			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
238	    srcPtr = (CARD32*)nPtr->ShadowPtr +
239			((1 - pbox->y2) * srcPitch) + pbox->x1;
240	} else {
241	    dstPtr = (CARD32*)nPtr->NeoFbBase +
242			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
243	    srcPtr = (CARD32*)nPtr->ShadowPtr +
244			(pbox->y1 * srcPitch) + pbox->x2 - 1;
245	}
246
247	while(width--) {
248	    src = srcPtr;
249	    dst = dstPtr;
250	    count = height;
251	    while(count--) {
252		*(dst++) = *src;
253		src += srcPitch;
254	    }
255	    srcPtr += nPtr->rotate;
256	    dstPtr += dstPitch;
257	}
258
259	pbox++;
260    }
261}
262
263
264
265