summaryrefslogtreecommitdiff
path: root/src/ast_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast_driver.c')
-rw-r--r--src/ast_driver.c129
1 files changed, 115 insertions, 14 deletions
diff --git a/src/ast_driver.c b/src/ast_driver.c
index 09972b5..e0dd4fa 100644
--- a/src/ast_driver.c
+++ b/src/ast_driver.c
@@ -166,19 +166,21 @@ typedef enum {
OPTION_ENG_CAPS,
OPTION_DBG_SELECT,
OPTION_NO_DDC,
- OPTION_VGA2_CLONE
+ OPTION_VGA2_CLONE,
+ OPTION_SHADOW_FB
} ASTOpts;
static const OptionInfoRec ASTOptions[] = {
- {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
- {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE},
- {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE},
- {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE},
- {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_MMIO2D, "MMIO2D", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_HWC_NUM, "HWCNumber", OPTV_INTEGER, {0}, FALSE},
+ {OPTION_ENG_CAPS, "ENGCaps", OPTV_INTEGER, {0}, FALSE},
{OPTION_DBG_SELECT, "DBGSelect", OPTV_INTEGER, {0}, FALSE},
- {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_NO_DDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_VGA2_CLONE, "VGA2Clone", OPTV_BOOLEAN, {0}, FALSE},
- {-1, NULL, OPTV_NONE, {0}, FALSE}
+ {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
+ {-1, NULL, OPTV_NONE, {0}, FALSE}
};
#ifdef XFree86LOADER
@@ -346,6 +348,43 @@ ASTProbe(DriverPtr drv, int flags)
return foundScreen;
}
+#ifdef Support_ShadowFB
+static void *
+ASTWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
+ CARD32 *size, void *closure)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ ASTPtr pAST = ASTPTR(pScrn);
+ int stride = pScrn->displayWidth * ((pScrn->bitsPerPixel + 1) / 8);
+
+ *size = stride;
+ return ((uint8_t *)pAST->FBVirtualAddr + pScrn->fbOffset + row * stride + offset);
+
+}
+
+static void
+ASTUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ shadowUpdatePacked(pScreen, pBuf);
+}
+
+static Bool
+ASTCreateScreenResources(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ ASTPtr pAST = ASTPTR(pScrn);
+ Bool ret;
+
+ pScreen->CreateScreenResources = pAST->CreateScreenResources;
+ ret = pScreen->CreateScreenResources(pScreen);
+ pScreen->CreateScreenResources = ASTCreateScreenResources;
+ shadowAdd(pScreen, pScreen->GetScreenPixmap(pScreen), pAST->update,
+ pAST->window, 0, 0);
+
+ return ret;
+}
+#endif /* Support_ShadowFB */
+
/*
* ASTPreInit --
*
@@ -776,6 +815,21 @@ ASTPreInit(ScrnInfoPtr pScrn, int flags)
}
#endif
+ /* ShadowFB */
+#ifdef Support_ShadowFB
+ pAST->shadowFB = FALSE;
+ if (pAST->noAccel == TRUE) /* enable shadowFB only noAccel */
+ {
+ if (xf86ReturnOptValBool(pAST->Options, OPTION_SHADOW_FB, TRUE))
+ {
+ if (xf86LoadSubModule(pScrn, "shadow")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using \"Shadow Framebuffer\"\n");
+ pAST->shadowFB = TRUE;
+ }
+ }
+ }
+#endif
+
#ifndef XSERVER_LIBPCIACCESS
/* We won't be using the VGA access after the probe */
xf86SetOperatingState(resVgaIo, pAST->pEnt->index, ResUnusedOpr);
@@ -856,14 +910,35 @@ ASTScreenInit(SCREEN_INIT_ARGS_DECL)
return FALSE;
}
+ /* allocate shadowFB */
+#ifdef Support_ShadowFB
+ pAST->shadowFB_validation = FALSE;
+ if (pAST->shadowFB) {
+ pAST->shadow = calloc(1, pScrn->displayWidth * pScrn->virtualY *
+ ((pScrn->bitsPerPixel + 7) / 8));
+ if (!pAST->shadow) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate shadow buffer\n");
+ }
+ else
+ pAST->shadowFB_validation = TRUE;
+ }
+#endif
+
switch(pScrn->bitsPerPixel) {
case 8:
case 16:
case 32:
- if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi,
- pScrn->displayWidth, pScrn->bitsPerPixel))
+#ifdef Support_ShadowFB
+ if (!fbScreenInit(pScreen, pAST->shadowFB_validation ? pAST->shadow : (pAST->FBVirtualAddr + pScrn->fbOffset),
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel))
+#else
+ if (!fbScreenInit(pScreen, pAST->FBVirtualAddr + pScrn->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->bitsPerPixel))
+#endif
return FALSE;
break;
default:
@@ -886,11 +961,29 @@ ASTScreenInit(SCREEN_INIT_ARGS_DECL)
}
}
+ /* Must be after RGB order fixed */
fbPictureInit(pScreen, 0, 0);
+ /* shadowFB setup */
+#ifdef Support_ShadowFB
+ if (pAST->shadowFB_validation) {
+ pAST->update = ASTUpdatePacked;
+ pAST->window = ASTWindowLinear;
+
+ if (!shadowSetup(pScreen))
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to setup shadow buffer\n");
+ return FALSE;
+ }
+
+ pAST->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = ASTCreateScreenResources;
+ }
+#endif
+
xf86SetBlackWhitePixels(pScreen);
-#ifdef HAVE_XAA_H
+#ifdef HAVE_XAA_H
#ifdef Accel_2D
if (!pAST->noAccel)
{
@@ -1264,6 +1357,14 @@ ASTCloseScreen(CLOSE_SCREEN_ARGS_DECL)
pAST->HWCInfoPtr = NULL;
}
+#ifdef Support_ShadowFB
+ if (pAST->shadowFB_validation) {
+ shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
+ free(pAST->shadow);
+ pScreen->CreateScreenResources = pAST->CreateScreenResources;
+ }
+#endif
+
pScrn->vtSema = FALSE;
pScreen->CloseScreen = pAST->CloseScreen;
return (*pScreen->CloseScreen) (CLOSE_SCREEN_ARGS);
@@ -1423,7 +1524,7 @@ ASTRestore(ScrnInfoPtr pScrn)
/* Restore DAC */
for (i=0; i<256; i++)
VGA_LOAD_PALETTE_INDEX (i, astReg->DAC[i][0], astReg->DAC[i][1], astReg->DAC[i][2]);
-
+
/* fixed Console Switch Refresh Rate Incorrect issue, ycchen@051106 */
for (i=0x81; i<=0xB6; i++)
SetIndexReg(CRTC_PORT, (UCHAR) (i), astReg->ExtCRTC[icount++]);