diff options
author | Evgeny M. Zubok <evgeny.zubok@tochka.ru> | 2009-05-04 15:10:17 +0400 |
---|---|---|
committer | Evgeny M. Zubok <evgeny.zubok@tochka.ru> | 2009-05-04 15:10:17 +0400 |
commit | a1d6d9bec68c3bf47af69b73c875836bc46db3a1 (patch) | |
tree | 63e2cbcae18bfb88914a441763801f6632134a4d | |
parent | dd2e8e7a5f0bbb0f6fc3cb32161a0024545179bc (diff) |
shadowFB option. Interlace mode support. Close bug #14999.
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/s3.h | 16 | ||||
-rw-r--r-- | src/s3_driver.c | 203 | ||||
-rw-r--r-- | src/s3_shadow.c | 274 |
5 files changed, 421 insertions, 92 deletions
@@ -1,3 +1,18 @@ +2009-05-04 Evgeny M. Zubok <evgeny.zubok@tochka.ru> + + * src/s3_driver.c: + * src/s3_shadow.c: + + Add shadowFB option. It can be used to speedup drawing when + hardware acceleration is unwanted or unavailable (for colour depth + 24 with 24 bpp framebuffer, for example). shadowFB is disabled by + default. Enabling shadowFB option disables HW acceleration. Thanks + to Egor Ivanov for initial porting of shadowFB from s3virge. + + Interlace mode support. + + Close bug #14999. + 2008-07-06 Evgeny M. Zubok <evgeny.zubok@tochka.ru> * src/s3_video.c: @@ -14,7 +29,7 @@ not implemented yet for all chipsets). Close bug #5527: 24-bit colour depth support (24bpp and - 32bpp framebuffer) for TRIO64V2. Acceleration doesn't work + 32bpp framebuffer) for TRIOs. Acceleration doesn't work with packed colour mode (24 bpp FB) but works with 32bpp framebuffer mode (hardware limitation? -- need data). diff --git a/src/Makefile.am b/src/Makefile.am index 743babd..84f926c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,7 +39,8 @@ s3_drv_la_SOURCES = \ s3_pcirename.h \ s3_reg.h \ s3_Ti.c \ - s3_Trio64DAC.c + s3_Trio64DAC.c \ + s3_shadow.c noinst_LTLIBRARIES = libs3_accel_newmmio.la libs3_accel_pio.la s3_drv_la_LIBADD = libs3_accel_newmmio.la libs3_accel_pio.la @@ -163,6 +163,13 @@ typedef struct _S3Rec { int imageWidth; int imageHeight; Bool hwCursor; + + Bool shadowFB; + int rotate; + unsigned char * ShadowPtr; + int ShadowPitch; + void (*PointerMoved)(int index, int x, int y); + } S3Rec, *S3Ptr; #define S3PTR(p) ((S3Ptr)((p)->driverPrivate)) @@ -224,6 +231,15 @@ void S3OutTiIndReg(ScrnInfoPtr pScrn, CARD32 reg, unsigned char mask, /* s3 gen cursor */ Bool S3_CursorInit(ScreenPtr pScreen); +/* in s3_shadow.c */ +void S3PointerMoved(int index, int x, int y); +void S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox); +void S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + + #define TRIO64_RAMDAC 0x8811 #define TI3025_RAMDAC 0x3025 #define TI3020_RAMDAC 0x3020 diff --git a/src/s3_driver.c b/src/s3_driver.c index 29e7fb5..88dc25a 100644 --- a/src/s3_driver.c +++ b/src/s3_driver.c @@ -54,7 +54,7 @@ #include "mibstore.h" #include "fb.h" #include "inputstr.h" - +#include "shadowfb.h" #include "IBM.h" #include "TI.h" @@ -157,7 +157,9 @@ typedef enum { OPTION_SLOW_DRAM, OPTION_SLOW_EDODRAM, OPTION_SLOW_VRAM, - OPTION_XVIDEO + OPTION_XVIDEO, + OPTION_SHADOW_FB, + OPTION_ROTATE } S3Opts; static OptionInfoRec S3Options[] = { @@ -168,6 +170,8 @@ static OptionInfoRec S3Options[] = { { OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SLOW_VRAM, "slow_vram", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -208,6 +212,12 @@ static const char *vbeSymbols[] = { NULL }; +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + + static const char *int10Symbols[] = { "xf86ExecX86int10", "xf86FreeInt10", @@ -269,6 +279,7 @@ pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin) xf86AddDriver(&S3, module, 0); LoaderRefSymLists(vgaHWSymbols, vbeSymbols, int10Symbols, ramdacSymbols, + shadowSymbols, fbSymbols, xaaSymbols, NULL); @@ -372,6 +383,7 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags) Gamma gzeros = {0.0, 0.0, 0.0}; int i, vgaCRIndex, vgaCRReg; unsigned char tmp; + char *s; if (flags & PROBE_DETECT) return FALSE; @@ -435,6 +447,48 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags) pS3->SlowDRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM, FALSE); pS3->SlowEDODRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_EDODRAM, FALSE); pS3->SlowVRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_VRAM, FALSE); + + + + if (xf86GetOptValBool(S3Options, OPTION_SHADOW_FB, &pS3->shadowFB)) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", + pS3->shadowFB ? "enabled" : "disabled"); + + pS3->rotate = 0; + if ((s = xf86GetOptValString(S3Options, OPTION_ROTATE))) { + if(!xf86NameCmp(s, "CW")) { + /* accel is disabled below for shadowFB */ + pS3->shadowFB = TRUE; + pS3->rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else if(!xf86NameCmp(s, "CCW")) { + pS3->shadowFB = TRUE; + pS3->rotate = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" + "counter clockwise - acceleration disabled\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" + "value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\" or \"CCW\"\n"); + } + } + + if(pS3->shadowFB && !pS3->NoAccel) { + pS3->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "HW acceleration not supported with \"shadowFB\".\n"); + } + + + if (pS3->rotate && pS3->HWCursor) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "HW cursor not supported with \"rotate\".\n"); + pS3->HWCursor = FALSE; + } + + if (pScrn->numEntities > 1) { S3FreeRec(pScrn); return FALSE; @@ -457,6 +511,14 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags) pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index); } + if (pS3->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + S3FreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + if (!xf86SetGamma(pScrn, gzeros)) return FALSE; @@ -722,7 +784,7 @@ static Bool S3PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - xf86SetCrtcForModes(pScrn, 0); + xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); pScrn->currentMode = pScrn->modes; xf86PrintModes(pScrn); xf86SetDpi(pScrn, 0, 0); @@ -744,6 +806,16 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; S3Ptr pS3 = S3PTR(pScrn); BoxRec ScreenArea; + int width, height, displayWidth; + + if (pS3->rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } else { + width = pScrn->virtualX; + height = pScrn->virtualY; + } + pScrn->fbOffset = 0; @@ -778,7 +850,18 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, miSetPixmapDepths (); - if (!fbScreenInit(pScreen, pS3->FBBase, pScrn->virtualX, + /* no screen rotation assumed */ + if(pS3->shadowFB) { + pS3->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); + pS3->ShadowPtr = xalloc(pS3->ShadowPitch * height); + displayWidth = pS3->ShadowPitch / (pScrn->bitsPerPixel >> 3); + } else { + pS3->ShadowPtr = NULL; + displayWidth = pScrn->displayWidth; + } + + if (!fbScreenInit(pScreen, (pS3->shadowFB ? pS3->ShadowPtr : pS3->FBBase), + pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) return FALSE; @@ -824,7 +907,6 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, ScreenArea.x1, ScreenArea.y1, ScreenArea.x2, ScreenArea.y2); - /* 2D acceleration setup */ if (pS3->NoAccel) @@ -832,13 +914,13 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, "Acceleration disabled (by option)\n"); /* It seems that acceleration isn't supported for 24-bit packed - colour. Disable it for S3 Trio64V2 */ - if (!pS3->NoAccel && (pScrn->bitsPerPixel == 24) && - (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration isn't supported for 24 bpp. Disabled.\n"); + colour. So disable it. Using shadowFB is recommended in this mode. */ + if (!pS3->NoAccel && (pScrn->bitsPerPixel == 24)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HW acceleration isn't supported for 24 bpp. Disabled.\n"); pS3->NoAccel = TRUE; } + if (!pS3->NoAccel) { if (pS3->S3NewMMIO) if (S3AccelInitNewMMIO(pScreen)) { @@ -882,6 +964,28 @@ static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n"); + /* Shadow framebuffer setup */ + + if (pS3->shadowFB) { + RefreshAreaFuncPtr refreshArea = S3RefreshArea; + + if (pS3->rotate) { + if (!pS3->PointerMoved) { + pS3->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = S3PointerMoved; + } + + switch (pScrn->bitsPerPixel) { + case 8: refreshArea = S3RefreshArea8; break; + case 16: refreshArea = S3RefreshArea16; break; + case 24: refreshArea = S3RefreshArea24; break; + case 32: refreshArea = S3RefreshArea32; break; + } + } + + ShadowFBInit(pScreen, refreshArea); + } + if (!miCreateDefColormap(pScreen)) @@ -1226,9 +1330,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) if ((mode->HTotal == mode->CrtcHTotal) && (pS3->pixMuxShift != 0)) { if (pS3->pixMuxShift > 0) { - /* XXX hack */ -/* mode->Flags |= V_PIXMUX; */ - mode->CrtcHTotal >>= pS3->pixMuxShift; mode->CrtcHDisplay >>= pS3->pixMuxShift; mode->CrtcHBlankStart >>= pS3->pixMuxShift; @@ -1237,8 +1338,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) mode->CrtcHSyncEnd >>= pS3->pixMuxShift; mode->CrtcHSkew >>= pS3->pixMuxShift; } else if (pS3->pixMuxShift < 0) { -/* mode->Flags |= V_PIXMUX; */ - mode->CrtcHTotal <<= -pS3->pixMuxShift; mode->CrtcHDisplay <<= -pS3->pixMuxShift; mode->CrtcHBlankStart <<= -pS3->pixMuxShift; @@ -1249,15 +1348,6 @@ static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) } } - /* This shouldn't be needed -- they should be set by vgaHWInit() */ - if (!mode->CrtcVAdjusted) { - mode->CrtcVTotal >>= interlacedived; - mode->CrtcVDisplay >>= interlacedived; - mode->CrtcVSyncStart >>= interlacedived; - mode->CrtcVSyncEnd >>= interlacedived; - mode->CrtcVAdjusted = TRUE; - } - if (!vgaHWInit(pScrn, mode)) return FALSE; @@ -1932,71 +2022,6 @@ void S3Regdump(ScrnInfoPtr pScrn) { S3Ptr pS3 = S3PTR(pScrn); int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; - -#if 0 - outb(vgaCRIndex, 0x31); - ErrorF("cr31 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x32); - ErrorF("cr32 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x33); - ErrorF("cr33 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x34); - ErrorF("cr34 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x3a); - ErrorF("cr3a = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x3b); - ErrorF("cr3b = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x3c); - ErrorF("cr3c = 0x%x\n", inb(vgaCRReg)); - - outb(vgaCRIndex, 0x40); - ErrorF("cr40 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x42); - ErrorF("cr42 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x43); - ErrorF("cr43 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x44); - ErrorF("cr44 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x45); - ErrorF("cr45 = 0x%x\n", inb(vgaCRReg)); - - outb(vgaCRIndex, 0x50); - ErrorF("cr50 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x51); - ErrorF("cr51 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x53); - ErrorF("cr53 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x54); - ErrorF("cr54 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x55); - ErrorF("cr55 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x58); - ErrorF("cr58 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x59); - ErrorF("cr59 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x5a); - ErrorF("cr5a = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x5d); - ErrorF("cr5d = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x5e); - ErrorF("cr5e = 0x%x\n", inb(vgaCRReg)); - - outb(vgaCRIndex, 0x60); - ErrorF("cr60 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x61); - ErrorF("cr61 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x62); - ErrorF("cr62 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x65); - ErrorF("cr65 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x66); - ErrorF("cr66 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x67); - ErrorF("cr67 = 0x%x\n", inb(vgaCRReg)); - outb(vgaCRIndex, 0x6d); - ErrorF("cr6d = 0x%x\n", inb(vgaCRReg)); - -#else { int j; @@ -2005,8 +2030,6 @@ void S3Regdump(ScrnInfoPtr pScrn) ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg)); } } -#endif - #if 0 ErrorF("DAC regs\n"); diff --git a/src/s3_shadow.c b/src/s3_shadow.c new file mode 100644 index 0000000..1273765 --- /dev/null +++ b/src/s3_shadow.c @@ -0,0 +1,274 @@ +/* +Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the XFree86 Project shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the XFree86 Project. +*/ + +/* + Copyright (c) 1999,2000 The XFree86 Project Inc. + based on code written by Mark Vojkovich <markv@valinux.com> +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "shadowfb.h" +#include "servermd.h" +#include "s3.h" + + +void +S3RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + S3Ptr pS3 = S3PTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel); + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = pS3->ShadowPtr + (pbox->y1 * pS3->ShadowPitch) + + (pbox->x1 * Bpp); + dst = pS3->FBBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += pS3->ShadowPitch; + } + + pbox++; + } +} + +void +S3PointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + S3Ptr pS3 = S3PTR(pScrn); + int newX, newY; + + if(pS3->rotate == 1) { + newX = pScrn->pScreen->height - y - 1; + newY = x; + } else { + newX = y; + newY = pScrn->pScreen->width - x - 1; + } + + (*pS3->PointerMoved)(index, newX, newY); +} + +void +S3RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + S3Ptr pS3 = S3PTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pS3->rotate * pS3->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* in dwords */ + + if(pS3->rotate == 1) { + dstPtr = pS3->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = pS3->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 8) | + (src[srcPitch * 2] << 16) | + (src[srcPitch * 3] << 24); + src += srcPitch * 4; + } + srcPtr += pS3->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +void +S3RefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + S3Ptr pS3 = S3PTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD16 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pS3->rotate * pS3->ShadowPitch >> 1; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~1; + y2 = (pbox->y2 + 1) & ~1; + height = (y2 - y1) >> 1; /* in dwords */ + + if(pS3->rotate == 1) { + dstPtr = (CARD16*)pS3->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - y2; + srcPtr = (CARD16*)pS3->ShadowPtr + + ((1 - y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD16*)pS3->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + y1; + srcPtr = (CARD16*)pS3->ShadowPtr + + (y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + *(dst++) = src[0] | (src[srcPitch] << 16); + src += srcPitch * 2; + } + srcPtr += pS3->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} + + +/* this one could be faster */ +void +S3RefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + S3Ptr pS3 = S3PTR(pScrn); + int count, width, height, y1, y2, dstPitch, srcPitch; + CARD8 *dstPtr, *srcPtr, *src; + CARD32 *dst; + + dstPitch = BitmapBytePad(pScrn->displayWidth * 24); + srcPitch = -pS3->rotate * pS3->ShadowPitch; + + while(num--) { + width = pbox->x2 - pbox->x1; + y1 = pbox->y1 & ~3; + y2 = (pbox->y2 + 3) & ~3; + height = (y2 - y1) >> 2; /* blocks of 3 dwords */ + + if(pS3->rotate == 1) { + dstPtr = pS3->FBBase + + (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3); + srcPtr = pS3->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3); + } else { + dstPtr = pS3->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3); + srcPtr = pS3->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3; + } + + while(width--) { + src = srcPtr; + dst = (CARD32*)dstPtr; + count = height; + while(count--) { + dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) | + (src[srcPitch] << 24); + dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) | + (src[srcPitch * 2] << 16) | + (src[(srcPitch * 2) + 1] << 24); + dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) | + (src[(srcPitch * 3) + 1] << 16) | + (src[(srcPitch * 3) + 2] << 24); + dst += 3; + src += srcPitch * 4; + } + srcPtr += pS3->rotate * 3; + dstPtr += dstPitch; + } + + pbox++; + } +} + +void +S3RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + S3Ptr pS3 = S3PTR(pScrn); + int count, width, height, dstPitch, srcPitch; + CARD32 *dstPtr, *srcPtr, *src, *dst; + + dstPitch = pScrn->displayWidth; + srcPitch = -pS3->rotate * pS3->ShadowPitch >> 2; + + while(num--) { + width = pbox->x2 - pbox->x1; + height = pbox->y2 - pbox->y1; + + if(pS3->rotate == 1) { + dstPtr = (CARD32*)pS3->FBBase + + (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2; + srcPtr = (CARD32*)pS3->ShadowPtr + + ((1 - pbox->y2) * srcPitch) + pbox->x1; + } else { + dstPtr = (CARD32*)pS3->FBBase + + ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1; + srcPtr = (CARD32*)pS3->ShadowPtr + + (pbox->y1 * srcPitch) + pbox->x2 - 1; + } + + while(width--) { + src = srcPtr; + dst = dstPtr; + count = height; + while(count--) { + *(dst++) = *src; + src += srcPitch; + } + srcPtr += pS3->rotate; + dstPtr += dstPitch; + } + + pbox++; + } +} |