summaryrefslogtreecommitdiff
path: root/src/mga_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mga_video.c')
-rw-r--r--src/mga_video.c196
1 files changed, 138 insertions, 58 deletions
diff --git a/src/mga_video.c b/src/mga_video.c
index 1f0e87d..30ae6fc 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 new_linear;
+ 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;
+
+ 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
@@ -762,7 +844,7 @@ MGAPutImage(
unsigned char *dst_start;
int new_size, offset, offset2 = 0, offset3 = 0;
int srcPitch, srcPitch2 = 0, dstPitch;
- int top, left, npixels, nlines, bpp;
+ int top, left, npixels, nlines;
BoxRec dstBox;
CARD32 tmp;
@@ -788,10 +870,8 @@ MGAPutImage(
dstBox.y2 -= pScrn->frameY0;
}
- bpp = pScrn->bitsPerPixel >> 3;
-
dstPitch = ((width << 1) + 15) & ~15;
- new_size = ((dstPitch * height) + bpp - 1) / bpp;
+ new_size = dstPitch * height;
switch(id) {
case FOURCC_YV12:
@@ -808,11 +888,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,16 +902,13 @@ MGAPutImage(
npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left;
left <<= 1;
- offset = pPriv->linear->offset * bpp;
+ offset = pPriv->video_offset;
if(pPriv->doubleBuffer)
- offset += pPriv->currentBuffer * new_size * bpp;
+ offset += pPriv->currentBuffer * new_size;
dst_start = pMga->FbStart + offset + left + (top * dstPitch);
- if(pMga->TexturedVideo && pMga->AccelInfoRec->NeedToSync &&
- ((long)data != pPriv->lastPort))
- {
- MGAStormSync(pScrn);
- }
+ if (pMga->TexturedVideo && ((long)data != pPriv->lastPort))
+ MGA_SYNC(pMga, pScrn);
switch(id) {
case FOURCC_YV12:
@@ -949,9 +1027,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 +1043,7 @@ MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time)
/****************** Offscreen stuff ***************/
typedef struct {
- FBLinearPtr linear;
+ void *surface_memory;
Bool isOn;
} OffscreenPrivRec, * OffscreenPrivPtr;
@@ -977,8 +1055,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 +1067,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;
surface->devPrivate.ptr = (pointer)pPriv;
return Success;
@@ -1044,11 +1123,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);