diff options
-rw-r--r-- | src/mga.h | 35 | ||||
-rw-r--r-- | src/mga_video.c | 181 |
2 files changed, 167 insertions, 49 deletions
@@ -193,13 +193,20 @@ typedef struct { int contrast; Bool doubleBuffer; unsigned char currentBuffer; - FBLinearPtr linear; RegionRec clip; CARD32 colorKey; CARD32 videoStatus; Time offTime; Time freeTime; int lastPort; + +#ifdef USE_EXA + int size; + ExaOffscreenArea *off_screen; +#endif + + void *video_memory; + int video_offset; } MGAPortPrivRec, *MGAPortPrivPtr; typedef struct { @@ -705,4 +712,30 @@ void MGAFillDisplayModeStruct(DisplayModePtr pMode, LPMGAMODEINFO pModeInfo); /************************************************/ #endif +static __inline__ void +MGA_MARK_SYNC(MGAPtr pMga, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (pMga->Exa) + exaMarkSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!pMga->Exa) + SET_SYNC_FLAG(pMga->AccelInfoRec); +#endif +} + +static __inline__ void +MGA_SYNC(MGAPtr pMga, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (pMga->Exa) + exaWaitSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->AccelInfoRec->Sync(pScrn); +#endif +} + #endif diff --git a/src/mga_video.c b/src/mga_video.c index 1f0e87d..279d5a3 100644 --- a/src/mga_video.c +++ b/src/mga_video.c @@ -19,7 +19,12 @@ #include "xf86xv.h" #include <X11/extensions/Xv.h> #include "xaa.h" + +#ifdef USE_XAA +#include "xaa.h" #include "xaalocal.h" +#endif + #include "dixstruct.h" #include "fourcc.h" @@ -52,7 +57,7 @@ static int MGAPutImage(ScrnInfoPtr, short, short, short, short, short, short, Bool, RegionPtr, pointer, DrawablePtr); static int MGAQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); - +static void MGAFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); static void MGAResetVideoOverlay(ScrnInfoPtr); @@ -63,6 +68,19 @@ static void MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time); static Atom xvBrightness, xvContrast, xvColorKey, xvDoubleBuffer; +#ifdef USE_EXA +static void +MGAVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = MGAPTR(pScrn); + MGAPortPrivPtr pPriv = pMga->portPrivate; + + if (pPriv->video_memory == area) + pPriv->video_memory = NULL; +} +#endif /* USE_EXA */ + void MGAInitVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -331,9 +349,9 @@ MGAStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if(shutdown) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) OUTREG(MGAREG_BESCTL, 0); - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if (pPriv->video_memory) { + MGAFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; } pPriv->videoStatus = 0; } else { @@ -527,45 +545,109 @@ MGACopyMungedData( } -static FBLinearPtr +static CARD32 MGAAllocateMemory( ScrnInfoPtr pScrn, - FBLinearPtr linear, + void **mem_struct, int size ){ - ScreenPtr pScreen; - FBLinearPtr new_linear; + MGAPtr pMga = MGAPTR(pScrn); + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + int offset = 0; + +#ifdef USE_EXA + if (pMga->Exa) { + ExaOffscreenArea *area = *mem_struct; + + if (area) { + if (area->size >= size) + return area->offset; - if(linear) { - if(linear->size >= size) - return linear; - - if(xf86ResizeOffscreenLinear(linear, size)) - return linear; + exaOffscreenFree(pScrn->pScreen, area); + } + + area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, MGAVideoSave, + NULL); + *mem_struct = area; + + if (!area) + return 0; - xf86FreeOffscreenLinear(linear); + offset = area->offset; } +#endif /* USE_EXA */ +#ifdef USE_XAA + FBLinearPtr linear = *mem_struct; + int cpp = pMga->CurrentLayout.bitsPerPixel / 8; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size + * appropriately. + */ + size = (size + cpp - 1) / cpp; + + if (!pMga->Exa) { + if (linear) { + if (linear->size >= size) + return linear->offset * cpp; - pScreen = screenInfo.screens[pScrn->scrnIndex]; + if (xf86ResizeOffscreenLinear(linear, size)) + return linear->offset * cpp; - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, - NULL, NULL, NULL); + xf86FreeOffscreenLinear(linear); + } - if(!new_linear) { - int max_size; - xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, - PRIORITY_EXTREME); - - if(max_size < size) - return NULL; + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; - xf86PurgeUnlockedOffscreenAreas(pScreen); - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, - NULL, NULL, NULL); + 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; } +#endif /* USE_XAA */ + + return offset; +} + +static void +MGAFreeMemory(ScrnInfoPtr pScrn, void *mem_struct) +{ + MGAPtr pMga = MGAPTR(pScrn); + +#ifdef USE_EXA + if (pMga->Exa) { + ExaOffscreenArea *area = mem_struct; + + if (area) + exaOffscreenFree(pScrn->pScreen, area); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!pMga->Exa) { + FBLinearPtr linear = mem_struct; - return new_linear; + if (linear) + xf86FreeOffscreenLinear(linear); + } +#endif /* USE_XAA */ } static void @@ -740,7 +822,7 @@ MGADisplayVideoTexture( pbox++; } - pMga->AccelInfoRec->NeedToSync = TRUE; + MGA_MARK_SYNC(pMga, pScrn); } static int @@ -808,11 +890,12 @@ MGAPutImage( break; } - if(!(pPriv->linear = MGAAllocateMemory(pScrn, pPriv->linear, - pPriv->doubleBuffer ? (new_size << 1) : new_size))) - { + pPriv->video_offset = MGAAllocateMemory(pScrn, &pPriv->video_memory, + pPriv->doubleBuffer ? + (new_size << 1) : new_size); + if (!pPriv->video_offset) return BadAlloc; - } + pPriv->currentBuffer ^= 1; /* copy data */ @@ -821,7 +904,7 @@ MGAPutImage( npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; left <<= 1; - offset = pPriv->linear->offset * bpp; + offset = pPriv->video_offset * bpp; if(pPriv->doubleBuffer) offset += pPriv->currentBuffer * new_size * bpp; dst_start = pMga->FbStart + offset + left + (top * dstPitch); @@ -949,9 +1032,9 @@ MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time) } } else { /* FREE_TIMER */ if(pPriv->freeTime < time) { - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if (pPriv->video_memory) { + MGAFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; } pPriv->videoStatus = 0; pMga->VideoTimerCallback = NULL; @@ -965,7 +1048,7 @@ MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time) /****************** Offscreen stuff ***************/ typedef struct { - FBLinearPtr linear; + void *surface_memory; Bool isOn; } OffscreenPrivRec, * OffscreenPrivPtr; @@ -977,8 +1060,8 @@ MGAAllocateSurface( unsigned short h, XF86SurfacePtr surface ){ - FBLinearPtr linear; - int pitch, size, bpp; + void *surface_memory = NULL; + int pitch, size, bpp, offset; OffscreenPrivPtr pPriv; if((w > 1024) || (h > 1024)) @@ -989,35 +1072,36 @@ MGAAllocateSurface( bpp = pScrn->bitsPerPixel >> 3; size = ((pitch * h) + bpp - 1) / bpp; - if(!(linear = MGAAllocateMemory(pScrn, NULL, size))) + offset = MGAAllocateMemory(pScrn, &surface_memory, size); + if (!offset) return BadAlloc; surface->width = w; surface->height = h; if(!(surface->pitches = xalloc(sizeof(int)))) { - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } - pPriv->linear = linear; + pPriv->surface_memory = surface_memory; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = linear->offset * bpp; + surface->offsets[0] = offset * bpp; surface->devPrivate.ptr = (pointer)pPriv; return Success; @@ -1044,11 +1128,12 @@ static int MGAFreeSurface( XF86SurfacePtr surface ){ + ScrnInfoPtr pScrn = surface->pScrn; OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) MGAStopSurface(surface); - xf86FreeOffscreenLinear(pPriv->linear); + MGAFreeMemory(pScrn, pPriv->surface_memory); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); |