From 9ad33dd65a79277ef75a6e95373614852725f5a9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 17 Aug 2007 16:46:48 -0700 Subject: Use i830_memory.c instead of the AA's allocator for XV buffers. This should fix issues with XV being allocated into XAA's tiled pixmap cache and resulting bad rendering. Its also brings us closer to being able to shrink the size of the pixmap cache on XAA, which is of limited utility. --- src/i830.h | 8 +++ src/i830_memory.c | 4 +- src/i830_video.c | 172 +++++++++++++++--------------------------------------- src/i830_video.h | 14 +---- 4 files changed, 57 insertions(+), 141 deletions(-) diff --git a/src/i830.h b/src/i830.h index 1cfcb9ab..6888a9bc 100644 --- a/src/i830.h +++ b/src/i830.h @@ -641,6 +641,14 @@ extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long offset, unsigned long size); +i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, + unsigned long size, unsigned long alignment, + int flags); +i830_memory *i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, + unsigned long size, + unsigned long pitch, + unsigned long alignment, int flags, + enum tile_format tile_format); void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix); void i830_reset_allocations(ScrnInfoPtr pScrn); diff --git a/src/i830_memory.c b/src/i830_memory.c index 15d3a489..d6fa852a 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -515,7 +515,7 @@ i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) * The memory will be bound automatically when the driver is in control of the * VT. */ -static i830_memory * +i830_memory * i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long alignment, int flags) { @@ -544,7 +544,7 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, * some search across all allocation options to fix this, probably, but that * would be another rewrite. */ -static i830_memory * +i830_memory * i830_allocate_memory_tiled(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long pitch, unsigned long alignment, int flags, diff --git a/src/i830_video.c b/src/i830_video.c index b4f9e746..926e1227 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -107,9 +107,6 @@ static int I830QueryImageAttributesTextured(ScrnInfoPtr, int, unsigned short *, static void I830BlockHandler(int, pointer, pointer, pointer); -static void -I830FreeMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear); - #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer; @@ -841,7 +838,7 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen) pPriv->saturation = 128; pPriv->current_crtc = NULL; pPriv->desired_crtc = NULL; - memset(&pPriv->linear, 0, sizeof(pPriv->linear)); + pPriv->buf = NULL; pPriv->currentBuf = 0; pPriv->gamma5 = 0xc0c0c0; pPriv->gamma4 = 0x808080; @@ -955,7 +952,7 @@ I830SetupImageVideoTextured(ScreenPtr pScreen) pPriv->textured = TRUE; pPriv->videoStatus = 0; - memset(&pPriv->linear, 0, sizeof(pPriv->linear)); + pPriv->buf = NULL; pPriv->currentBuf = 0; pPriv->doubleBuffer = 0; @@ -1015,7 +1012,10 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if (pI830->entityPrivate) pI830->entityPrivate->XvInUse = -1; } - I830FreeMemory(pScrn, &pPriv->linear); + /* Sync before freeing the buffer, because the pages will be unbound. + */ + I830Sync(pScrn); + i830_free_memory(pScrn, pPriv->buf); pPriv->videoStatus = 0; } else { if (pPriv->videoStatus & CLIENT_VIDEO_ON) { @@ -2075,112 +2075,6 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc, i830_overlay_continue (pScrn, scaleChanged); } -#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 byte offset of the allocated memory from the start of framebuffer. - */ -static void -I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size, - int align) -{ - ScreenPtr pScreen = pScrn->pScreen; - I830Ptr pI830 = I830PTR(pScrn); - -#ifdef I830_USE_EXA - if (pI830->useEXA) { - if (linear->exa != NULL) { - if (linear->exa->size >= size) - return; - - exaOffscreenFree(pScreen, linear->exa); - linear->offset = 0; - } - - 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) { - /* Converts an offset from XAA's linear allocator to an offset from the - * start of fb. - */ -#define XAA_OFFSET_TO_OFFSET(x) \ - (pI830->front_buffer->offset + (x * pI830->cpp)) - - /* 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; - - if (linear->xaa != NULL) { - if (linear->xaa->size >= size) { - linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset); - return; - } - - if (xf86ResizeOffscreenLinear(linear->xaa, size)) { - linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset); - return; - } - - xf86FreeOffscreenLinear(linear->xaa); - } - - linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align, - NULL, NULL, NULL); - if (linear->xaa == NULL) - return; - - linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset); - } -#endif /* I830_USE_XAA */ -} - -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; -} - static Bool i830_clip_video_helper (ScrnInfoPtr pScrn, xf86CrtcPtr *crtc_ret, @@ -2293,7 +2187,7 @@ I830PutImage(ScrnInfoPtr pScrn, int top, left, npixels, nlines, size; BoxRec dstBox; int pitchAlignMask; - int extraLinear; + int alloc_size, extraLinear; xf86CrtcPtr crtc; if (pPriv->textured) @@ -2410,19 +2304,38 @@ I830PutImage(ScrnInfoPtr pScrn, else extraLinear = 0; - /* size is multiplied by 2 because we have two buffers that are flipping */ - I830AllocateMemory(pScrn, &pPriv->linear, - extraLinear + (pPriv->doubleBuffer ? size * 2 : size), - 16); + alloc_size = size; + if (pPriv->doubleBuffer) + alloc_size *= 2; + alloc_size += extraLinear; + + if (pPriv->buf) { + /* Wait for any previous acceleration to the buffer to have completed. + * When we start using BOs for rendering, we won't have to worry + * because mapping or freeing will take care of it automatically. + */ + I830Sync(pScrn); + } + + /* Free the current buffer if we're going to have to reallocate */ + if (pPriv->buf && pPriv->buf->size < alloc_size) { + i830_free_memory(pScrn, pPriv->buf); + pPriv->buf = NULL; + } - if (pPriv->linear.offset == 0) + if (pPriv->buf == NULL) { + pPriv->buf = i830_allocate_memory(pScrn, "xv buffer", alloc_size, 16, + 0); + } + + if (pPriv->buf == NULL) return BadAlloc; - pPriv->extra_offset = pPriv->linear.offset + + pPriv->extra_offset = pPriv->buf->offset + (pPriv->doubleBuffer ? size * 2 : size); /* fixup pointers */ - pPriv->YBuf0offset = pPriv->linear.offset; + pPriv->YBuf0offset = pPriv->buf->offset; if (pI830->rotation & (RR_Rotate_90 | RR_Rotate_270)) { pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * width); pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * width / 2); @@ -2654,7 +2567,11 @@ I830BlockHandler(int i, } } else { /* FREE_TIMER */ if (pPriv->freeTime < now) { - I830FreeMemory(pScrn, &pPriv->linear); + /* Sync before freeing the buffer, because the pages will be + * unbound. + */ + I830Sync(pScrn); + i830_free_memory(pScrn, pPriv->buf); pPriv->videoStatus = 0; } } @@ -2666,7 +2583,7 @@ I830BlockHandler(int i, ***************************************************************************/ typedef struct { - struct linear_alloc linear; + i830_memory *buf; Bool isOn; } OffscreenPrivRec, *OffscreenPrivPtr; @@ -2711,8 +2628,8 @@ I830AllocateSurface(ScrnInfoPtr pScrn, fbpitch = pI830->cpp * pScrn->displayWidth; size = pitch * h; - I830AllocateMemory(pScrn, &pPriv->linear, size, 16); - if (pPriv->linear.offset == 0) { + pPriv->buf = i830_allocate_memory(pScrn, "xv surface buffer", size, 16, 0); + if (pPriv->buf == NULL) { xfree(surface->pitches); xfree(surface->offsets); xfree(pPriv); @@ -2727,7 +2644,7 @@ I830AllocateSurface(ScrnInfoPtr pScrn, surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = pPriv->linear.offset; + surface->offsets[0] = pPriv->buf->offset; surface->devPrivate.ptr = (pointer) pPriv; memset(pI830->FbBase + surface->offsets[0], 0, size); @@ -2760,10 +2677,13 @@ I830StopSurface(XF86SurfacePtr surface) static int I830FreeSurface(XF86SurfacePtr surface) { + ScrnInfoPtr pScrn = surface->pScrn; OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr; I830StopSurface(surface); - I830FreeMemory(surface->pScrn, &pPriv->linear); + /* Sync before freeing the buffer, because the pages will be unbound. */ + I830Sync(pScrn); + i830_free_memory(surface->pScrn, pPriv->buf); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); diff --git a/src/i830_video.h b/src/i830_video.h index 7e2d1498..23954e15 100644 --- a/src/i830_video.h +++ b/src/i830_video.h @@ -27,18 +27,6 @@ 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; @@ -70,7 +58,7 @@ typedef struct { CARD32 videoStatus; Time offTime; Time freeTime; - struct linear_alloc linear; + i830_memory *buf; /** YUV data buffer */ unsigned int extra_offset; Bool overlayOK; -- cgit v1.2.3