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