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