Merge remote branch 'vsyrjala/xv_reput'

This commit is contained in:
Keith Packard 2010-12-02 08:39:33 -08:00
commit 3824417335
5 changed files with 179 additions and 111 deletions

View File

@ -498,7 +498,7 @@ typedef struct _confdrirec {
/* These values should be adjusted when new fields are added to ScrnInfoRec */
#define NUM_RESERVED_INTS 16
#define NUM_RESERVED_POINTERS 14
#define NUM_RESERVED_FUNCS 11
#define NUM_RESERVED_FUNCS 10
typedef pointer (*funcPointer)(void);
@ -652,6 +652,7 @@ typedef Bool xf86PMEventProc (int, pmEvent, Bool);
typedef void xf86DPMSSetProc (ScrnInfoPtr, int, int);
typedef void xf86LoadPaletteProc (ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
typedef void xf86SetOverscanProc (ScrnInfoPtr, int);
typedef void xf86ModeSetProc (ScrnInfoPtr);
/*
@ -802,6 +803,7 @@ typedef struct _ScrnInfoRec {
xf86LoadPaletteProc *LoadPalette;
xf86SetOverscanProc *SetOverscan;
xorgDriverFuncProc *DriverFunc;
xf86ModeSetProc *ModeSet;
/*
* This can be used when the minor ABI version is incremented.

View File

@ -104,6 +104,7 @@ static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
static Bool xf86XVEnterVT(int, int);
static void xf86XVLeaveVT(int, int);
static void xf86XVAdjustFrame(int index, int x, int y, int flags);
static void xf86XVModeSet(ScrnInfoPtr pScrn);
/* misc */
@ -287,6 +288,7 @@ xf86XVScreenInit(
ScreenPriv->EnterVT = pScrn->EnterVT;
ScreenPriv->LeaveVT = pScrn->LeaveVT;
ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
ScreenPriv->ModeSet = pScrn->ModeSet;
pScreen->DestroyWindow = xf86XVDestroyWindow;
pScreen->WindowExposures = xf86XVWindowExposures;
@ -295,6 +297,7 @@ xf86XVScreenInit(
pScrn->LeaveVT = xf86XVLeaveVT;
if(pScrn->AdjustFrame)
pScrn->AdjustFrame = xf86XVAdjustFrame;
pScrn->ModeSet = xf86XVModeSet;
if(!xf86XVInitAdaptors(pScreen, adaptors, num))
return FALSE;
@ -556,7 +559,7 @@ xf86XVInitAdaptors(
adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
adaptorPriv->PutImage = adaptorPtr->PutImage;
adaptorPriv->ReputImage = adaptorPtr->ReputImage;
adaptorPriv->ReputImage = adaptorPtr->ReputImage; /* image/still */
pa->devPriv.ptr = (pointer)adaptorPriv;
@ -661,8 +664,7 @@ xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
pCompositeClip = RegionCreate(NullBox, 1);
RegionCopy(pCompositeClip, portPriv->clientClip);
RegionTranslate(pCompositeClip,
portPriv->pDraw->x + portPriv->clipOrg.x,
portPriv->pDraw->y + portPriv->clipOrg.y);
portPriv->pDraw->x, portPriv->pDraw->y);
RegionIntersect(pCompositeClip, pregWin, pCompositeClip);
portPriv->pCompositeClip = pCompositeClip;
@ -687,6 +689,8 @@ xf86XVCopyClip(
portPriv->clientClip = RegionCreate(NullBox, 1);
/* Note: this is in window coordinates */
RegionCopy(portPriv->clientClip, pGC->clientClip);
RegionTranslate(portPriv->clientClip,
pGC->clipOrg.x, pGC->clipOrg.y);
} else if(portPriv->clientClip) { /* free the old clientClip */
RegionDestroy(portPriv->clientClip);
portPriv->clientClip = NULL;
@ -697,7 +701,27 @@ xf86XVCopyClip(
RegionDestroy(portPriv->pCompositeClip);
}
portPriv->clipOrg = pGC->clipOrg;
portPriv->pCompositeClip = pGC->pCompositeClip;
portPriv->FreeCompositeClip = FALSE;
portPriv->subWindowMode = pGC->subWindowMode;
}
static void
xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv,
GCPtr pGC,
DrawablePtr pDraw)
{
if (!portPriv->clientClip)
portPriv->clientClip = RegionCreate(NullBox, 1);
/* Keep the original GC composite clip around for ReputImage */
RegionCopy(portPriv->clientClip, pGC->pCompositeClip);
RegionTranslate(portPriv->clientClip,
-pDraw->x, -pDraw->y);
/* get rid of the old clip list */
if (portPriv->pCompositeClip && portPriv->FreeCompositeClip)
RegionDestroy(portPriv->pCompositeClip);
portPriv->pCompositeClip = pGC->pCompositeClip;
portPriv->FreeCompositeClip = FALSE;
portPriv->subWindowMode = pGC->subWindowMode;
@ -852,6 +876,7 @@ CLIP_VIDEO_BAILOUT:
return ret;
}
/* Reput image/still */
static int
xf86XVReputImage(XvPortRecPrivatePtr portPriv)
{
@ -863,6 +888,11 @@ xf86XVReputImage(XvPortRecPrivatePtr portPriv)
xf86XVUpdateCompositeClip(portPriv);
/* the clip can get smaller over time */
RegionCopy(portPriv->clientClip, portPriv->pCompositeClip);
RegionTranslate(portPriv->clientClip,
-portPriv->pDraw->x, -portPriv->pDraw->y);
/* translate the video region to the screen */
WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
@ -912,7 +942,10 @@ xf86XVReputImage(XvPortRecPrivatePtr portPriv)
}
ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
portPriv->vid_x, portPriv->vid_y,
WinBox.x1, WinBox.y1,
portPriv->vid_w, portPriv->vid_h,
portPriv->drw_w, portPriv->drw_h,
&ClipRegion, portPriv->DevPriv.ptr,
portPriv->pDraw);
@ -1004,6 +1037,71 @@ xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
portPriv->pDraw = NULL;
}
static void
xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,
WindowPtr pWin,
Bool visible)
{
if (!visible) {
if (pPriv->isOn == XV_ON) {
(*pPriv->AdaptorRec->StopVideo)(pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
pPriv->isOn = XV_PENDING;
}
if (!pPriv->type) /* overlaid still/image*/
xf86XVRemovePortFromWindow(pWin, pPriv);
return;
}
switch (pPriv->type) {
case XvInputMask:
xf86XVReputVideo(pPriv);
break;
case XvOutputMask:
xf86XVRegetVideo(pPriv);
break;
default: /* overlaid still/image*/
if (pPriv->AdaptorRec->ReputImage)
xf86XVReputImage(pPriv);
break;
}
}
static void
xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
{
ScreenPtr pScreen = pScrn->pScreen;
XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
XvAdaptorPtr pa;
int c, i;
for (c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
XvPortPtr pPort = pa->pPorts;
for (i = pa->nPorts; i > 0; i--, pPort++) {
XvPortRecPrivatePtr pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
WindowPtr pWin = (WindowPtr)pPriv->pDraw;
Bool visible;
if (pPriv->isOn == XV_OFF || !pWin)
continue;
visible = pWin->visibility == VisibilityUnobscured ||
pWin->visibility == VisibilityPartiallyObscured;
/*
* Stop and remove still/images if
* ReputImage isn't supported.
*/
if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
visible = FALSE;
xf86XVReputOrStopPort(pPriv, pWin, visible);
}
}
}
/**** ScreenRec fields ****/
static Bool
@ -1048,7 +1146,6 @@ xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
ScreenPtr pScreen = pWin->drawable.pScreen;
XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
XF86XVWindowPtr pPrev;
XvPortRecPrivatePtr pPriv;
Bool AreasExposed;
@ -1061,47 +1158,20 @@ xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
/* filter out XClearWindow/Area */
if (!pWin->valdata) return;
pPrev = NULL;
while(WinPriv) {
Bool visible = TRUE;
pPriv = WinPriv->PortRec;
/* Reput anyone with a reput function */
/*
* Stop and remove still/images if areas were exposed and
* ReputImage isn't supported.
*/
if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
visible = !AreasExposed;
switch(pPriv->type) {
case XvInputMask:
xf86XVReputVideo(pPriv);
break;
case XvOutputMask:
xf86XVRegetVideo(pPriv);
break;
default: /* overlaid still/image*/
if (pPriv->AdaptorRec->ReputImage)
xf86XVReputImage(pPriv);
else if(AreasExposed) {
XF86XVWindowPtr tmp;
if (pPriv->isOn == XV_ON) {
(*pPriv->AdaptorRec->StopVideo)(
pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
pPriv->isOn = XV_PENDING;
}
pPriv->pDraw = NULL;
if(!pPrev)
dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
WinPriv->next);
else
pPrev->next = WinPriv->next;
tmp = WinPriv;
WinPriv = WinPriv->next;
free(tmp);
continue;
}
break;
}
pPrev = WinPriv;
WinPriv = WinPriv->next;
xf86XVReputOrStopPort(pPriv, pWin, visible);
}
}
@ -1112,15 +1182,13 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
ScreenPtr pScreen = pWin->drawable.pScreen;
XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
XF86XVWindowPtr tmp, pPrev = NULL;
XvPortRecPrivatePtr pPriv;
Bool visible = (pWin->visibility == VisibilityUnobscured) ||
(pWin->visibility == VisibilityPartiallyObscured);
while(WinPriv) {
pPriv = WinPriv->PortRec;
Bool visible = pWin->visibility == VisibilityUnobscured ||
pWin->visibility == VisibilityPartiallyObscured;
if(!pPriv) goto next;
pPriv = WinPriv->PortRec;
if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
RegionDestroy(pPriv->pCompositeClip);
@ -1131,34 +1199,15 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
(*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
pWin, dx, dy);
/* Stop everything except images, but stop them too if the
window isn't visible. But we only remove the images. */
/*
* Stop and remove still/images if
* ReputImage isn't supported.
*/
if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
visible = FALSE;
if(pPriv->type || !visible) {
if(pPriv->isOn == XV_ON) {
(*pPriv->AdaptorRec->StopVideo)(
pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
pPriv->isOn = XV_PENDING;
}
if(!pPriv->type) { /* overlaid still/image */
pPriv->pDraw = NULL;
if(!pPrev)
dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
WinPriv->next);
else
pPrev->next = WinPriv->next;
tmp = WinPriv;
WinPriv = WinPriv->next;
free(tmp);
continue;
}
}
next:
pPrev = WinPriv;
WinPriv = WinPriv->next;
xf86XVReputOrStopPort(pPriv, pWin, visible);
}
if(ScreenPriv->ClipNotify) {
@ -1195,6 +1244,7 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
pScrn->EnterVT = ScreenPriv->EnterVT;
pScrn->LeaveVT = ScreenPriv->LeaveVT;
pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
pScrn->ModeSet = ScreenPriv->ModeSet;
for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
xf86XVFreeAdaptor(pa);
@ -1287,11 +1337,7 @@ xf86XVAdjustFrame(int index, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[index];
ScreenPtr pScreen = pScrn->pScreen;
XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
WindowPtr pWin;
XvAdaptorPtr pa;
int c, i;
if(ScreenPriv->AdjustFrame) {
pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
@ -1299,39 +1345,29 @@ xf86XVAdjustFrame(int index, int x, int y, int flags)
pScrn->AdjustFrame = xf86XVAdjustFrame;
}
for(c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
XvPortPtr pPort = pa->pPorts;
XvPortRecPrivatePtr pPriv;
xf86XVReputOrStopAllPorts(pScrn);
}
for(i = pa->nPorts; i > 0; i--, pPort++) {
pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
if(!pPriv->type && (pPriv->isOn != XV_OFF)) { /* overlaid still/image */
if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
RegionDestroy(pPriv->pCompositeClip);
pPriv->pCompositeClip = NULL;
pWin = (WindowPtr)pPriv->pDraw;
if ((pPriv->AdaptorRec->ReputImage) &&
((pWin->visibility == VisibilityUnobscured) ||
(pWin->visibility == VisibilityPartiallyObscured)))
static void
xf86XVModeSet(ScrnInfoPtr pScrn)
{
xf86XVReputImage(pPriv);
} else if (pPriv->isOn == XV_ON) {
(*pPriv->AdaptorRec->StopVideo)(
pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
xf86XVRemovePortFromWindow(pWin, pPriv);
pPriv->isOn = XV_PENDING;
continue;
}
}
}
}
ScreenPtr pScreen = pScrn->pScreen;
XF86XVScreenPtr ScreenPriv;
/* Can be called before pScrn->pScreen is set */
if (!pScreen)
return;
ScreenPriv = GET_XF86XV_SCREEN(pScreen);
if (ScreenPriv->ModeSet) {
pScrn->ModeSet = ScreenPriv->ModeSet;
(*pScrn->ModeSet)(pScrn);
pScrn->ModeSet = xf86XVModeSet;
}
xf86XVReputOrStopAllPorts(pScrn);
}
/**** XvAdaptorRec fields ****/
@ -1429,6 +1465,8 @@ xf86XVPutStill(
WinBox.x2 = WinBox.x1 + drw_w;
WinBox.y2 = WinBox.y1 + drw_h;
xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
RegionInit(&WinRegion, &WinBox, 1);
RegionNull(&ClipRegion);
RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip);
@ -1482,6 +1520,8 @@ xf86XVPutStill(
xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
portPriv->isOn = XV_ON;
portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
portPriv->type = 0; /* no mask means it's transient and should
@ -1497,6 +1537,10 @@ PUT_STILL_BAILOUT:
portPriv->isOn = XV_PENDING;
}
/* This clip was copied and only good for one shot */
if(!portPriv->FreeCompositeClip)
portPriv->pCompositeClip = NULL;
RegionUninit(&WinRegion);
RegionUninit(&ClipRegion);
@ -1718,6 +1762,8 @@ xf86XVPutImage(
if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
xf86XVCopyCompositeClip(portPriv, pGC, pDraw);
WinBox.x1 = pDraw->x + drw_x;
WinBox.y1 = pDraw->y + drw_y;
WinBox.x2 = WinBox.x1 + drw_w;
@ -1779,6 +1825,8 @@ xf86XVPutImage(
(portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
portPriv->isOn = XV_ON;
portPriv->vid_x = src_x; portPriv->vid_y = src_y;
portPriv->vid_w = src_w; portPriv->vid_h = src_h;
portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
portPriv->type = 0; /* no mask means it's transient and should
@ -1794,6 +1842,10 @@ PUT_IMAGE_BAILOUT:
portPriv->isOn = XV_PENDING;
}
/* This clip was copied and only good for one shot */
if(!portPriv->FreeCompositeClip)
portPriv->pCompositeClip = NULL;
RegionUninit(&WinRegion);
RegionUninit(&ClipRegion);

View File

@ -36,6 +36,10 @@
#define VIDEO_INVERT_CLIPLIST 0x00000002
#define VIDEO_OVERLAID_IMAGES 0x00000004
#define VIDEO_OVERLAID_STILLS 0x00000008
/*
* Usage of VIDEO_CLIP_TO_VIEWPORT is not recommended.
* It can make reput behaviour inconsistent.
*/
#define VIDEO_CLIP_TO_VIEWPORT 0x00000010
typedef struct {
@ -107,7 +111,9 @@ typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
short src_w, short src_h, short drw_w, short drw_h,
int image, unsigned char* buf, short width, short height, Bool Sync,
RegionPtr clipBoxes, pointer data, DrawablePtr pDraw );
typedef int (* ReputImageFuncPtr)( ScrnInfoPtr pScrn, short drw_x, short drw_y,
typedef int (* ReputImageFuncPtr)( ScrnInfoPtr pScrn,
short src_x, short src_y, short drw_x, short drw_y,
short src_w, short src_h, short drw_w, short drw_h,
RegionPtr clipBoxes, pointer data, DrawablePtr pDraw );
typedef int (*QueryImageAttributesFuncPtr)(ScrnInfoPtr pScrn,
int image, unsigned short *width, unsigned short *height,
@ -165,7 +171,7 @@ typedef struct {
GetPortAttributeFuncPtr GetPortAttribute;
QueryBestSizeFuncPtr QueryBestSize;
PutImageFuncPtr PutImage;
ReputImageFuncPtr ReputImage;
ReputImageFuncPtr ReputImage; /* image/still */
QueryImageAttributesFuncPtr QueryImageAttributes;
ClipNotifyFuncPtr ClipNotify;
} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;

View File

@ -44,6 +44,7 @@ typedef struct {
Bool (*EnterVT)(int, int);
void (*LeaveVT)(int, int);
GCPtr videoGC;
xf86ModeSetProc *ModeSet;
} XF86XVScreenRec, *XF86XVScreenPtr;
typedef struct {
@ -67,7 +68,6 @@ typedef struct {
DrawablePtr pDraw;
unsigned char type;
unsigned int subWindowMode;
DDXPointRec clipOrg;
RegionPtr clientClip;
RegionPtr pCompositeClip;
Bool FreeCompositeClip;

View File

@ -371,6 +371,8 @@ done:
crtc->active = TRUE;
if (scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
if (scrn->ModeSet)
scrn->ModeSet(scrn);
} else {
crtc->x = saved_x;
crtc->y = saved_y;
@ -407,12 +409,16 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
void
xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
{
ScrnInfoPtr scrn = crtc->scrn;
crtc->x = x;
crtc->y = y;
if (crtc->funcs->set_origin) {
if (!xf86CrtcRotate (crtc))
return;
crtc->funcs->set_origin (crtc, x, y);
if (scrn->ModeSet)
scrn->ModeSet(scrn);
}
else
xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
@ -2894,6 +2900,8 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
}
if (pScrn->pScreen)
xf86_crtc_notify(pScrn->pScreen);
if (pScrn->ModeSet)
pScrn->ModeSet(pScrn);
}
#ifdef RANDR_12_INTERFACE