diff options
author | Hunk Cui <Hunk.Cui@amd.com> | 2010-07-12 13:17:18 +0800 |
---|---|---|
committer | Martin-Éric Racine <q-funk@iki.fi> | 2010-08-06 17:35:40 +0300 |
commit | 8a61ef8f9f6b9dac6804754572250e59d80bdf06 (patch) | |
tree | 930f35eec5aa6ba5d1303f235b01ca2daa390652 | |
parent | 2bcbc0b64091218d348ad9f699370e4bfde3948b (diff) |
Fix rotation with newer Xserver versions (exaOffscreenAlloc)
*Del for deduct the probable size of a shadow buffer.
*Use exaOffscreenAlloc allocate the shadow buffer.
*Rotateeddata has to be allocate in offscreen memory range.
*Ubuntu Bugzilla #377929
Signed-off-by: Hunk Cui <Hunk.Cui@amd.com>
-rw-r--r-- | src/geode.h | 2 | ||||
-rw-r--r-- | src/lx_display.c | 46 | ||||
-rw-r--r-- | src/lx_memory.c | 8 |
3 files changed, 44 insertions, 12 deletions
diff --git a/src/geode.h b/src/geode.h index 8fe67b5..ad94a02 100644 --- a/src/geode.h +++ b/src/geode.h @@ -210,6 +210,8 @@ typedef struct _geodeRec int Pitch; /* display FB pitch */ int displaySize; /* The size of the visibile area */ + ExaOffscreenArea *shadowArea; + /* Framebuffer memory */ unsigned char *FBBase; diff --git a/src/lx_display.c b/src/lx_display.c index 856ad95..4f7c4ed 100644 --- a/src/lx_display.c +++ b/src/lx_display.c @@ -363,20 +363,48 @@ lx_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, WRITE_VID32(DF_DISPLAY_CONFIG, dcfg); } + /* Allocates shadow memory, and allocating a new space for Rotatation. + * The size is measured in bytes, and the offset from the beginning + * of card space is returned. + */ + +Bool +LXAllocShadow(ScrnInfoPtr pScrni, int size) +{ + GeodeRec *pGeode = GEODEPTR(pScrni); + + if (pGeode->shadowArea) { + if (pGeode->shadowArea->size != size) { + exaOffscreenFree(pScrni->pScreen, pGeode->shadowArea); + pGeode->shadowArea = NULL; + } + } + + if (pGeode->shadowArea == NULL) { + pGeode->shadowArea = + exaOffscreenAlloc(pScrni->pScreen, size, 4, TRUE, + NULL, NULL); + + if (pGeode->shadowArea == NULL) + return FALSE; + } + + pScrni->fbOffset = pGeode->shadowArea->offset; +} + static void * lx_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) { ScrnInfoPtr pScrni = crtc->scrn; GeodePtr pGeode = GEODEPTR(pScrni); - LXCrtcPrivatePtr lx_crtc = crtc->driver_private; unsigned int rpitch, size; rpitch = pScrni->displayWidth * (pScrni->bitsPerPixel / 8); size = rpitch * height; - lx_crtc->rotate_mem = GeodeAllocOffscreen(pGeode, size, 4); + LXAllocShadow(pScrni, size); /* Allocate shadow memory */ - if (lx_crtc->rotate_mem == NULL) { + if (pGeode->shadowArea->offset == NULL) { xf86DrvMsg(pScrni->scrnIndex, X_ERROR, "Couldn't allocate the shadow memory for rotation\n"); xf86DrvMsg(pScrni->scrnIndex, X_ERROR, @@ -386,8 +414,8 @@ lx_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } - memset(pGeode->FBBase + lx_crtc->rotate_mem->offset, 0, size); - return pGeode->FBBase + lx_crtc->rotate_mem->offset; + memset(pGeode->FBBase + pGeode->shadowArea->offset, 0, size); + return pGeode->FBBase + pGeode->shadowArea->offset; } static PixmapPtr @@ -417,15 +445,17 @@ lx_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rpixmap, void *data) { ScrnInfoPtr pScrni = crtc->scrn; GeodeRec *pGeode = GEODEPTR(pScrni); - LXCrtcPrivatePtr lx_crtc = crtc->driver_private; if (rpixmap) FreeScratchPixmapHeader(rpixmap); + /* Free shadow memory */ if (data) { gp_wait_until_idle(); - GeodeFreeOffscreen(pGeode, lx_crtc->rotate_mem); - lx_crtc->rotate_mem = NULL; + if (pGeode->shadowArea != NULL) { + exaOffscreenFree(pScrni->pScreen, pGeode->shadowArea); + pGeode->shadowArea = NULL; + } } } diff --git a/src/lx_memory.c b/src/lx_memory.c index 3f853d4..2106526 100644 --- a/src/lx_memory.c +++ b/src/lx_memory.c @@ -249,10 +249,6 @@ LXInitOffscreen(ScrnInfoPtr pScrni) /* Deduct the maxmimum size of a video overlay */ size -= 0x200000; - - /* Deduct the probable size of a shadow buffer */ - size -= pScrni->virtualX * - (pScrni->virtualY * (pScrni->bitsPerPixel >> 3)); /* Align the size to a K boundary */ size &= ~1023; @@ -287,6 +283,10 @@ LXInitOffscreen(ScrnInfoPtr pScrni) xf86DrvMsg(pScrni->scrnIndex, X_INFO, " Cursor: 0x%x bytes\n", LX_CURSOR_HW_WIDTH * 4 * LX_CURSOR_HW_HEIGHT); + if (pGeode->exaBfrSz) + xf86DrvMsg(pScrni->scrnIndex, X_INFO, " ExaBfrSz: 0x%x bytes\n", + pGeode->exaBfrSz); + if (pGeode->pExa->offScreenBase) xf86DrvMsg(pScrni->scrnIndex, X_INFO, " EXA: 0x%x bytes\n", (unsigned int)(pGeode->pExa->memorySize - |