sis_shadow.c revision 72b676d7
1/* $XFree86$ */ 2/* $XdotOrg$ */ 3/* 4 * Copyright (C) 1999-2004 by The XFree86 Project, Inc. 5 * based on code written by Mark Vojkovich 6 * Copyright (C) 2003-2005 Thomas Winischhofer 7 * 8 * Licensed under the following terms: 9 * 10 * Permission to use, copy, modify, distribute, and sell this software and its 11 * documentation for any purpose is hereby granted without fee, provided that 12 * the above copyright notice appears in all copies and that both that copyright 13 * notice and this permission notice appear in supporting documentation, and 14 * and that the name of the copyright holder not be used in advertising 15 * or publicity pertaining to distribution of the software without specific, 16 * written prior permission. The copyright holder makes no representations 17 * about the suitability of this software for any purpose. It is provided 18 * "as is" without expressed or implied warranty. 19 * 20 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 22 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR 23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 24 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 25 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 26 * PERFORMANCE OF THIS SOFTWARE. 27 * 28 * This module doesn't use CurrentLayout, because it is never 29 * active when DGA is active and vice versa. 30 */ 31 32#ifdef HAVE_CONFIG_H 33#include "config.h" 34#endif 35 36#include "sis.h" 37#include "servermd.h" 38 39void SISPointerMoved(int index, int x, int y); 40void SISPointerMovedReflect(int index, int x, int y); 41void SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 42void SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 43void SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 44void SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 45void SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 46void SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); 47 48void 49SISPointerMoved(int index, int x, int y) 50{ 51 ScrnInfoPtr pScrn = xf86Screens[index]; 52 SISPtr pSiS = SISPTR(pScrn); 53 54 if(pSiS->Rotate == 1) { 55 (*pSiS->PointerMoved)(index, pScrn->pScreen->height - y - 1, x); 56 } else { 57 (*pSiS->PointerMoved)(index, y, pScrn->pScreen->width - x - 1); 58 } 59} 60 61void 62SISPointerMovedReflect(int index, int x, int y) 63{ 64 ScrnInfoPtr pScrn = xf86Screens[index]; 65 SISPtr pSiS = SISPTR(pScrn); 66 67 switch(pSiS->Reflect) { 68 case 1: /* x */ 69 (*pSiS->PointerMoved)(index, pScrn->pScreen->width - x - 1, y); 70 break; 71 case 2: /* y */ 72 (*pSiS->PointerMoved)(index, x, pScrn->pScreen->height - y - 1); 73 break; 74 case 3: /* x + y */ 75 (*pSiS->PointerMoved)(index, pScrn->pScreen->width - x - 1, pScrn->pScreen->height - y - 1); 76 } 77} 78 79/* Refresh area (unreflected, unrotated) */ 80 81void 82SISRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 83{ 84 SISPtr pSiS = SISPTR(pScrn); 85 int width, height, Bpp, FBPitch; 86 CARD8 *src, *dst; 87 88 Bpp = pScrn->bitsPerPixel >> 3; 89 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 90 91 while(num--) { 92 93 width = (pbox->x2 - pbox->x1) * Bpp; 94 height = pbox->y2 - pbox->y1; 95 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp); 96 dst = pSiS->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); 97 98 while(height--) { 99 SiSMemCopyToVideoRam(pSiS, dst, src, width); 100 dst += FBPitch; 101 src += pSiS->ShadowPitch; 102 } 103 104 pbox++; 105 } 106} 107 108/* RefreshArea for reflection */ 109 110void 111SISRefreshAreaReflect(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 112{ 113 SISPtr pSiS = SISPTR(pScrn); 114 int width, height, Bpp, FBPitch, twidth; 115 CARD8 *src, *dst, *tdst, *tsrc; 116 CARD16 *tdst16, *tsrc16; 117 CARD32 *tdst32, *tsrc32; 118 119 Bpp = pScrn->bitsPerPixel >> 3; 120 FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); 121 122 while(num--) { 123 width = (pbox->x2 - pbox->x1) * Bpp; 124 height = pbox->y2 - pbox->y1; 125 src = pSiS->ShadowPtr + (pbox->y1 * pSiS->ShadowPitch) + (pbox->x1 * Bpp); 126 dst = pSiS->FbBase; 127 switch(pSiS->Reflect) { 128 case 1: /* x */ 129 dst += (pbox->y1 * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp); 130 switch(Bpp) { 131 case 1: 132 while(height--) { 133 tdst = dst; 134 tsrc = src; 135 twidth = width; 136 while(twidth--) *tdst-- = *tsrc++; 137 dst += FBPitch; 138 src += pSiS->ShadowPitch; 139 } 140 break; 141 case 2: 142 width >>= 1; 143 while(height--) { 144 tdst16 = (CARD16 *)dst; 145 tsrc16 = (CARD16 *)src; 146 twidth = width; 147 while(twidth--) *tdst16-- = *tsrc16++; 148 dst += FBPitch; 149 src += pSiS->ShadowPitch; 150 } 151 break; 152 case 4: 153 width >>= 2; 154 while(height--) { 155 tdst32 = (CARD32 *)dst; 156 tsrc32 = (CARD32 *)src; 157 twidth = width; 158 while(twidth--) *tdst32-- = *tsrc32++; 159 dst += FBPitch; 160 src += pSiS->ShadowPitch; 161 } 162 } 163 break; 164 case 2: /* y */ 165 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + (pbox->x1 * Bpp); 166 while(height--) { 167 SiSMemCopyToVideoRam(pSiS, dst, src, width); 168 dst -= FBPitch; 169 src += pSiS->ShadowPitch; 170 } 171 break; 172 case 3: /* x + y */ 173 dst += ((pScrn->virtualY - pbox->y1 - 1) * FBPitch) + ((pScrn->displayWidth - pbox->x1 - 1) * Bpp); 174 switch(Bpp) { 175 case 1: 176 while(height--) { 177 tdst = dst; 178 tsrc = src; 179 twidth = width; 180 while(twidth--) *tdst-- = *tsrc++; 181 dst -= FBPitch; 182 src += pSiS->ShadowPitch; 183 } 184 break; 185 case 2: 186 width >>= 1; 187 while(height--) { 188 tdst16 = (CARD16 *)dst; 189 tsrc16 = (CARD16 *)src; 190 twidth = width; 191 while(twidth--) *tdst16-- = *tsrc16++; 192 dst -= FBPitch; 193 src += pSiS->ShadowPitch; 194 } 195 break; 196 case 4: 197 width >>= 2; 198 while(height--) { 199 tdst32 = (CARD32 *)dst; 200 tsrc32 = (CARD32 *)src; 201 twidth = width; 202 while(twidth--) *tdst32-- = *tsrc32++; 203 dst -= FBPitch; 204 src += pSiS->ShadowPitch; 205 } 206 break; 207 } 208 } 209 pbox++; 210 } 211} 212 213/* RefreshArea()s for rotation */ 214 215void 216SISRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 217{ 218 SISPtr pSiS = SISPTR(pScrn); 219 int count, width, height, y1, y2, dstPitch, srcPitch; 220 CARD8 *dstPtr, *srcPtr, *src; 221 CARD32 *dst; 222 223 dstPitch = pScrn->displayWidth; 224 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch; 225 226 while(num--) { 227 width = pbox->x2 - pbox->x1; 228 y1 = pbox->y1 & ~3; 229 y2 = (pbox->y2 + 3) & ~3; 230 height = (y2 - y1) >> 2; /* in dwords */ 231 232 if(pSiS->Rotate == 1) { 233 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 234 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 235 } else { 236 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 237 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 238 } 239 240 while(width--) { 241 src = srcPtr; 242 dst = (CARD32 *)dstPtr; 243 count = height; 244 while(count--) { 245 *(dst++) = src[0] | 246 (src[srcPitch] << 8) | 247 (src[srcPitch * 2] << 16) | 248 (src[srcPitch * 3] << 24); 249 src += (srcPitch * 4); 250 } 251 srcPtr += pSiS->Rotate; 252 dstPtr += dstPitch; 253 } 254 255 pbox++; 256 } 257} 258 259void 260SISRefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 261{ 262 SISPtr pSiS = SISPTR(pScrn); 263 int count, width, height, y1, y2, dstPitch, srcPitch; 264 CARD16 *dstPtr, *srcPtr, *src; 265 CARD32 *dst; 266 267 dstPitch = pScrn->displayWidth; 268 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 1; 269 270 while(num--) { 271 width = pbox->x2 - pbox->x1; 272 y1 = pbox->y1 & ~1; 273 y2 = (pbox->y2 + 1) & ~1; 274 height = (y2 - y1) >> 1; /* in dwords */ 275 276 if(pSiS->Rotate == 1) { 277 dstPtr = (CARD16 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; 278 srcPtr = (CARD16 *)pSiS->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; 279 } else { 280 dstPtr = (CARD16 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; 281 srcPtr = (CARD16 *)pSiS->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; 282 } 283 284 while(width--) { 285 src = srcPtr; 286 dst = (CARD32 *)dstPtr; 287 count = height; 288 while(count--) { 289 *(dst++) = src[0] | (src[srcPitch] << 16); 290 src += (srcPitch * 2); 291 } 292 srcPtr += pSiS->Rotate; 293 dstPtr += dstPitch; 294 } 295 296 pbox++; 297 } 298} 299 300/* this one could be faster */ 301void 302SISRefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 303{ 304 SISPtr pSiS = SISPTR(pScrn); 305 int count, width, height, y1, y2, dstPitch, srcPitch; 306 CARD8 *dstPtr, *srcPtr, *src; 307 CARD32 *dst; 308 309 dstPitch = BitmapBytePad(pScrn->displayWidth * 24); 310 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch; 311 312 while(num--) { 313 width = pbox->x2 - pbox->x1; 314 y1 = pbox->y1 & ~3; 315 y2 = (pbox->y2 + 3) & ~3; 316 height = (y2 - y1) >> 2; /* blocks of 3 dwords */ 317 318 if(pSiS->Rotate == 1) { 319 dstPtr = pSiS->FbBase + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); 320 srcPtr = pSiS->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); 321 } else { 322 dstPtr = pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); 323 srcPtr = pSiS->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; 324 } 325 326 while(width--) { 327 src = srcPtr; 328 dst = (CARD32 *)dstPtr; 329 count = height; 330 while(count--) { 331 dst[0] = src[0] | 332 (src[1] << 8) | 333 (src[2] << 16) | 334 (src[srcPitch] << 24); 335 dst[1] = src[srcPitch + 1] | 336 (src[srcPitch + 2] << 8) | 337 (src[srcPitch * 2] << 16) | 338 (src[(srcPitch * 2) + 1] << 24); 339 dst[2] = src[(srcPitch * 2) + 2] | 340 (src[srcPitch * 3] << 8) | 341 (src[(srcPitch * 3) + 1] << 16) | 342 (src[(srcPitch * 3) + 2] << 24); 343 dst += 3; 344 src += (srcPitch << 2); 345 } 346 srcPtr += pSiS->Rotate * 3; 347 dstPtr += dstPitch; 348 } 349 350 pbox++; 351 } 352} 353 354void 355SISRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) 356{ 357 SISPtr pSiS = SISPTR(pScrn); 358 int count, width, height, dstPitch, srcPitch; 359 CARD32 *dstPtr, *srcPtr, *src, *dst; 360 361 dstPitch = pScrn->displayWidth; 362 srcPitch = -pSiS->Rotate * pSiS->ShadowPitch >> 2; 363 364 while(num--) { 365 width = pbox->x2 - pbox->x1; 366 height = pbox->y2 - pbox->y1; 367 368 if(pSiS->Rotate == 1) { 369 dstPtr = (CARD32 *)pSiS->FbBase + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; 370 srcPtr = (CARD32 *)pSiS->ShadowPtr + ((1 - pbox->y2) * srcPitch) + pbox->x1; 371 } else { 372 dstPtr = (CARD32 *)pSiS->FbBase + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; 373 srcPtr = (CARD32 *)pSiS->ShadowPtr + (pbox->y1 * srcPitch) + pbox->x2 - 1; 374 } 375 376 while(width--) { 377 src = srcPtr; 378 dst = dstPtr; 379 count = height; 380 while(count--) { 381 *(dst++) = *src; 382 src += srcPitch; 383 } 384 srcPtr += pSiS->Rotate; 385 dstPtr += dstPitch; 386 } 387 388 pbox++; 389 } 390} 391