diff options
author | Dave Airlie <airlied@redhat.com> | 2011-09-29 15:55:36 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-09-29 15:56:15 +0100 |
commit | bb848a788f8dae6f54eb2c03eb2046066732e6e8 (patch) | |
tree | 670153639d44045adedc809d6f86e353709bd83c | |
parent | f699c4dc6fd2a34555045950d75ba287723a1e06 (diff) |
add shadowfb support, default to on.
we should probably expose a bit from kernel to say if shadow is preferred
or wasteful.
-rw-r--r-- | src/driver.c | 62 | ||||
-rw-r--r-- | src/driver.h | 2 |
2 files changed, 64 insertions, 0 deletions
diff --git a/src/driver.c b/src/driver.c index 1192878..bde690c 100644 --- a/src/driver.c +++ b/src/driver.c @@ -49,6 +49,7 @@ #include "xf86Crtc.h" #include "miscstruct.h" #include "dixstruct.h" +#include "shadow.h" #include "xf86xv.h" #include <X11/extensions/Xv.h> #include <xorg-server.h> @@ -110,11 +111,13 @@ typedef enum { OPTION_SW_CURSOR, OPTION_DEVICE_PATH, + OPTION_SHADOW_FB, } modesettingOpts; static const OptionInfoRec Options[] = { {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_DEVICE_PATH, "kmsdev", OPTV_STRING, {0}, FALSE }, + {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, {-1, NULL, OPTV_NONE, {0}, FALSE} }; @@ -472,6 +475,8 @@ PreInit(ScrnInfoPtr pScrn, int flags) ms->SWCursor = TRUE; } + ms->shadow_enable = xf86ReturnOptValBool(ms->Options, OPTION_SHADOW_FB, TRUE); + ms->drmmode.fd = ms->fd; if (drmmode_pre_init(pScrn, &ms->drmmode, pScrn->bitsPerPixel / 8) == FALSE) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "KMS setup failed\n"); @@ -504,11 +509,31 @@ PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } + if (ms->shadow_enable) { + if (!xf86LoadSubModule(pScrn, "shadow")) { + return FALSE; + } + } + return TRUE; fail: return FALSE; } +static void * +msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode, + CARD32 *size, void *closure) +{ + ScrnInfoPtr pScrn = xf86Screens[screen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + int stride; + + stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8; + *size = stride; + + return ((uint8_t *)ms->drmmode.front_bo->ptr + row * stride + offset); +} + static Bool CreateScreenResources(ScreenPtr pScreen) { @@ -532,9 +557,19 @@ CreateScreenResources(ScreenPtr pScreen) return FALSE; rootPixmap = pScreen->GetScreenPixmap(pScreen); + + if (ms->shadow_enable) + pixels = ms->shadow_fb; + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) FatalError("Couldn't adjust screen pixmap\n"); + if (ms->shadow_enable) { + if (!shadowAdd(pScreen, rootPixmap, shadowUpdatePackedWeak(), + msShadowWindow, 0, 0)) + return FALSE; + } + ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, rootPixmap); @@ -551,6 +586,15 @@ CreateScreenResources(ScreenPtr pScreen) } static Bool +msShadowInit(ScreenPtr pScreen) +{ + if (!shadowSetup(pScreen)) { + return FALSE; + } + return TRUE; +} + +static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -571,6 +615,13 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!drmmode_create_initial_bos(pScrn, &ms->drmmode)) return FALSE; + if (ms->shadow_enable) { + ms->shadow_fb = calloc(1, pScrn->displayWidth * pScrn->virtualY * + ((pScrn->bitsPerPixel + 7) >> 3)); + if (!ms->shadow_fb) + ms->shadow_enable = FALSE; + } + miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, @@ -607,6 +658,12 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) fbPictureInit(pScreen, NULL, 0); + if (ms->shadow_enable && !msShadowInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "shadow fb init failed\n"); + return FALSE; + } + ms->createScreenResources = pScreen->CreateScreenResources; pScreen->CreateScreenResources = CreateScreenResources; @@ -715,6 +772,11 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen) ms->damage = NULL; } + if (ms->shadow_enable) { + shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen)); + free(ms->shadow_fb); + ms->shadow_fb = NULL; + } drmmode_uevent_fini(pScrn, &ms->drmmode); drmmode_free_bos(pScrn, &ms->drmmode); diff --git a/src/driver.h b/src/driver.h index beb5f8d..494ca0c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -76,6 +76,8 @@ typedef struct _modesettingRec DamagePtr damage; Bool dirty_enabled; + Bool shadow_enable; + void *shadow_fb; } modesettingRec, *modesettingPtr; #define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) |