summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Crouse <jordan@cosmicpenguin.net>2008-11-18 15:41:58 -0700
committerJordan Crouse <jordan@cosmicpenguin.net>2008-11-18 15:44:13 -0700
commitcf0655edbcbd3910c12c33d8c786cc72c0242786 (patch)
treed6572761ffb7be4eb6b6dda814d4160890e8b91a
parentee23fd75f5eb4447ca238694cc03fcdc219ee245 (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.c14
-rw-r--r--src/lx_memory.c29
-rw-r--r--src/lx_video.c37
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;