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