diff options
Diffstat (limited to 'src/savage_video.c')
-rw-r--r-- | src/savage_video.c | 163 |
1 files changed, 138 insertions, 25 deletions
diff --git a/src/savage_video.c b/src/savage_video.c index 65f1ff9..f953787 100644 --- a/src/savage_video.c +++ b/src/savage_video.c @@ -38,6 +38,7 @@ static int SavagePutImage( ScrnInfoPtr, DrawablePtr); static int SavageQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); +static void SavageFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); void SavageResetVideo(ScrnInfoPtr pScrn); @@ -206,13 +207,18 @@ typedef struct { int hue; /* -128 .. 127 */ Bool interpolation; /* on/off */ - FBAreaPtr area; + /*FBAreaPtr area;*/ RegionRec clip; CARD32 colorKey; CARD32 videoStatus; Time offTime; Time freeTime; int lastKnownPitch; + + int size; + void *video_memory; + int video_offset; + } SavagePortPrivRec, *SavagePortPrivPtr; @@ -1005,10 +1011,10 @@ SavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if(shutdown) { /*SavageClipVWindow(pScrn);*/ SavageStreamsOff( pScrn ); - if(pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } + if (pPriv->video_memory != NULL) { + SavageFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; + } pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { @@ -1266,15 +1272,87 @@ SavageCopyPlanarData( } } -static FBAreaPtr +static void +SavageVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; + + if (pPriv->video_memory == area) + pPriv->video_memory = NULL; +} + +static CARD32 SavageAllocateMemory( ScrnInfoPtr pScrn, - FBAreaPtr area, - int numlines + void **mem_struct, + int size ){ - ScreenPtr pScreen; - FBAreaPtr new_area; + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + SavagePtr psav = SAVPTR(pScrn); + int offset = 0; + + if (psav->useEXA) { + ExaOffscreenArea *area = *mem_struct; + + if (area != NULL) { + if (area->size >= size) + return area->offset; + + exaOffscreenFree(pScrn->pScreen, area); + } + + area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SavageVideoSave, + NULL); + *mem_struct = area; + if (area == NULL) + return 0; + offset = area->offset; + } + + if (!psav->useEXA) { + FBLinearPtr linear = *mem_struct; + int cpp = pScrn->bitsPerPixel / 8; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size + * appropriately. + */ + size = (size + cpp - 1) / cpp; + + if (linear) { + if(linear->size >= size) + return linear->offset * cpp; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear->offset * cpp; + xf86FreeOffscreenLinear(linear); + } + + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; + + if (!linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, + PRIORITY_EXTREME); + + if(max_size < size) + return 0; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; + if (!linear) + return 0; + } + offset = linear->offset * cpp; + } +#if 0 if(area) { if((area->box.y2 - area->box.y1) >= numlines) return area; @@ -1306,6 +1384,29 @@ SavageAllocateMemory( } return new_area; +#endif + return offset; +} + +static void +SavageFreeMemory( + ScrnInfoPtr pScrn, + void *mem_struct +){ + SavagePtr psav = SAVPTR(pScrn); + + if (psav->useEXA) { + ExaOffscreenArea *area = mem_struct; + + if (area != NULL) + exaOffscreenFree(pScrn->pScreen, area); + } + if (!psav->useEXA) { + FBLinearPtr linear = mem_struct; + + if (linear != NULL) + xf86FreeOffscreenLinear(linear); + } } static void @@ -1752,7 +1853,7 @@ SavagePutImage( ScreenPtr pScreen = pScrn->pScreen; INT32 x1, x2, y1, y2; unsigned char *dst_start; - int pitch, new_h, offset, offsetV=0, offsetU=0; + int pitch, new_size, offset, offsetV=0, offsetU=0; int srcPitch, srcPitch2=0, dstPitch; int top, left, npixels, nlines; BoxRec dstBox; @@ -1790,7 +1891,8 @@ SavagePutImage( pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; dstPitch = ((width << 1) + 15) & ~15; - new_h = ((dstPitch * height) + pitch - 1) / pitch; + /*new_h = ((dstPitch * height) + pitch - 1) / pitch;*/ + new_size = dstPitch * height; switch(id) { case FOURCC_Y211: /* Y211 */ @@ -1816,8 +1918,12 @@ SavagePutImage( break; } - if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h))) - return BadAlloc; +/* if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h))) + return BadAlloc;*/ + pPriv->video_offset = SavageAllocateMemory(pScrn, &pPriv->video_memory, + new_size); + if (pPriv->video_offset == 0) + return BadAlloc; /* copy data */ top = y1 >> 16; @@ -1825,8 +1931,8 @@ SavagePutImage( npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; left <<= 1; - /*offset = ((pPriv->area->box.y1 * pitch)) + (top * dstPitch);*/ - offset = pPriv->area->box.y1 * psav->lDelta; + offset = (pPriv->video_offset) + (top * dstPitch); + /*offset = pPriv->area->box.y1 * psav->lDelta;*/ dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD)); switch(id) { @@ -1837,8 +1943,7 @@ SavagePutImage( offsetU += tmp; offsetV += tmp; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; - if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv - /*&& (!psav->disableCOB)*/) { + if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) { SavageCopyPlanarDataBCI( pScrn, buf + (top * srcPitch) + (left >> 1), @@ -1938,7 +2043,7 @@ SavageQueryImageAttributes( /****************** Offscreen stuff ***************/ typedef struct { - FBAreaPtr area; + void *surface_memory; Bool isOn; } OffscreenPrivRec, * OffscreenPrivPtr; @@ -1950,8 +2055,9 @@ SavageAllocateSurface( unsigned short h, XF86SurfacePtr surface ){ - FBAreaPtr area; + int offset, size; int pitch, fbpitch, numlines; + void *surface_memory = NULL; OffscreenPrivPtr pPriv; if((w > 1024) || (h > 1024)) @@ -1961,32 +2067,38 @@ SavageAllocateSurface( pitch = ((w << 1) + 15) & ~15; fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + size = pitch * h; - if(!(area = SavageAllocateMemory(pScrn, NULL, numlines))) + offset = SavageAllocateMemory(pScrn, &surface_memory, size); + if (offset == 0) return BadAlloc; surface->width = w; surface->height = h; - if(!(surface->pitches = xalloc(sizeof(int)))) + if(!(surface->pitches = xalloc(sizeof(int)))) { + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; + } if(!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; } - pPriv->area = area; + pPriv->surface_memory = surface_memory; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = area->box.y1 * fbpitch; + surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/ surface->devPrivate.ptr = (pointer)pPriv; return Success; @@ -2014,11 +2126,12 @@ static int SavageFreeSurface( XF86SurfacePtr surface ){ + ScrnInfoPtr pScrn = surface->pScrn; OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) SavageStopSurface(surface); - xf86FreeOffscreenArea(pPriv->area); + SavageFreeMemory(pScrn, pPriv->surface_memory); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); |