neo_shadow.c revision 692f60a7
1692f60a7Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.2 2000/11/03 18:46:11 eich Exp $ */
2692f60a7Smrg
3692f60a7Smrg/*
4692f60a7Smrg   Copyright (c) 1999, 2000 The XFree86 Project Inc.
5692f60a7Smrg   based on code written by Mark Vojkovich <markv@valinux.com>
6692f60a7Smrg*/
7692f60a7Smrg
8692f60a7Smrg#ifdef HAVE_CONFIG_H
9692f60a7Smrg#include "config.h"
10692f60a7Smrg#endif
11692f60a7Smrg
12692f60a7Smrg#include "xf86.h"
13692f60a7Smrg#include "xf86_OSproc.h"
14692f60a7Smrg#include "xf86Resources.h"
15692f60a7Smrg#include "xf86PciInfo.h"
16692f60a7Smrg#include "xf86Pci.h"
17692f60a7Smrg#include "shadowfb.h"
18692f60a7Smrg#include "servermd.h"
19692f60a7Smrg#include "neo.h"
20692f60a7Smrg
21692f60a7Smrgvoid
22692f60a7SmrgneoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
23692f60a7Smrg{
24692f60a7Smrg    RegionPtr damage = &pBuf->damage;
25692f60a7Smrg    ScrnInfoPtr pScrn;
26692f60a7Smrg    pScrn = xf86Screens[pScreen->myNum];
27692f60a7Smrg
28692f60a7Smrg    (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage),
29692f60a7Smrg				      REGION_RECTS(damage));
30692f60a7Smrg}
31692f60a7Smrg
32692f60a7Smrgvoid
33692f60a7SmrgneoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
34692f60a7Smrg{
35692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
36692f60a7Smrg    int width, height, Bpp, FBPitch;
37692f60a7Smrg    unsigned char *src, *dst;
38692f60a7Smrg
39692f60a7Smrg    Bpp = pScrn->bitsPerPixel >> 3;
40692f60a7Smrg    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
41692f60a7Smrg
42692f60a7Smrg    while(num--) {
43692f60a7Smrg	width = (pbox->x2 - pbox->x1) * Bpp;
44692f60a7Smrg	height = pbox->y2 - pbox->y1;
45692f60a7Smrg	src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) +
46692f60a7Smrg						(pbox->x1 * Bpp);
47692f60a7Smrg	dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
48692f60a7Smrg
49692f60a7Smrg	while(height--) {
50692f60a7Smrg	    memcpy(dst, src, width);
51692f60a7Smrg	    dst += FBPitch;
52692f60a7Smrg	    src += nPtr->ShadowPitch;
53692f60a7Smrg	}
54692f60a7Smrg
55692f60a7Smrg	pbox++;
56692f60a7Smrg    }
57692f60a7Smrg}
58692f60a7Smrg
59692f60a7Smrgvoid
60692f60a7SmrgneoPointerMoved(int index, int x, int y)
61692f60a7Smrg{
62692f60a7Smrg    ScrnInfoPtr pScrn = xf86Screens[index];
63692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
64692f60a7Smrg    int newX, newY;
65692f60a7Smrg
66692f60a7Smrg    if(nPtr->rotate == 1) {
67692f60a7Smrg	newX = pScrn->pScreen->height - y - 1;
68692f60a7Smrg	newY = x;
69692f60a7Smrg    } else {
70692f60a7Smrg	newX = y;
71692f60a7Smrg	newY = pScrn->pScreen->width - x - 1;
72692f60a7Smrg    }
73692f60a7Smrg
74692f60a7Smrg    (*nPtr->PointerMoved)(index, newX, newY);
75692f60a7Smrg}
76692f60a7Smrg
77692f60a7Smrgvoid
78692f60a7SmrgneoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
79692f60a7Smrg{
80692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
81692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
82692f60a7Smrg    CARD8 *dstPtr, *srcPtr, *src;
83692f60a7Smrg    CARD32 *dst;
84692f60a7Smrg
85692f60a7Smrg    dstPitch = pScrn->displayWidth;
86692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
87692f60a7Smrg
88692f60a7Smrg    while(num--) {
89692f60a7Smrg	width = pbox->x2 - pbox->x1;
90692f60a7Smrg	y1 = pbox->y1 & ~3;
91692f60a7Smrg	y2 = (pbox->y2 + 3) & ~3;
92692f60a7Smrg	height = (y2 - y1) >> 2;  /* in dwords */
93692f60a7Smrg
94692f60a7Smrg	if(nPtr->rotate == 1) {
95692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
96692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
97692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
98692f60a7Smrg	} else {
99692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
100692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
101692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
102692f60a7Smrg	}
103692f60a7Smrg
104692f60a7Smrg	while(width--) {
105692f60a7Smrg	    src = srcPtr;
106692f60a7Smrg	    dst = (CARD32*)dstPtr;
107692f60a7Smrg	    count = height;
108692f60a7Smrg	    while(count--) {
109692f60a7Smrg		*(dst++) = src[0] | (src[srcPitch] << 8) |
110692f60a7Smrg					(src[srcPitch * 2] << 16) |
111692f60a7Smrg					(src[srcPitch * 3] << 24);
112692f60a7Smrg		src += srcPitch * 4;
113692f60a7Smrg	    }
114692f60a7Smrg	    srcPtr += nPtr->rotate;
115692f60a7Smrg	    dstPtr += dstPitch;
116692f60a7Smrg	}
117692f60a7Smrg
118692f60a7Smrg	pbox++;
119692f60a7Smrg    }
120692f60a7Smrg}
121692f60a7Smrg
122692f60a7Smrg
123692f60a7Smrgvoid
124692f60a7SmrgneoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
125692f60a7Smrg{
126692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
127692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
128692f60a7Smrg    CARD16 *dstPtr, *srcPtr, *src;
129692f60a7Smrg    CARD32 *dst;
130692f60a7Smrg
131692f60a7Smrg    dstPitch = pScrn->displayWidth;
132692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 1;
133692f60a7Smrg
134692f60a7Smrg    while(num--) {
135692f60a7Smrg	width = pbox->x2 - pbox->x1;
136692f60a7Smrg	y1 = pbox->y1 & ~1;
137692f60a7Smrg	y2 = (pbox->y2 + 1) & ~1;
138692f60a7Smrg	height = (y2 - y1) >> 1;  /* in dwords */
139692f60a7Smrg
140692f60a7Smrg	if(nPtr->rotate == 1) {
141692f60a7Smrg	    dstPtr = (CARD16*)nPtr->NeoFbBase +
142692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
143692f60a7Smrg	    srcPtr = (CARD16*)nPtr->ShadowPtr +
144692f60a7Smrg			((1 - y2) * srcPitch) + pbox->x1;
145692f60a7Smrg	} else {
146692f60a7Smrg	    dstPtr = (CARD16*)nPtr->NeoFbBase +
147692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
148692f60a7Smrg	    srcPtr = (CARD16*)nPtr->ShadowPtr +
149692f60a7Smrg			(y1 * srcPitch) + pbox->x2 - 1;
150692f60a7Smrg	}
151692f60a7Smrg
152692f60a7Smrg	while(width--) {
153692f60a7Smrg	    src = srcPtr;
154692f60a7Smrg	    dst = (CARD32*)dstPtr;
155692f60a7Smrg	    count = height;
156692f60a7Smrg	    while(count--) {
157692f60a7Smrg		*(dst++) = src[0] | (src[srcPitch] << 16);
158692f60a7Smrg		src += srcPitch * 2;
159692f60a7Smrg	    }
160692f60a7Smrg	    srcPtr += nPtr->rotate;
161692f60a7Smrg	    dstPtr += dstPitch;
162692f60a7Smrg	}
163692f60a7Smrg
164692f60a7Smrg	pbox++;
165692f60a7Smrg    }
166692f60a7Smrg}
167692f60a7Smrg
168692f60a7Smrg
169692f60a7Smrg/* this one could be faster */
170692f60a7Smrgvoid
171692f60a7SmrgneoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
172692f60a7Smrg{
173692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
174692f60a7Smrg    int count, width, height, y1, y2, dstPitch, srcPitch;
175692f60a7Smrg    CARD8 *dstPtr, *srcPtr, *src;
176692f60a7Smrg    CARD32 *dst;
177692f60a7Smrg
178692f60a7Smrg    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
179692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch;
180692f60a7Smrg
181692f60a7Smrg    while(num--) {
182692f60a7Smrg        width = pbox->x2 - pbox->x1;
183692f60a7Smrg        y1 = pbox->y1 & ~3;
184692f60a7Smrg        y2 = (pbox->y2 + 3) & ~3;
185692f60a7Smrg        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
186692f60a7Smrg
187692f60a7Smrg	if(nPtr->rotate == 1) {
188692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
189692f60a7Smrg			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
190692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
191692f60a7Smrg	} else {
192692f60a7Smrg	    dstPtr = nPtr->NeoFbBase +
193692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
194692f60a7Smrg	    srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
195692f60a7Smrg	}
196692f60a7Smrg
197692f60a7Smrg	while(width--) {
198692f60a7Smrg	    src = srcPtr;
199692f60a7Smrg	    dst = (CARD32*)dstPtr;
200692f60a7Smrg	    count = height;
201692f60a7Smrg	    while(count--) {
202692f60a7Smrg		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
203692f60a7Smrg				(src[srcPitch] << 24);
204692f60a7Smrg		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
205692f60a7Smrg				(src[srcPitch * 2] << 16) |
206692f60a7Smrg				(src[(srcPitch * 2) + 1] << 24);
207692f60a7Smrg		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
208692f60a7Smrg				(src[(srcPitch * 3) + 1] << 16) |
209692f60a7Smrg				(src[(srcPitch * 3) + 2] << 24);
210692f60a7Smrg		dst += 3;
211692f60a7Smrg		src += srcPitch * 4;
212692f60a7Smrg	    }
213692f60a7Smrg	    srcPtr += nPtr->rotate * 3;
214692f60a7Smrg	    dstPtr += dstPitch;
215692f60a7Smrg	}
216692f60a7Smrg
217692f60a7Smrg	pbox++;
218692f60a7Smrg    }
219692f60a7Smrg}
220692f60a7Smrg
221692f60a7Smrgvoid
222692f60a7SmrgneoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
223692f60a7Smrg{
224692f60a7Smrg    NEOPtr nPtr = NEOPTR(pScrn);
225692f60a7Smrg    int count, width, height, dstPitch, srcPitch;
226692f60a7Smrg    CARD32 *dstPtr, *srcPtr, *src, *dst;
227692f60a7Smrg
228692f60a7Smrg    dstPitch = pScrn->displayWidth;
229692f60a7Smrg    srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 2;
230692f60a7Smrg
231692f60a7Smrg    while(num--) {
232692f60a7Smrg	width = pbox->x2 - pbox->x1;
233692f60a7Smrg	height = pbox->y2 - pbox->y1;
234692f60a7Smrg
235692f60a7Smrg	if(nPtr->rotate == 1) {
236692f60a7Smrg	    dstPtr = (CARD32*)nPtr->NeoFbBase +
237692f60a7Smrg			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
238692f60a7Smrg	    srcPtr = (CARD32*)nPtr->ShadowPtr +
239692f60a7Smrg			((1 - pbox->y2) * srcPitch) + pbox->x1;
240692f60a7Smrg	} else {
241692f60a7Smrg	    dstPtr = (CARD32*)nPtr->NeoFbBase +
242692f60a7Smrg			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
243692f60a7Smrg	    srcPtr = (CARD32*)nPtr->ShadowPtr +
244692f60a7Smrg			(pbox->y1 * srcPitch) + pbox->x2 - 1;
245692f60a7Smrg	}
246692f60a7Smrg
247692f60a7Smrg	while(width--) {
248692f60a7Smrg	    src = srcPtr;
249692f60a7Smrg	    dst = dstPtr;
250692f60a7Smrg	    count = height;
251692f60a7Smrg	    while(count--) {
252692f60a7Smrg		*(dst++) = *src;
253692f60a7Smrg		src += srcPitch;
254692f60a7Smrg	    }
255692f60a7Smrg	    srcPtr += nPtr->rotate;
256692f60a7Smrg	    dstPtr += dstPitch;
257692f60a7Smrg	}
258692f60a7Smrg
259692f60a7Smrg	pbox++;
260692f60a7Smrg    }
261692f60a7Smrg}
262692f60a7Smrg
263692f60a7Smrg
264692f60a7Smrg
265