diff options
author | Jordan Crouse <jordan@cosmicpenguin.net> | 2008-11-18 15:41:58 -0700 |
---|---|---|
committer | Jordan Crouse <jordan@cosmicpenguin.net> | 2008-11-18 15:44:13 -0700 |
commit | cf0655edbcbd3910c12c33d8c786cc72c0242786 (patch) | |
tree | d6572761ffb7be4eb6b6dda814d4160890e8b91a | |
parent | ee23fd75f5eb4447ca238694cc03fcdc219ee245 (diff) |
LX: Change the way EXA memory is allocated
Change how EXA memory is allocated to better allow for
EXA + video + rotation to co-exist on the system. Change
the video to only allocate memory when it needs it.
Also, automatically disable compression when there is less then
16Mb of memory.
-rw-r--r-- | src/lx_driver.c | 14 | ||||
-rw-r--r-- | src/lx_memory.c | 29 | ||||
-rw-r--r-- | src/lx_video.c | 37 |
3 files changed, 57 insertions, 23 deletions
diff --git a/src/lx_driver.c b/src/lx_driver.c index 2ee6a1a..bbc6992 100644 --- a/src/lx_driver.c +++ b/src/lx_driver.c @@ -526,6 +526,18 @@ LXPreInit(ScrnInfoPtr pScrni, int flags) pGeode->FBAvail = pScrni->videoRam << 10; } + /* If we have <= 16Mb of memory then compression is going + to hurt - so warn and disable */ + + if (pGeode->tryCompression && + pGeode->FBAvail <= 0x1000000) { + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "%x bytes of video memory is less then optimal\n", pGeode->FBAvail); + xf86DrvMsg(pScrni->scrnIndex, X_INFO, + "when compression is on. Disabling compression.\n"); + pGeode->tryCompression = FALSE; + } + /* Carve out some memory for the command buffer */ pGeode->CmdBfrSize = CIM_CMD_BFR_SZ; @@ -598,8 +610,6 @@ LXRestore(ScrnInfoPtr pScrni) static Bool LXUnmapMem(ScrnInfoPtr pScrni) { - GeodeRec *pGeode = GEODEPTR(pScrni); - #ifndef XSERVER_LIBPCIACCESS xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_gp_ptr, LX_GP_REG_SIZE); xf86UnMapVidMem(pScrni->scrnIndex, (pointer) cim_vg_ptr, LX_VG_REG_SIZE); diff --git a/src/lx_memory.c b/src/lx_memory.c index 9964c8e..41adba5 100644 --- a/src/lx_memory.c +++ b/src/lx_memory.c @@ -48,7 +48,8 @@ GeodeOffscreenFreeSize(GeodeRec * pGeode) return pGeode->offscreenSize; for (; ptr->next; ptr = ptr->next) ; - return pGeode->offscreenSize - (ptr->offset + ptr->size); + return (pGeode->offscreenStart + pGeode->offscreenSize) + - (ptr->offset + ptr->size); } void @@ -235,16 +236,28 @@ LXInitOffscreen(ScrnInfoPtr pScrni) pGeode->pExa->offScreenBase = 0; pGeode->pExa->memorySize = 0; - /* In a break from the previous behavior, we will - * allocate 3 screens worth of offscreen memory. - * (that means, 3 * y * (x * bpp) - not the compressed - * pitch if it is enabled). */ + /* This might cause complaints - in order to avoid using + xorg.conf as much as possible, we make assumptions about + what a "default" memory map would look like. After + discussion, we agreed that the default driver should assume + the user will want to use rotation and video overlays, and + EXA will get whatever is leftover. + */ - /* FIXME: Make this configurable */ + /* Get the amount of offscreen memory still left */ + size = GeodeOffscreenFreeSize(pGeode); - size = 3 * (pScrni->virtualY * - ((pScrni->virtualX + 3) & ~3) * (pScrni->bitsPerPixel >> 3)); + /* 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; + + /* Allocate the EXA offscreen space */ ptr = GeodeAllocOffscreen(pGeode, size, 4); if (ptr == NULL) { diff --git a/src/lx_video.c b/src/lx_video.c index d41bb50..01ccba7 100644 --- a/src/lx_video.c +++ b/src/lx_video.c @@ -189,6 +189,24 @@ struct /* Copy planar YUV data */ static Bool +LXAllocMem(GeodeRec *pGeode, GeodePortPrivRec *pPriv, int size) +{ + if (!pPriv->vidmem || pPriv->vidmem->size < size) { + if (pPriv->vidmem) + GeodeFreeOffscreen(pGeode, pPriv->vidmem); + + pPriv->vidmem = GeodeAllocOffscreen(pGeode, size, 4); + + if (pPriv->vidmem == NULL) { + ErrorF("Could not allocate memory for the video\n"); + return FALSE; + } + } + + return TRUE; +} + +static Bool LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, short x1, short y1, short x2, short y2, int width, int height, pointer data) @@ -219,12 +237,8 @@ LXCopyPlanar(ScrnInfoPtr pScrni, int id, unsigned char *buf, size = YDstPitch * height; size += UVDstPitch * height; - pPriv->vidmem = GeodeAllocOffscreen(pGeode, size, 4); - - if (pPriv->vidmem == NULL) { - ErrorF("Could not allocate memory for the video\n"); + if (LXAllocMem(pGeode, pPriv, size) == FALSE) return FALSE; - } /* The top of the source region we want to copy */ top = y1 & ~1; @@ -284,12 +298,8 @@ LXCopyPacked(ScrnInfoPtr pScrni, int id, unsigned char *buf, lines = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; - pPriv->vidmem = GeodeAllocOffscreen(pGeode, lines, 4); - - if (pPriv->vidmem == NULL) { - ErrorF("Error while allocating an offscreen region.\n"); + if (LXAllocMem(pGeode, pPriv, lines) == FALSE) return FALSE; - } /* The top of the source region we want to copy */ top = y1; @@ -485,14 +495,14 @@ LXPutImage(ScrnInfoPtr pScrni, if (id == FOURCC_YV12 || id == FOURCC_I420) ret = LXCopyPlanar(pScrni, id, buf, x1, y1, x2, y2, width, - height, data); + height, data); else ret = LXCopyPacked(pScrni, id, buf, x1, y1, x2, y2, width, - height, data); + height, data); if (ret == FALSE) return BadAlloc; - + if (!RegionsEqual(&pPriv->clip, clipBoxes) || (drawW != pPriv->pwidth || drawH != pPriv->pheight)) { REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); @@ -705,6 +715,7 @@ LXSetupImageVideo(ScreenPtr pScrn) /* Use the common function */ adapt->QueryImageAttributes = GeodeQueryImageAttributes; + pPriv->vidmem = NULL; pPriv->filter = 0; pPriv->colorKey = 0; pPriv->colorKeyMode = 0; |