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