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