summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mga.h35
-rw-r--r--src/mga_video.c181
2 files changed, 167 insertions, 49 deletions
diff --git a/src/mga.h b/src/mga.h
index a59e450..62f8042 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -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);