s3_shadow.c revision b27e1915
1/* 2Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 4Permission is hereby granted, free of charge, to any person obtaining a copy of 5this software and associated documentation files (the "Software"), to deal in 6the Software without restriction, including without limitation the rights to 7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 8of the Software, and to permit persons to whom the Software is furnished to do 9so, subject to the following conditions: 10 11The above copyright notice and this permission notice shall be included in all 12copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 16NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of the XFree86 Project shall not 22be used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from the XFree86 Project. 24*/ 25 26/* 27 Copyright (c) 1999,2000 The XFree86 Project Inc. 28 based on code written by Mark Vojkovich <markv@valinux.com> 29*/ 30 31#ifdef HAVE_CONFIG_H 32#include "config.h" 33#endif 34 35#include "xf86.h" 36#include "xf86_OSproc.h" 37#include "xf86PciInfo.h" 38#include "xf86Pci.h" 39#include "shadowfb.h" 40#include "servermd.h" 41#include "s3.h" 42 43 44void 45S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 46{ 47 S3Ptr pS3 = S3PTR(pScrn); 48 int width, height, Bpp, FBPitch; 49 unsigned char *src, *dst; 50 51 Bpp = pScrn->bitsPerPixel >> 3; 52 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 53 54 while(num--) { 55 width = (pbox->x2 - pbox->x1) * Bpp; 56 height = pbox->y2 - pbox->y1; 57 src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) + 58 (pbox->x1 * Bpp); 59 dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 60 61 while(height--) { 62 memcpy(dst, src, width); 63 dst += FBPitch; 64 src += pS3->ShadowPitch; 65 } 66 67 pbox++; 68 } 69} 70 71void 72S3PointerMoved(SCRN_ARG_TYPE arg, int x, int y) 73{ 74 SCRN_INFO_PTR(arg); 75 S3Ptr pS3 = S3PTR(pScrn); 76 int newX, newY; 77 78 if(pS3->rotate == 1) { 79 newX = pScrn->pScreen->height - y - 1; 80 newY = x; 81 } else { 82 newX = y; 83 newY = pScrn->pScreen->width - x - 1; 84 } 85 86 (*pS3->PointerMoved)(arg, newX, newY); 87} 88 89void 90S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 91{ 92 S3Ptr pS3 = S3PTR(pScrn); 93 int count, width, height, y1, y2, dstPitch, srcPitch; 94 CARD8 *dstPtr, *srcPtr, *src; 95 CARD32 *dst; 96 97 dstPitch = pScrn->displayWidth; 98 srcPitch = -pS3->rotate * pS3->ShadowPitch; 99 100 while(num--) { 101 width = pbox->x2 - pbox->x1; 102 y1 = pbox->y1 & ~3; 103 y2 = (pbox->y2 + 3) & ~3; 104 height = (y2 - y1) >> 2; /* in dwords */ 105 106 if(pS3->rotate == 1) { 107 dstPtr = pS3->FBBase + 108 (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 109 srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 110 } else { 111 dstPtr = pS3->FBBase + 112 ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 113 srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 114 } 115 116 while(width--) { 117 src = srcPtr; 118 dst = (CARD32*)dstPtr; 119 count = height; 120 while(count--) { 121 *(dst++) = src[0] | (src[srcPitch] << 8) | 122 (src[srcPitch * 2] << 16) | 123 (src[srcPitch * 3] << 24); 124 src += srcPitch * 4; 125 } 126 srcPtr += pS3->rotate; 127 dstPtr += dstPitch; 128 } 129 130 pbox++; 131 } 132} 133 134 135void 136S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 137{ 138 S3Ptr pS3 = S3PTR(pScrn); 139 int count, width, height, y1, y2, dstPitch, srcPitch; 140 CARD16 *dstPtr, *srcPtr, *src; 141 CARD32 *dst; 142 143 dstPitch = pScrn->displayWidth; 144 srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1; 145 146 while(num--) { 147 width = pbox->x2 - pbox->x1; 148 y1 = pbox->y1 & ~1; 149 y2 = (pbox->y2 + 1) & ~1; 150 height = (y2 - y1) >> 1; /* in dwords */ 151 152 if(pS3->rotate == 1) { 153 dstPtr = (CARD16*)pS3->FBBase + 154 (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 155 srcPtr = (CARD16*)pS3->ShadowPtr + 156 ((1 - y2) * srcPitch) + pbox->x1; 157 } else { 158 dstPtr = (CARD16*)pS3->FBBase + 159 ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 160 srcPtr = (CARD16*)pS3->ShadowPtr + 161 (y1 * srcPitch) + pbox->x2 - 1; 162 } 163 164 while(width--) { 165 src = srcPtr; 166 dst = (CARD32*)dstPtr; 167 count = height; 168 while(count--) { 169 *(dst++) = src[0] | (src[srcPitch] << 16); 170 src += srcPitch * 2; 171 } 172 srcPtr += pS3->rotate; 173 dstPtr += dstPitch; 174 } 175 176 pbox++; 177 } 178} 179 180 181/* this one could be faster */ 182void 183S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 184{ 185 S3Ptr pS3 = S3PTR(pScrn); 186 int count, width, height, y1, y2, dstPitch, srcPitch; 187 CARD8 *dstPtr, *srcPtr, *src; 188 CARD32 *dst; 189 190 dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 191 srcPitch = -pS3->rotate * pS3->ShadowPitch; 192 193 while(num--) { 194 width = pbox->x2 - pbox->x1; 195 y1 = pbox->y1 & ~3; 196 y2 = (pbox->y2 + 3) & ~3; 197 height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 198 199 if(pS3->rotate == 1) { 200 dstPtr = pS3->FBBase + 201 (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 202 srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 203 } else { 204 dstPtr = pS3->FBBase + 205 ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 206 srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 207 } 208 209 while(width--) { 210 src = srcPtr; 211 dst = (CARD32*)dstPtr; 212 count = height; 213 while(count--) { 214 dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | 215 (src[srcPitch] << 24); 216 dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | 217 (src[srcPitch * 2] << 16) | 218 (src[(srcPitch * 2) + 1] << 24); 219 dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | 220 (src[(srcPitch * 3) + 1] << 16) | 221 (src[(srcPitch * 3) + 2] << 24); 222 dst += 3; 223 src += srcPitch * 4; 224 } 225 srcPtr += pS3->rotate * 3; 226 dstPtr += dstPitch; 227 } 228 229 pbox++; 230 } 231} 232 233void 234S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 235{ 236 S3Ptr pS3 = S3PTR(pScrn); 237 int count, width, height, dstPitch, srcPitch; 238 CARD32 *dstPtr, *srcPtr, *src, *dst; 239 240 dstPitch = pScrn->displayWidth; 241 srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2; 242 243 while(num--) { 244 width = pbox->x2 - pbox->x1; 245 height = pbox->y2 - pbox->y1; 246 247 if(pS3->rotate == 1) { 248 dstPtr = (CARD32*)pS3->FBBase + 249 (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 250 srcPtr = (CARD32*)pS3->ShadowPtr + 251 ((1 - pbox->y2) * srcPitch) + pbox->x1; 252 } else { 253 dstPtr = (CARD32*)pS3->FBBase + 254 ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 255 srcPtr = (CARD32*)pS3->ShadowPtr + 256 (pbox->y1 * srcPitch) + pbox->x2 - 1; 257 } 258 259 while(width--) { 260 src = srcPtr; 261 dst = dstPtr; 262 count = height; 263 while(count--) { 264 *(dst++) = *src; 265 src += srcPitch; 266 } 267 srcPtr += pS3->rotate; 268 dstPtr += dstPitch; 269 } 270 271 pbox++; 272 } 273} 274