neo_shadow.c revision 692f60a7
1692f60a7Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_shadow.c,v 1.2 2000/11/03 18:46:11 eich Exp $ */ 2692f60a7Smrg 3692f60a7Smrg/* 4692f60a7Smrg Copyright (c) 1999, 2000 The XFree86 Project Inc. 5692f60a7Smrg based on code written by Mark Vojkovich <markv@valinux.com> 6692f60a7Smrg*/ 7692f60a7Smrg 8692f60a7Smrg#ifdef HAVE_CONFIG_H 9692f60a7Smrg#include "config.h" 10692f60a7Smrg#endif 11692f60a7Smrg 12692f60a7Smrg#include "xf86.h" 13692f60a7Smrg#include "xf86_OSproc.h" 14692f60a7Smrg#include "xf86Resources.h" 15692f60a7Smrg#include "xf86PciInfo.h" 16692f60a7Smrg#include "xf86Pci.h" 17692f60a7Smrg#include "shadowfb.h" 18692f60a7Smrg#include "servermd.h" 19692f60a7Smrg#include "neo.h" 20692f60a7Smrg 21692f60a7Smrgvoid 22692f60a7SmrgneoShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) 23692f60a7Smrg{ 24692f60a7Smrg RegionPtr damage = &pBuf->damage; 25692f60a7Smrg ScrnInfoPtr pScrn; 26692f60a7Smrg pScrn = xf86Screens[pScreen->myNum]; 27692f60a7Smrg 28692f60a7Smrg (NEOPTR(pScrn))->refreshArea (pScrn, REGION_NUM_RECTS(damage), 29692f60a7Smrg REGION_RECTS(damage)); 30692f60a7Smrg} 31692f60a7Smrg 32692f60a7Smrgvoid 33692f60a7SmrgneoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 34692f60a7Smrg{ 35692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 36692f60a7Smrg int width, height, Bpp, FBPitch; 37692f60a7Smrg unsigned char *src, *dst; 38692f60a7Smrg 39692f60a7Smrg Bpp = pScrn->bitsPerPixel >> 3; 40692f60a7Smrg FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 41692f60a7Smrg 42692f60a7Smrg while(num--) { 43692f60a7Smrg width = (pbox->x2 - pbox->x1) * Bpp; 44692f60a7Smrg height = pbox->y2 - pbox->y1; 45692f60a7Smrg src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) + 46692f60a7Smrg (pbox->x1 * Bpp); 47692f60a7Smrg dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 48692f60a7Smrg 49692f60a7Smrg while(height--) { 50692f60a7Smrg memcpy(dst, src, width); 51692f60a7Smrg dst += FBPitch; 52692f60a7Smrg src += nPtr->ShadowPitch; 53692f60a7Smrg } 54692f60a7Smrg 55692f60a7Smrg pbox++; 56692f60a7Smrg } 57692f60a7Smrg} 58692f60a7Smrg 59692f60a7Smrgvoid 60692f60a7SmrgneoPointerMoved(int index, int x, int y) 61692f60a7Smrg{ 62692f60a7Smrg ScrnInfoPtr pScrn = xf86Screens[index]; 63692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 64692f60a7Smrg int newX, newY; 65692f60a7Smrg 66692f60a7Smrg if(nPtr->rotate == 1) { 67692f60a7Smrg newX = pScrn->pScreen->height - y - 1; 68692f60a7Smrg newY = x; 69692f60a7Smrg } else { 70692f60a7Smrg newX = y; 71692f60a7Smrg newY = pScrn->pScreen->width - x - 1; 72692f60a7Smrg } 73692f60a7Smrg 74692f60a7Smrg (*nPtr->PointerMoved)(index, newX, newY); 75692f60a7Smrg} 76692f60a7Smrg 77692f60a7Smrgvoid 78692f60a7SmrgneoRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 79692f60a7Smrg{ 80692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 81692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 82692f60a7Smrg CARD8 *dstPtr, *srcPtr, *src; 83692f60a7Smrg CARD32 *dst; 84692f60a7Smrg 85692f60a7Smrg dstPitch = pScrn->displayWidth; 86692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch; 87692f60a7Smrg 88692f60a7Smrg while(num--) { 89692f60a7Smrg width = pbox->x2 - pbox->x1; 90692f60a7Smrg y1 = pbox->y1 & ~3; 91692f60a7Smrg y2 = (pbox->y2 + 3) & ~3; 92692f60a7Smrg height = (y2 - y1) >> 2; /* in dwords */ 93692f60a7Smrg 94692f60a7Smrg if(nPtr->rotate == 1) { 95692f60a7Smrg dstPtr = nPtr->NeoFbBase + 96692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 97692f60a7Smrg srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 98692f60a7Smrg } else { 99692f60a7Smrg dstPtr = nPtr->NeoFbBase + 100692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 101692f60a7Smrg srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 102692f60a7Smrg } 103692f60a7Smrg 104692f60a7Smrg while(width--) { 105692f60a7Smrg src = srcPtr; 106692f60a7Smrg dst = (CARD32*)dstPtr; 107692f60a7Smrg count = height; 108692f60a7Smrg while(count--) { 109692f60a7Smrg *(dst++) = src[0] | (src[srcPitch] << 8) | 110692f60a7Smrg (src[srcPitch * 2] << 16) | 111692f60a7Smrg (src[srcPitch * 3] << 24); 112692f60a7Smrg src += srcPitch * 4; 113692f60a7Smrg } 114692f60a7Smrg srcPtr += nPtr->rotate; 115692f60a7Smrg dstPtr += dstPitch; 116692f60a7Smrg } 117692f60a7Smrg 118692f60a7Smrg pbox++; 119692f60a7Smrg } 120692f60a7Smrg} 121692f60a7Smrg 122692f60a7Smrg 123692f60a7Smrgvoid 124692f60a7SmrgneoRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 125692f60a7Smrg{ 126692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 127692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 128692f60a7Smrg CARD16 *dstPtr, *srcPtr, *src; 129692f60a7Smrg CARD32 *dst; 130692f60a7Smrg 131692f60a7Smrg dstPitch = pScrn->displayWidth; 132692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 1; 133692f60a7Smrg 134692f60a7Smrg while(num--) { 135692f60a7Smrg width = pbox->x2 - pbox->x1; 136692f60a7Smrg y1 = pbox->y1 & ~1; 137692f60a7Smrg y2 = (pbox->y2 + 1) & ~1; 138692f60a7Smrg height = (y2 - y1) >> 1; /* in dwords */ 139692f60a7Smrg 140692f60a7Smrg if(nPtr->rotate == 1) { 141692f60a7Smrg dstPtr = (CARD16*)nPtr->NeoFbBase + 142692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 143692f60a7Smrg srcPtr = (CARD16*)nPtr->ShadowPtr + 144692f60a7Smrg ((1 - y2) * srcPitch) + pbox->x1; 145692f60a7Smrg } else { 146692f60a7Smrg dstPtr = (CARD16*)nPtr->NeoFbBase + 147692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 148692f60a7Smrg srcPtr = (CARD16*)nPtr->ShadowPtr + 149692f60a7Smrg (y1 * srcPitch) + pbox->x2 - 1; 150692f60a7Smrg } 151692f60a7Smrg 152692f60a7Smrg while(width--) { 153692f60a7Smrg src = srcPtr; 154692f60a7Smrg dst = (CARD32*)dstPtr; 155692f60a7Smrg count = height; 156692f60a7Smrg while(count--) { 157692f60a7Smrg *(dst++) = src[0] | (src[srcPitch] << 16); 158692f60a7Smrg src += srcPitch * 2; 159692f60a7Smrg } 160692f60a7Smrg srcPtr += nPtr->rotate; 161692f60a7Smrg dstPtr += dstPitch; 162692f60a7Smrg } 163692f60a7Smrg 164692f60a7Smrg pbox++; 165692f60a7Smrg } 166692f60a7Smrg} 167692f60a7Smrg 168692f60a7Smrg 169692f60a7Smrg/* this one could be faster */ 170692f60a7Smrgvoid 171692f60a7SmrgneoRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 172692f60a7Smrg{ 173692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 174692f60a7Smrg int count, width, height, y1, y2, dstPitch, srcPitch; 175692f60a7Smrg CARD8 *dstPtr, *srcPtr, *src; 176692f60a7Smrg CARD32 *dst; 177692f60a7Smrg 178692f60a7Smrg dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 179692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch; 180692f60a7Smrg 181692f60a7Smrg while(num--) { 182692f60a7Smrg width = pbox->x2 - pbox->x1; 183692f60a7Smrg y1 = pbox->y1 & ~3; 184692f60a7Smrg y2 = (pbox->y2 + 3) & ~3; 185692f60a7Smrg height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 186692f60a7Smrg 187692f60a7Smrg if(nPtr->rotate == 1) { 188692f60a7Smrg dstPtr = nPtr->NeoFbBase + 189692f60a7Smrg (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 190692f60a7Smrg srcPtr = nPtr->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 191692f60a7Smrg } else { 192692f60a7Smrg dstPtr = nPtr->NeoFbBase + 193692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 194692f60a7Smrg srcPtr = nPtr->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 195692f60a7Smrg } 196692f60a7Smrg 197692f60a7Smrg while(width--) { 198692f60a7Smrg src = srcPtr; 199692f60a7Smrg dst = (CARD32*)dstPtr; 200692f60a7Smrg count = height; 201692f60a7Smrg while(count--) { 202692f60a7Smrg dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | 203692f60a7Smrg (src[srcPitch] << 24); 204692f60a7Smrg dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | 205692f60a7Smrg (src[srcPitch * 2] << 16) | 206692f60a7Smrg (src[(srcPitch * 2) + 1] << 24); 207692f60a7Smrg dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | 208692f60a7Smrg (src[(srcPitch * 3) + 1] << 16) | 209692f60a7Smrg (src[(srcPitch * 3) + 2] << 24); 210692f60a7Smrg dst += 3; 211692f60a7Smrg src += srcPitch * 4; 212692f60a7Smrg } 213692f60a7Smrg srcPtr += nPtr->rotate * 3; 214692f60a7Smrg dstPtr += dstPitch; 215692f60a7Smrg } 216692f60a7Smrg 217692f60a7Smrg pbox++; 218692f60a7Smrg } 219692f60a7Smrg} 220692f60a7Smrg 221692f60a7Smrgvoid 222692f60a7SmrgneoRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 223692f60a7Smrg{ 224692f60a7Smrg NEOPtr nPtr = NEOPTR(pScrn); 225692f60a7Smrg int count, width, height, dstPitch, srcPitch; 226692f60a7Smrg CARD32 *dstPtr, *srcPtr, *src, *dst; 227692f60a7Smrg 228692f60a7Smrg dstPitch = pScrn->displayWidth; 229692f60a7Smrg srcPitch = -nPtr->rotate * nPtr->ShadowPitch >> 2; 230692f60a7Smrg 231692f60a7Smrg while(num--) { 232692f60a7Smrg width = pbox->x2 - pbox->x1; 233692f60a7Smrg height = pbox->y2 - pbox->y1; 234692f60a7Smrg 235692f60a7Smrg if(nPtr->rotate == 1) { 236692f60a7Smrg dstPtr = (CARD32*)nPtr->NeoFbBase + 237692f60a7Smrg (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 238692f60a7Smrg srcPtr = (CARD32*)nPtr->ShadowPtr + 239692f60a7Smrg ((1 - pbox->y2) * srcPitch) + pbox->x1; 240692f60a7Smrg } else { 241692f60a7Smrg dstPtr = (CARD32*)nPtr->NeoFbBase + 242692f60a7Smrg ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 243692f60a7Smrg srcPtr = (CARD32*)nPtr->ShadowPtr + 244692f60a7Smrg (pbox->y1 * srcPitch) + pbox->x2 - 1; 245692f60a7Smrg } 246692f60a7Smrg 247692f60a7Smrg while(width--) { 248692f60a7Smrg src = srcPtr; 249692f60a7Smrg dst = dstPtr; 250692f60a7Smrg count = height; 251692f60a7Smrg while(count--) { 252692f60a7Smrg *(dst++) = *src; 253692f60a7Smrg src += srcPitch; 254692f60a7Smrg } 255692f60a7Smrg srcPtr += nPtr->rotate; 256692f60a7Smrg dstPtr += dstPitch; 257692f60a7Smrg } 258692f60a7Smrg 259692f60a7Smrg pbox++; 260692f60a7Smrg } 261692f60a7Smrg} 262692f60a7Smrg 263692f60a7Smrg 264692f60a7Smrg 265