diff options
-rw-r--r-- | src/i830_driver.c | 34 | ||||
-rw-r--r-- | src/i830_memory.c | 397 | ||||
-rw-r--r-- | src/i830_video.c | 199 | ||||
-rw-r--r-- | src/i830_video.h | 15 |
4 files changed, 332 insertions, 313 deletions
diff --git a/src/i830_driver.c b/src/i830_driver.c index d30af07c..e2653c15 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2855,20 +2855,28 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) DPRINTF(PFX, "assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n"); - if (I830IsPrimary(pScrn)) { - if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); - } - - if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, pI830->LinearMem.Offset / pI830->cpp, pI830->LinearMem.Size / pI830->cpp)) - xf86DrvMsg(scrnIndex, X_INFO, - "Using %ld bytes of offscreen memory for linear (offset=0x%lx)\n", pI830->LinearMem.Size, pI830->LinearMem.Offset); + if (!pI830->useEXA) { + if (I830IsPrimary(pScrn)) { + if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } - } else { - if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to init memory manager\n"); + if (pI830->LinearAlloc && + xf86InitFBManagerLinear(pScreen, + pI830->LinearMem.Offset / pI830->cpp, + pI830->LinearMem.Size / pI830->cpp)) + { + xf86DrvMsg(scrnIndex, X_INFO, + "Using %ld bytes of offscreen memory for linear " + "(offset=0x%lx)\n", pI830->LinearMem.Size, + pI830->LinearMem.Offset); + } + } else { + if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to init memory manager\n"); + } } } diff --git a/src/i830_memory.c b/src/i830_memory.c index 7b0c6fe4..b41a73d2 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -602,11 +602,141 @@ GetFreeSpace(ScrnInfoPtr pScrn) return extra; } +/** + * Allocates a framebuffer for a screen. + * + * Used once for each X screen, so once with RandR 1.2 and twice with classic + * dualhead. + * + * \param pScrn ScrnInfoPtr for the screen being allocated + * \param pI830 I830Ptr for the screen being allocated. + * \param FbMemBox + */ +static Bool +I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox, + I830MemRange *FrontBuffer, I830MemPool *StolenPool, + Bool secondary, const int flags) +{ + Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0); + unsigned long minspace, avail, lineSize; + int cacheLines, maxCacheLines; + int verbosity = dryrun ? 4 : 1; + const char *s = dryrun ? "[dryrun] " : ""; + Bool tileable; + int align, alignflags; + long size, alloced, fb_height; + + /* Clear everything first. */ + memset(FbMemBox, 0, sizeof(*FbMemBox)); + memset(FrontBuffer, 0, sizeof(*FrontBuffer)); + FrontBuffer->Key = -1; + + /* We'll allocate the fb such that the root window will fit regardless of + * rotation. + */ + if (pScrn->virtualX > pScrn->virtualY) + fb_height = pScrn->virtualX; + else + fb_height = pScrn->virtualY; + + FbMemBox->x1 = 0; + FbMemBox->x2 = pScrn->displayWidth; + FbMemBox->y1 = 0; + FbMemBox->y2 = fb_height; + + /* Calculate how much framebuffer memory to allocate. For the + * initial allocation, calculate a reasonable minimum. This is + * enough for the virtual screen size, plus some pixmap cache + * space if we're using XAA. + */ + + lineSize = pScrn->displayWidth * pI830->cpp; + minspace = lineSize * pScrn->virtualY; + avail = pScrn->videoRam * 1024; + + if (!pI830->useEXA) { + maxCacheLines = (avail - minspace) / lineSize; + /* This shouldn't happen. */ + if (maxCacheLines < 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Internal Error: " + "maxCacheLines < 0 in I830Allocate2DMemory()\n"); + maxCacheLines = 0; + } + if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY)) + maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY; + + if (pI830->CacheLines >= 0) { + cacheLines = pI830->CacheLines; + } else { +#if 1 + /* Make sure there is enough for two DVD sized YUV buffers */ + cacheLines = (pScrn->depth == 24) ? 256 : 384; + if (pScrn->displayWidth <= 1024) + cacheLines *= 2; +#else + /* + * Make sure there is enough for two DVD sized YUV buffers. + * Make that 1.5MB, which is around what was allocated with + * the old algorithm + */ + cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth; +#endif + } + if (cacheLines > maxCacheLines) + cacheLines = maxCacheLines; + + FbMemBox->y2 += cacheLines; + + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sAllocating at least %d scanlines for pixmap cache\n", + s, cacheLines); + } else { + /* For EXA, we have a separate allocation for the linear allocator which + * also does the pixmap cache. + */ + cacheLines = 0; + } + + tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && + IsTileable(pScrn->displayWidth * pI830->cpp); + if (tileable) { + if (IS_I9XX(pI830)) + align = MB(1); + else + align = KB(512); + alignflags = ALIGN_BOTH_ENDS; + } else { + align = KB(64); + alignflags = 0; + } + + size = lineSize * (fb_height + cacheLines); + size = ROUND_TO_PAGE(size); + xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, + "%sInitial %sframebuffer allocation size: %ld kByte\n", + s, secondary ? "secondary " : "", + size / 1024); + alloced = I830AllocVidMem(pScrn, FrontBuffer, + StolenPool, size, align, + flags | alignflags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "%sframebuffer. Is your VideoRAM set too low?\n", + secondary ? "secondary " : ""); + } + return FALSE; + } + + return TRUE; +} + /* * Allocate memory for 2D operation. This includes the (front) framebuffer, * ring buffer, scratch memory, HW cursor. */ - Bool I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) { @@ -648,8 +778,6 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) pI830->StolenPool.Free.Size); if (flags & ALLOC_INITIAL) { - unsigned long minspace, avail, lineSize; - int cacheLines, maxCacheLines; if (pI830->NeedRingBufferLow) AllocateRingBuffer(pScrn, flags | FORCE_LOW); @@ -660,242 +788,45 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags) I830EntPtr pI830Ent = pI830->entityPrivate; I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2); - /* Clear everything first. */ - memset(&(pI830->FbMemBox2), 0, sizeof(pI830->FbMemBox2)); - memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2)); - pI830->FrontBuffer2.Key = -1; - -#if 1 /* ROTATION */ - pI830->FbMemBox2.x1 = 0; - pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth; - pI830->FbMemBox2.y1 = 0; - if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY) - pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX; - else - pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY; -#else - pI830->FbMemBox2.x1 = 0; - pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth; - pI830->FbMemBox2.y1 = 0; - pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY; -#endif - - /* - * Calculate how much framebuffer memory to allocate. For the - * initial allocation, calculate a reasonable minimum. This is - * enough for the virtual screen size, plus some pixmap cache - * space. - */ - - lineSize = pI830Ent->pScrn_2->displayWidth * pI8302->cpp; - minspace = lineSize * pI830Ent->pScrn_2->virtualY; - avail = pI830Ent->pScrn_2->videoRam * 1024; - maxCacheLines = (avail - minspace) / lineSize; - /* This shouldn't happen. */ - if (maxCacheLines < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); - maxCacheLines = 0; - } - if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY)) - maxCacheLines = MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY; - - if (pI8302->CacheLines >= 0) { - cacheLines = pI8302->CacheLines; - } else { -#if 1 - /* Make sure there is enough for two DVD sized YUV buffers */ - cacheLines = (pI830Ent->pScrn_2->depth == 24) ? 256 : 384; - if (pI830Ent->pScrn_2->displayWidth <= 1024) - cacheLines *= 2; -#else - /* - * Make sure there is enough for two DVD sized YUV buffers. - * Make that 1.5MB, which is around what was allocated with - * the old algorithm - */ - cacheLines = (MB(1) + KB(512)) / pI8302->cpp / pI830Ent->pScrn_2->displayWidth; -#endif - } - if (cacheLines > maxCacheLines) - cacheLines = maxCacheLines; - - pI830->FbMemBox2.y2 += cacheLines; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocating at least %d scanlines for pixmap cache\n", - s, cacheLines); - - tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip && - IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - -#if 1 /* ROTATION */ - if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY) - size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines); - else - size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines); - size = ROUND_TO_PAGE(size); -#else - size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines); - size = ROUND_TO_PAGE(size); -#endif - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sSecondary framebuffer allocation size: %ld kByte\n", s, - size / 1024); - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer2), - &(pI830->StolenPool), size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pI830Ent->pScrn_2->scrnIndex, X_ERROR, - "Failed to allocate secondary framebuffer.\n"); - } - return FALSE; - } - } - - /* Clear everything first. */ - memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox)); - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - -#if 1 /* ROTATION */ - pI830->FbMemBox.x1 = 0; - pI830->FbMemBox.x2 = pScrn->displayWidth; - pI830->FbMemBox.y1 = 0; - if (pScrn->virtualX > pScrn->virtualY) - pI830->FbMemBox.y2 = pScrn->virtualX; - else - pI830->FbMemBox.y2 = pScrn->virtualY; -#else - pI830->FbMemBox.x1 = 0; - pI830->FbMemBox.x2 = pScrn->displayWidth; - pI830->FbMemBox.y1 = 0; - pI830->FbMemBox.y2 = pScrn->virtualY; -#endif - - /* - * Calculate how much framebuffer memory to allocate. For the - * initial allocation, calculate a reasonable minimum. This is - * enough for the virtual screen size, plus some pixmap cache - * space. - */ - - lineSize = pScrn->displayWidth * pI830->cpp; - minspace = lineSize * pScrn->virtualY; - avail = pScrn->videoRam * 1024; - maxCacheLines = (avail - minspace) / lineSize; - /* This shouldn't happen. */ - if (maxCacheLines < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Internal Error: " - "maxCacheLines < 0 in I830Allocate2DMemory()\n"); - maxCacheLines = 0; - } - if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY)) - maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY; - - if (pI830->CacheLines >= 0) { - cacheLines = pI830->CacheLines; - } else { -#if 1 - /* Make sure there is enough for two DVD sized YUV buffers */ - cacheLines = (pScrn->depth == 24) ? 256 : 384; - if (pScrn->displayWidth <= 1024) - cacheLines *= 2; -#else - /* - * Make sure there is enough for two DVD sized YUV buffers. - * Make that 1.5MB, which is around what was allocated with - * the old algorithm - */ - cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth; -#endif - } - if (cacheLines > maxCacheLines) - cacheLines = maxCacheLines; - - pI830->FbMemBox.y2 += cacheLines; - - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sAllocating at least %d scanlines for pixmap cache\n", - s, cacheLines); - - tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip && - IsTileable(pScrn->displayWidth * pI830->cpp); - if (tileable) { - if (IS_I9XX(pI830)) - align = MB(1); - else - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } - -#if 1 /* ROTATION */ - if (pScrn->virtualX > pScrn->virtualY) - size = lineSize * (pScrn->virtualX + cacheLines); - else - size = lineSize * (pScrn->virtualY + cacheLines); - size = ROUND_TO_PAGE(size); -#else - size = lineSize * (pScrn->virtualY + cacheLines); - size = ROUND_TO_PAGE(size); -#endif - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sInitial framebuffer allocation size: %ld kByte\n", s, - size / 1024); - alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer), - &(pI830->StolenPool), size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "framebuffer. Is your VideoRAM set too low ??\n"); + if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302, + &pI830->FbMemBox2, + &pI830->FrontBuffer2, &pI830->StolenPool, + TRUE, flags)) + { + return FALSE; } + } + if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox, + &pI830->FrontBuffer, &pI830->StolenPool, + FALSE, flags)) + { return FALSE; } -#ifdef I830_USE_EXA - size = lineSize * pScrn->virtualY; - size = ROUND_TO_PAGE(size); - if (tileable) { - align = KB(512); - alignflags = ALIGN_BOTH_ENDS; - } else { - align = KB(64); - alignflags = 0; - } +#ifdef I830_USE_EXA + if (pI830->useEXA) { + /* Default EXA to having 3 screens worth of offscreen memory space + * (for pixmaps), plus a double-buffered, 1920x1088 video's worth. + */ + size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY; + size += 1920 * 1088 * 2 * 2; + size = ROUND_TO_PAGE(size); - alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), - &(pI830->StolenPool), size, align, - flags | alignflags | - FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); - if (alloced < size) { - if (!dryrun) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " - "offscreen memory. Not enough VRAM?\n"); + alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen), + &(pI830->StolenPool), size, 1, + flags | + FROM_ANYWHERE | ALLOCATE_AT_BOTTOM); + if (alloced < size) { + if (!dryrun) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate " + "offscreen memory. Not enough VRAM?\n"); + } + return FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of " + "EXA offscreen memory at 0x%lx, size %ld KB\n", + pI830->Offscreen.Start, pI830->Offscreen.Size/1024); } - return FALSE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate " - "offscreen memory at 0x%lx, size %ld KB\n", - pI830->Offscreen.Start, pI830->Offscreen.Size/1024); } #endif } else { diff --git a/src/i830_video.c b/src/i830_video.c index d10fd168..946a447e 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -120,8 +120,8 @@ static int I830QueryImageAttributesTextured(ScrnInfoPtr, int, unsigned short *, static void I830BlockHandler(int, pointer, pointer, pointer); -static FBLinearPtr -I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size); +static void +I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear); #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) @@ -715,7 +715,7 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) pPriv->contrast = 64; pPriv->saturation = 128; pPriv->pipe = 0; /* XXX must choose pipe wisely */ - pPriv->linear = NULL; + memset(&pPriv->linear, 0, sizeof(pPriv->linear)); pPriv->currentBuf = 0; pPriv->gamma5 = 0xc0c0c0; pPriv->gamma4 = 0x808080; @@ -838,7 +838,7 @@ I830SetupImageVideoTextured(ScreenPtr pScreen) pPriv->textured = TRUE; pPriv->videoStatus = 0; - pPriv->linear = NULL; + memset(&pPriv->linear, 0, sizeof(pPriv->linear)); pPriv->currentBuf = 0; pPriv->doubleBuffer = 0; @@ -902,10 +902,7 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; } - if (pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; - } + I830FreeMemory(pScrn, &pPriv->linear); pPriv->videoStatus = 0; } else { if (pPriv->videoStatus & CLIENT_VIDEO_ON) { @@ -2224,9 +2221,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, /* * Use the extra space allocated at the end of the Xv buffer */ - state_base_offset = (pPriv->YBuf0offset + - pPriv->linear->size * pI830->cpp - - BRW_LINEAR_EXTRA); + state_base_offset = pPriv->extra_offset; state_base_offset = ALIGN(state_base_offset, 64); state_base = (char *)(pI830->FbBase + state_base_offset); @@ -2798,44 +2793,119 @@ BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id, #endif } -static FBLinearPtr -I830AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) +#ifdef I830_USE_EXA +static void +I830VideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + struct linear_alloc *linear = area->privData; + + linear->exa = NULL; + linear->offset = 0; +} +#endif /* I830_USE_EXA */ + +/** + * Allocates linear memory using the XFree86 (XAA) or EXA allocator. + * + * \param pPriv adaptor the memory is being allocated for. + * \param size size of the allocation, in bytes. + * \param alignment offset alignment of the allocation, in bytes. + * \return offset of the allocated memory. + */ +static void +I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size, + int align) { - ScreenPtr pScreen; - FBLinearPtr new_linear = NULL; + ScreenPtr pScreen = pScrn->pScreen; + I830Ptr pI830 = I830PTR(pScrn); - if (linear) { - if (linear->size >= size) - return linear; +#ifdef I830_USE_EXA + if (pI830->useEXA) { + if (linear->exa != NULL) { + if (linear->exa->size >= size) + return; - if (xf86ResizeOffscreenLinear(linear, size)) - return linear; + exaOffscreenFree(pScreen, linear->exa); + linear->offset = 0; + } - xf86FreeOffscreenLinear(linear); + linear->exa = exaOffscreenAlloc(pScreen, size, align, TRUE, + I830VideoSave, linear); + if (linear->exa == NULL) + return; + linear->offset = linear->exa->offset; } +#endif /* I830_USE_EXA */ +#ifdef I830_USE_XAA + if (!pI830->useEXA) { + int max_size; - pScreen = screenInfo.screens[pScrn->scrnIndex]; + /* The XFree86 linear allocator operates in units of screen pixels, + * sadly. + */ + size = (size + pI830->cpp - 1) / pI830->cpp; + align = (align + pI830->cpp - 1) / pI830->cpp; - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, - NULL, NULL, NULL); + if (linear->xaa != NULL) { + if (linear->xaa->size >= size) { + linear->offset = linear->xaa->offset * pI830->cpp; + return; + } - if (!new_linear) { - int max_size; + if (xf86ResizeOffscreenLinear(linear->xaa, size)) { + linear->offset = linear->xaa->offset * pI830->cpp; + return; + } + + xf86FreeOffscreenLinear(linear->xaa); + } + + linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, align, + NULL, NULL, NULL); + if (linear->xaa != NULL) { + linear->offset = linear->xaa->offset * pI830->cpp; + return; + } - xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, + xf86QueryLargestOffscreenLinear(pScreen, &max_size, align, PRIORITY_EXTREME); if (max_size < size) { - ErrorF("No memory available\n"); - return NULL; + ErrorF("No memory available\n"); + linear->offset = 0; + return; } xf86PurgeUnlockedOffscreenAreas(pScreen); - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, - NULL, NULL, NULL); + linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, 4, + NULL, NULL, NULL); + linear->offset = linear->xaa->offset * pI830->cpp; } +#endif /* I830_USE_XAA */ +} - return new_linear; +static void +I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear) +{ + I830Ptr pI830 = I830PTR(pScrn); + +#ifdef I830_USE_EXA + if (pI830->useEXA) { + if (linear->exa != NULL) { + exaOffscreenFree(pScrn->pScreen, linear->exa); + linear->exa = NULL; + } + } +#endif /* I830_USE_EXA */ +#ifdef I830_USE_XAA + if (!pI830->useEXA) { + if (linear->xaa != NULL) { + xf86FreeOffscreenLinear(linear->xaa); + linear->xaa = NULL; + } + } +#endif /* I830_USE_XAA */ + linear->offset = 0; } /* @@ -2981,19 +3051,21 @@ I830PutImage(ScrnInfoPtr pScrn, extraLinear = 0; /* size is multiplied by 2 because we have two buffers that are flipping */ - pPriv->linear = I830AllocateMemory(pScrn, pPriv->linear, - (extraLinear + - (pPriv->doubleBuffer ? size * 2 : size)) / - pI830->cpp); + I830AllocateMemory(pScrn, &pPriv->linear, + extraLinear + (pPriv->doubleBuffer ? size * 2 : size), + 16); - if(!pPriv->linear || pPriv->linear->offset < (pScrn->virtualX * pScrn->virtualY)) + if (pPriv->linear.offset == 0) return BadAlloc; + pPriv->extra_offset = pPriv->linear.offset + + pPriv->doubleBuffer ? size * 2 : size; + /* fixup pointers */ #if 0 - pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear->offset * pI830->cpp; + pPriv->YBuf0offset = pScrn->fbOffset + pPriv->linear.offset; #else - pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear->offset * pI830->cpp; + pPriv->YBuf0offset = pI830->FrontBuffer.Start + pPriv->linear.offset; #endif if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); @@ -3236,10 +3308,7 @@ I830BlockHandler(int i, } } else { /* FREE_TIMER */ if (pPriv->freeTime < now) { - if (pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; - } + I830FreeMemory(pScrn, &pPriv->linear); pPriv->videoStatus = 0; } } @@ -3251,7 +3320,7 @@ I830BlockHandler(int i, ***************************************************************************/ typedef struct { - FBLinearPtr linear; + struct linear_alloc linear; Bool isOn; } OffscreenPrivRec, *OffscreenPrivPtr; @@ -3261,8 +3330,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn, unsigned short w, unsigned short h, XF86SurfacePtr surface) { - FBLinearPtr linear; - int pitch, fbpitch, size, bpp; + int pitch, fbpitch, size; OffscreenPrivPtr pPriv; I830Ptr pI830 = I830PTR(pScrn); @@ -3280,41 +3348,40 @@ I830AllocateSurface(ScrnInfoPtr pScrn, if (pI830->rotation != RR_Rotate_0) return BadAlloc; - w = (w + 1) & ~1; - pitch = ((w << 1) + 15) & ~15; - bpp = pScrn->bitsPerPixel >> 3; - fbpitch = bpp * pScrn->displayWidth; - size = ((pitch * h) + bpp - 1) / bpp; - - if (!(linear = I830AllocateMemory(pScrn, NULL, size))) + if (!(surface->pitches = xalloc(sizeof(int)))) return BadAlloc; - - surface->width = w; - surface->height = h; - - if (!(surface->pitches = xalloc(sizeof(int)))) { - xf86FreeOffscreenLinear(linear); - return BadAlloc; - } if (!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); - xf86FreeOffscreenLinear(linear); return BadAlloc; } if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); - xf86FreeOffscreenLinear(linear); return BadAlloc; } - pPriv->linear = linear; + w = (w + 1) & ~1; + pitch = ((w << 1) + 15) & ~15; + fbpitch = pI830->cpp * pScrn->displayWidth; + size = pitch * h; + + I830AllocateMemory(pScrn, &pPriv->linear, size, 16); + if (pPriv->linear.offset == 0) { + xfree(surface->pitches); + xfree(surface->offsets); + xfree(pPriv); + return BadAlloc; + } + + surface->width = w; + surface->height = h; + pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = linear->offset * bpp; + surface->offsets[0] = pPriv->linear.offset; surface->devPrivate.ptr = (pointer) pPriv; #if 0 @@ -3358,7 +3425,7 @@ I830FreeSurface(XF86SurfacePtr surface) if (pPriv->isOn) { I830StopSurface(surface); } - xf86FreeOffscreenLinear(pPriv->linear); + I830FreeMemory(surface->pScrn, &pPriv->linear); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); diff --git a/src/i830_video.h b/src/i830_video.h index 6a09a258..12a5bda2 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -27,6 +27,18 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86.h" #include "xf86_OSproc.h" +/* Ugly mess to support the old XF86 allocator or EXA using the same code. + */ +struct linear_alloc { +#ifdef I830_USE_XAA + FBLinearPtr xaa; +#endif +#ifdef I830_USE_EXA + ExaOffscreenArea *exa; +#endif + unsigned int offset; +}; + typedef struct { CARD32 YBuf0offset; CARD32 UBuf0offset; @@ -57,7 +69,8 @@ typedef struct { CARD32 videoStatus; Time offTime; Time freeTime; - FBLinearPtr linear; + struct linear_alloc linear; + unsigned int extra_offset; Bool overlayOK; int oneLineMode; |