summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2006-12-27 13:05:12 +0100
committerMichel Dänzer <michel@tungstengraphics.com>2006-12-27 13:08:02 +0100
commit43236f5bfc33f4757dbc5ed9d5682a73c06d8b87 (patch)
tree29213dd05e002dadca185fbebb5d7335ac2db56c /src
parent643573a51fbdcaa4ddb8036956a626f3dce13881 (diff)
downloadxorg-driver-xf86-video-fbdev-43236f5bfc33f4757dbc5ed9d5682a73c06d8b87.tar.gz
Fix shadow framebuffer, and by extension rotation.
Based on Adam Jackson's shadow framebuffer fixes in xf86-video-vesa.
Diffstat (limited to 'src')
-rw-r--r--src/fbdev.c92
1 files changed, 60 insertions, 32 deletions
diff --git a/src/fbdev.c b/src/fbdev.c
index 8955bcc..ca5752c 100644
--- a/src/fbdev.c
+++ b/src/fbdev.c
@@ -63,11 +63,6 @@ static Bool FBDevDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
enum { FBDEV_ROTATE_NONE=0, FBDEV_ROTATE_CW=270, FBDEV_ROTATE_UD=180, FBDEV_ROTATE_CCW=90 };
-/*static ShadowUpdateProc updateFuncs[] =
- { shadowUpdatePacked, shadowUpdateRotate8_270, shadowUpdateRotate8_180, shadowUpdateRotate8_90,
- shadowUpdatePacked, shadowUpdateRotate16_270, shadowUpdateRotate16_180, shadowUpdateRotate16_90,
- shadowUpdatePacked, shadowUpdateRotate32_270, shadowUpdateRotate32_180, shadowUpdateRotate32_90 }; */
-
/* -------------------------------------------------------------------- */
@@ -234,7 +229,9 @@ typedef struct {
int lineLength;
int rotate;
Bool shadowFB;
+ void *shadow;
CloseScreenProcPtr CloseScreen;
+ CreateScreenResourcesProcPtr CreateScreenResources;
void (*PointerMoved)(int index, int x, int y);
EntityInfoPtr pEnt;
/* DGA info */
@@ -613,33 +610,47 @@ FBDevPreInit(ScrnInfoPtr pScrn, int flags)
return TRUE;
}
+
static Bool
-FBDevShadowInit(ScreenPtr pScreen, FBDevPtr fPtr)
+FBDevCreateScreenResources(ScreenPtr pScreen)
{
PixmapPtr pPixmap;
- ShadowUpdateProc update;
- ShadowWindowProc window;
-
- pPixmap = pScreen->CreatePixmap(pScreen, pScreen->width, pScreen->height,
- pScreen->rootDepth);
- if (!pPixmap)
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
+ Bool ret;
+
+ pScreen->CreateScreenResources = fPtr->CreateScreenResources;
+ ret = pScreen->CreateScreenResources(pScreen);
+ pScreen->CreateScreenResources = FBDevCreateScreenResources;
+
+ if (!ret)
+ return FALSE;
+
+ pPixmap = pScreen->GetScreenPixmap(pScreen);
+
+ if (!shadowAdd(pScreen, pPixmap, fPtr->rotate ?
+ shadowUpdateRotatePackedWeak() : shadowUpdatePackedWeak(),
+ FBDevWindowLinear, fPtr->rotate, NULL)) {
return FALSE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+FBDevShadowInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
if (!shadowSetup(pScreen)) {
- pScreen->DestroyPixmap(pPixmap);
return FALSE;
}
- update = fPtr->rotate ? shadowUpdateRotatePackedWeak()
- : shadowUpdatePackedWeak();
+ fPtr->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = FBDevCreateScreenResources;
- if (!shadowAdd(pScreen, pPixmap, update, FBDevWindowLinear,
- fPtr->rotate, NULL)) {
- pScreen->DestroyPixmap(pPixmap);
- return FALSE;
- } else {
- return TRUE;
- }
+ return TRUE;
}
@@ -650,7 +661,7 @@ FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
FBDevPtr fPtr = FBDEVPTR(pScrn);
VisualPtr visual;
int init_picture = 0;
- int ret,flags,width,height;
+ int ret, flags;
int type;
TRACE_ENTER("FBDevScreenInit");
@@ -707,11 +718,9 @@ FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if(fPtr->rotate==FBDEV_ROTATE_CW || fPtr->rotate==FBDEV_ROTATE_CCW)
{
- height = pScrn->virtualX;
- width = pScrn->displayWidth = pScrn->virtualY;
- } else {
- height = pScrn->virtualY;
- width = pScrn->virtualX;
+ int tmp = pScrn->virtualX;
+ pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY;
+ pScrn->virtualY = tmp;
}
if(fPtr->rotate && !fPtr->PointerMoved) {
@@ -721,6 +730,17 @@ FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fPtr->fbstart = fPtr->fbmem + fPtr->fboff;
+ if (fPtr->shadowFB) {
+ fPtr->shadow = xcalloc(1, pScrn->virtualX * pScrn->virtualY *
+ pScrn->bitsPerPixel);
+
+ if (!fPtr->shadow) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate shadow framebuffer\n");
+ return FALSE;
+ }
+ }
+
switch ((type = fbdevHWGetType(pScrn)))
{
#ifdef USE_AFB
@@ -751,8 +771,11 @@ FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
case 16:
case 24:
case 32:
- ret = fbScreenInit(pScreen, fPtr->fbstart, width, height,
- pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel);
+ ret = fbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow
+ : fPtr->fbstart, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi,
+ pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel);
init_picture = 1;
break;
default:
@@ -817,7 +840,7 @@ FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Render extension initialisation failed\n");
- if (fPtr->shadowFB && !FBDevShadowInit(pScreen, fPtr)) {
+ if (fPtr->shadowFB && !FBDevShadowInit(pScreen)) {
xf86DrvMsg(scrnIndex, X_ERROR,
"shadow framebuffer initialization failed\n");
return FALSE;
@@ -920,6 +943,10 @@ FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen)
fbdevHWRestore(pScrn);
fbdevHWUnmapVidmem(pScrn);
+ if (fPtr->shadow) {
+ xfree(fPtr->shadow);
+ fPtr->shadow = NULL;
+ }
if (fPtr->pDGAMode) {
xfree(fPtr->pDGAMode);
fPtr->pDGAMode = NULL;
@@ -927,6 +954,7 @@ FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen)
}
pScrn->vtSema = FALSE;
+ pScreen->CreateScreenResources = fPtr->CreateScreenResources;
pScreen->CloseScreen = fPtr->CloseScreen;
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
}
@@ -952,7 +980,7 @@ FBDevWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
else
*size = fPtr->lineLength = fbdevHWGetLineLength(pScrn);
- return ((CARD8 *)fPtr->fbmem + fPtr->fboff + row * fPtr->lineLength + offset);
+ return ((CARD8 *)fPtr->fbstart + row * fPtr->lineLength + offset);
}
static void