s3_shadow.c revision 4178061c
14178061cSmrg/*
24178061cSmrgCopyright (C) 1994-2000 The XFree86 Project, Inc.  All Rights Reserved.
34178061cSmrg
44178061cSmrgPermission is hereby granted, free of charge, to any person obtaining a copy of
54178061cSmrgthis software and associated documentation files (the "Software"), to deal in
64178061cSmrgthe Software without restriction, including without limitation the rights to
74178061cSmrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
84178061cSmrgof the Software, and to permit persons to whom the Software is furnished to do
94178061cSmrgso, subject to the following conditions:
104178061cSmrg
114178061cSmrgThe above copyright notice and this permission notice shall be included in all
124178061cSmrgcopies or substantial portions of the Software.
134178061cSmrg
144178061cSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154178061cSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
164178061cSmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
174178061cSmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
184178061cSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
194178061cSmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
204178061cSmrg
214178061cSmrgExcept as contained in this notice, the name of the XFree86 Project shall not
224178061cSmrgbe used in advertising or otherwise to promote the sale, use or other dealings
234178061cSmrgin this Software without prior written authorization from the XFree86 Project.
244178061cSmrg*/
254178061cSmrg
264178061cSmrg/*
274178061cSmrg   Copyright (c) 1999,2000  The XFree86 Project Inc.
284178061cSmrg   based on code written by Mark Vojkovich <markv@valinux.com>
294178061cSmrg*/
304178061cSmrg
314178061cSmrg#ifdef HAVE_CONFIG_H
324178061cSmrg#include "config.h"
334178061cSmrg#endif
344178061cSmrg
354178061cSmrg#include "xf86.h"
364178061cSmrg#include "xf86_OSproc.h"
374178061cSmrg#include "xf86Resources.h"
384178061cSmrg#include "xf86PciInfo.h"
394178061cSmrg#include "xf86Pci.h"
404178061cSmrg#include "shadowfb.h"
414178061cSmrg#include "servermd.h"
424178061cSmrg#include "s3.h"
434178061cSmrg
444178061cSmrg
454178061cSmrgvoid
464178061cSmrgS3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
474178061cSmrg{
484178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
494178061cSmrg    int width, height, Bpp, FBPitch;
504178061cSmrg    unsigned char *src, *dst;
514178061cSmrg
524178061cSmrg    Bpp = pScrn->bitsPerPixel >> 3;
534178061cSmrg    FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
544178061cSmrg
554178061cSmrg    while(num--) {
564178061cSmrg	width = (pbox->x2 - pbox->x1) * Bpp;
574178061cSmrg	height = pbox->y2 - pbox->y1;
584178061cSmrg	src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) +
594178061cSmrg		(pbox->x1 * Bpp);
604178061cSmrg	dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
614178061cSmrg
624178061cSmrg	while(height--) {
634178061cSmrg	    memcpy(dst, src, width);
644178061cSmrg	    dst += FBPitch;
654178061cSmrg	    src += pS3->ShadowPitch;
664178061cSmrg	}
674178061cSmrg
684178061cSmrg	pbox++;
694178061cSmrg    }
704178061cSmrg}
714178061cSmrg
724178061cSmrgvoid
734178061cSmrgS3PointerMoved(int index, int x, int y)
744178061cSmrg{
754178061cSmrg    ScrnInfoPtr pScrn = xf86Screens[index];
764178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
774178061cSmrg    int newX, newY;
784178061cSmrg
794178061cSmrg    if(pS3->rotate == 1) {
804178061cSmrg	newX = pScrn->pScreen->height - y - 1;
814178061cSmrg	newY = x;
824178061cSmrg    } else {
834178061cSmrg	newX = y;
844178061cSmrg	newY = pScrn->pScreen->width - x - 1;
854178061cSmrg    }
864178061cSmrg
874178061cSmrg    (*pS3->PointerMoved)(index, newX, newY);
884178061cSmrg}
894178061cSmrg
904178061cSmrgvoid
914178061cSmrgS3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
924178061cSmrg{
934178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
944178061cSmrg    int count, width, height, y1, y2, dstPitch, srcPitch;
954178061cSmrg    CARD8 *dstPtr, *srcPtr, *src;
964178061cSmrg    CARD32 *dst;
974178061cSmrg
984178061cSmrg    dstPitch = pScrn->displayWidth;
994178061cSmrg    srcPitch = -pS3->rotate * pS3->ShadowPitch;
1004178061cSmrg
1014178061cSmrg    while(num--) {
1024178061cSmrg	width = pbox->x2 - pbox->x1;
1034178061cSmrg	y1 = pbox->y1 & ~3;
1044178061cSmrg	y2 = (pbox->y2 + 3) & ~3;
1054178061cSmrg	height = (y2 - y1) >> 2;  /* in dwords */
1064178061cSmrg
1074178061cSmrg	if(pS3->rotate == 1) {
1084178061cSmrg	    dstPtr = pS3->FBBase +
1094178061cSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
1104178061cSmrg	    srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
1114178061cSmrg	} else {
1124178061cSmrg	    dstPtr = pS3->FBBase +
1134178061cSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
1144178061cSmrg	    srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
1154178061cSmrg	}
1164178061cSmrg
1174178061cSmrg	while(width--) {
1184178061cSmrg	    src = srcPtr;
1194178061cSmrg	    dst = (CARD32*)dstPtr;
1204178061cSmrg	    count = height;
1214178061cSmrg	    while(count--) {
1224178061cSmrg		*(dst++) = src[0] | (src[srcPitch] << 8) |
1234178061cSmrg					(src[srcPitch * 2] << 16) |
1244178061cSmrg					(src[srcPitch * 3] << 24);
1254178061cSmrg		src += srcPitch * 4;
1264178061cSmrg	    }
1274178061cSmrg	    srcPtr += pS3->rotate;
1284178061cSmrg	    dstPtr += dstPitch;
1294178061cSmrg	}
1304178061cSmrg
1314178061cSmrg	pbox++;
1324178061cSmrg    }
1334178061cSmrg}
1344178061cSmrg
1354178061cSmrg
1364178061cSmrgvoid
1374178061cSmrgS3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
1384178061cSmrg{
1394178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
1404178061cSmrg    int count, width, height, y1, y2, dstPitch, srcPitch;
1414178061cSmrg    CARD16 *dstPtr, *srcPtr, *src;
1424178061cSmrg    CARD32 *dst;
1434178061cSmrg
1444178061cSmrg    dstPitch = pScrn->displayWidth;
1454178061cSmrg    srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1;
1464178061cSmrg
1474178061cSmrg    while(num--) {
1484178061cSmrg	width = pbox->x2 - pbox->x1;
1494178061cSmrg	y1 = pbox->y1 & ~1;
1504178061cSmrg	y2 = (pbox->y2 + 1) & ~1;
1514178061cSmrg	height = (y2 - y1) >> 1;  /* in dwords */
1524178061cSmrg
1534178061cSmrg	if(pS3->rotate == 1) {
1544178061cSmrg	    dstPtr = (CARD16*)pS3->FBBase +
1554178061cSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - y2;
1564178061cSmrg	    srcPtr = (CARD16*)pS3->ShadowPtr +
1574178061cSmrg			((1 - y2) * srcPitch) + pbox->x1;
1584178061cSmrg	} else {
1594178061cSmrg	    dstPtr = (CARD16*)pS3->FBBase +
1604178061cSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
1614178061cSmrg	    srcPtr = (CARD16*)pS3->ShadowPtr +
1624178061cSmrg			(y1 * srcPitch) + pbox->x2 - 1;
1634178061cSmrg	}
1644178061cSmrg
1654178061cSmrg	while(width--) {
1664178061cSmrg	    src = srcPtr;
1674178061cSmrg	    dst = (CARD32*)dstPtr;
1684178061cSmrg	    count = height;
1694178061cSmrg	    while(count--) {
1704178061cSmrg		*(dst++) = src[0] | (src[srcPitch] << 16);
1714178061cSmrg		src += srcPitch * 2;
1724178061cSmrg	    }
1734178061cSmrg	    srcPtr += pS3->rotate;
1744178061cSmrg	    dstPtr += dstPitch;
1754178061cSmrg	}
1764178061cSmrg
1774178061cSmrg	pbox++;
1784178061cSmrg    }
1794178061cSmrg}
1804178061cSmrg
1814178061cSmrg
1824178061cSmrg/* this one could be faster */
1834178061cSmrgvoid
1844178061cSmrgS3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
1854178061cSmrg{
1864178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
1874178061cSmrg    int count, width, height, y1, y2, dstPitch, srcPitch;
1884178061cSmrg    CARD8 *dstPtr, *srcPtr, *src;
1894178061cSmrg    CARD32 *dst;
1904178061cSmrg
1914178061cSmrg    dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
1924178061cSmrg    srcPitch = -pS3->rotate * pS3->ShadowPitch;
1934178061cSmrg
1944178061cSmrg    while(num--) {
1954178061cSmrg        width = pbox->x2 - pbox->x1;
1964178061cSmrg        y1 = pbox->y1 & ~3;
1974178061cSmrg        y2 = (pbox->y2 + 3) & ~3;
1984178061cSmrg        height = (y2 - y1) >> 2;  /* blocks of 3 dwords */
1994178061cSmrg
2004178061cSmrg	if(pS3->rotate == 1) {
2014178061cSmrg	    dstPtr = pS3->FBBase +
2024178061cSmrg			(pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
2034178061cSmrg	    srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
2044178061cSmrg	} else {
2054178061cSmrg	    dstPtr = pS3->FBBase +
2064178061cSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
2074178061cSmrg	    srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
2084178061cSmrg	}
2094178061cSmrg
2104178061cSmrg	while(width--) {
2114178061cSmrg	    src = srcPtr;
2124178061cSmrg	    dst = (CARD32*)dstPtr;
2134178061cSmrg	    count = height;
2144178061cSmrg	    while(count--) {
2154178061cSmrg		dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
2164178061cSmrg				(src[srcPitch] << 24);
2174178061cSmrg		dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
2184178061cSmrg				(src[srcPitch * 2] << 16) |
2194178061cSmrg				(src[(srcPitch * 2) + 1] << 24);
2204178061cSmrg		dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
2214178061cSmrg				(src[(srcPitch * 3) + 1] << 16) |
2224178061cSmrg				(src[(srcPitch * 3) + 2] << 24);
2234178061cSmrg		dst += 3;
2244178061cSmrg		src += srcPitch * 4;
2254178061cSmrg	    }
2264178061cSmrg	    srcPtr += pS3->rotate * 3;
2274178061cSmrg	    dstPtr += dstPitch;
2284178061cSmrg	}
2294178061cSmrg
2304178061cSmrg	pbox++;
2314178061cSmrg    }
2324178061cSmrg}
2334178061cSmrg
2344178061cSmrgvoid
2354178061cSmrgS3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
2364178061cSmrg{
2374178061cSmrg    S3Ptr pS3 = S3PTR(pScrn);
2384178061cSmrg    int count, width, height, dstPitch, srcPitch;
2394178061cSmrg    CARD32 *dstPtr, *srcPtr, *src, *dst;
2404178061cSmrg
2414178061cSmrg    dstPitch = pScrn->displayWidth;
2424178061cSmrg    srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2;
2434178061cSmrg
2444178061cSmrg    while(num--) {
2454178061cSmrg	width = pbox->x2 - pbox->x1;
2464178061cSmrg	height = pbox->y2 - pbox->y1;
2474178061cSmrg
2484178061cSmrg	if(pS3->rotate == 1) {
2494178061cSmrg	    dstPtr = (CARD32*)pS3->FBBase +
2504178061cSmrg			(pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
2514178061cSmrg	    srcPtr = (CARD32*)pS3->ShadowPtr +
2524178061cSmrg			((1 - pbox->y2) * srcPitch) + pbox->x1;
2534178061cSmrg	} else {
2544178061cSmrg	    dstPtr = (CARD32*)pS3->FBBase +
2554178061cSmrg			((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
2564178061cSmrg	    srcPtr = (CARD32*)pS3->ShadowPtr +
2574178061cSmrg			(pbox->y1 * srcPitch) + pbox->x2 - 1;
2584178061cSmrg	}
2594178061cSmrg
2604178061cSmrg	while(width--) {
2614178061cSmrg	    src = srcPtr;
2624178061cSmrg	    dst = dstPtr;
2634178061cSmrg	    count = height;
2644178061cSmrg	    while(count--) {
2654178061cSmrg		*(dst++) = *src;
2664178061cSmrg		src += srcPitch;
2674178061cSmrg	    }
2684178061cSmrg	    srcPtr += pS3->rotate;
2694178061cSmrg	    dstPtr += dstPitch;
2704178061cSmrg	}
2714178061cSmrg
2724178061cSmrg	pbox++;
2734178061cSmrg    }
2744178061cSmrg}
275