[Intel-gfx] [PATCH] Xv: free tearing on textured video
Xiang, Haihao
haihao.xiang at intel.com
Tue Mar 3 03:27:51 CET 2009
> > >
> > > -#define NUM_TEXTURED_ATTRIBUTES 2
> > > +#define NUM_TEXTURED_ATTRIBUTES 3
> > > static XF86AttributeRec TexturedAttributes[NUM_ATTRIBUTES] = {
> > > {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
> > > {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
> > > + {XvSettable | XvGettable, -1, 1, "XV_VSYNC"},
> > > };
> >
> > Maybe I'm being dense, but shouldn't the size of the
> > TexturedAttributes array be NUM_TEXTURED_ATTRIBUTES instead of
> > NUM_ATTRIBUTES? I'd imagine you would have received "warning: excess
> > elements in array initializer" when building.
> > NUM_TEXTURED_ATTRIBUTES
> NUM_ATTRIBUTES is 5, so it is right. Of course
> TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] is more readable.
>
Here are some updates:
1. add the manual for XV_VSYNC.
2. change the size of TexturedAttributes to NUM_TEXTURED_ATTRIBUTES.
3. use the condition the Xv image is more than quarter of the pixels on the screen for auto sync.
Usually a normal window(such as mplayer) is less than half of the screen if connecting a wide monitor.
Add an Xv attribute XV_VSYNC which has three values -1 (off), 0 (auto)
and 1 (on) to control whether textured adapter synchronizes the screen
update to the vblank. The default value is 0.
---
man/intel.man | 15 ++++++++
src/i810_reg.h | 4 ++
src/i830_video.c | 98 +++++++++++++++++++++++++++++++++++++++++++----------
src/i830_video.h | 2 +
4 files changed, 100 insertions(+), 19 deletions(-)
diff --git a/man/intel.man b/man/intel.man
index c7a3c61..6d9ce52 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -408,6 +408,21 @@ builtin laptop screen, both running at 1024x768.
.BI " Option \*qmonitor-VGA\*q \*qSome Random CRT\*q"
.B "EndSection"
+.SH TEXTURED VIDEO ATTRIBUTES
+The driver supports the following X11 Xv attributes for Textured Video.
+You can use the "xvattr" tool to query/set those attributes at runtime.
+
+.SS "XV_VSYNC"
+XV_VSYNC is used to control whether textured adapter synchronizes the screen
+update to the vblank to eliminate tearing. It has three values 'off'(-1), 'on'(1)
+and 'auto'(0). 'off' means never sync, 'on' means always sync, no matter what
+size, and 'auto' means sync if the Xv image is more than quarter of the pixels
+on the screen. The default is 'auto'.
+
+.SS "XV_BRIGHTNESS"
+
+.SS "XV_CONTRAST"
+
.SH REPORTING BUGS
The xf86-video-intel driver is part of the X.Org and Freedesktop.org
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 51970c1..3114b42 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2436,7 +2436,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Wait for Events */
#define MI_WAIT_FOR_EVENT (0x03<<23)
+#define MI_WAIT_FOR_PIPEB_SVBLANK (1<<18)
+#define MI_WAIT_FOR_PIPEA_SVBLANK (1<<17)
#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16)
+#define MI_WAIT_FOR_PIPEB_VBLANK (1<<7)
+#define MI_WAIT_FOR_PIPEA_VBLANK (1<<3)
/* Flush */
#define MI_FLUSH (0x04<<23)
diff --git a/src/i830_video.c b/src/i830_video.c
index cdb1072..5f77334 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -117,6 +117,7 @@ static int I830QueryImageAttributesTextured(ScrnInfoPtr, int, unsigned short *,
static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer;
static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
+static Atom xvVsync;
/* Limits for the overlay/textured video source sizes. The documented hardware
* limits are 2048x2048 or better for overlay and both of our textured video
@@ -247,10 +248,11 @@ static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
{XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
};
-#define NUM_TEXTURED_ATTRIBUTES 2
-static XF86AttributeRec TexturedAttributes[NUM_ATTRIBUTES] = {
+#define NUM_TEXTURED_ATTRIBUTES 3
+static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
{XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
{XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
+ {XvSettable | XvGettable, -1, 1, "XV_VSYNC"},
};
#define GAMMA_ATTRIBUTES 6
@@ -1021,6 +1023,7 @@ I830SetupImageVideoTextured(ScreenPtr pScreen)
pPriv->doubleBuffer = 0;
pPriv->rotation = RR_Rotate_0;
+ pPriv->xvsync = 0;
/* gotta uninit this someplace, XXX: shouldn't be necessary for textured */
REGION_NULL(pScreen, &pPriv->clip);
@@ -1028,6 +1031,8 @@ I830SetupImageVideoTextured(ScreenPtr pScreen)
adapt->pPortPrivates[i].ptr = (pointer) (pPriv);
}
+ xvVsync = MAKE_ATOM("XV_VSYNC");
+
return adapt;
}
@@ -1108,6 +1113,12 @@ I830SetPortAttributeTextured(ScrnInfoPtr pScrn,
return BadValue;
pPriv->contrast = value;
return Success;
+ } else if (attribute == xvVsync) {
+ if ((value < -1) || (value > 1))
+ return BadValue;
+
+ pPriv->xvsync = value;
+ return Success;
} else {
return BadMatch;
}
@@ -1243,7 +1254,9 @@ I830GetPortAttribute(ScrnInfoPtr pScrn,
*value = pPriv->colorKey;
} else if (attribute == xvDoubleBuffer) {
*value = pPriv->doubleBuffer;
- } else
+ } else if (attribute == xvVsync) {
+ *value = pPriv->xvsync;
+ } else
return BadMatch;
return Success;
@@ -2139,6 +2152,7 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
static Bool
i830_clip_video_helper (ScrnInfoPtr pScrn,
+ I830PortPrivPtr pPriv,
xf86CrtcPtr *crtc_ret,
BoxPtr dst,
INT32 *xa,
@@ -2160,7 +2174,6 @@ i830_clip_video_helper (ScrnInfoPtr pScrn,
if (crtc_ret)
{
I830Ptr pI830 = I830PTR(pScrn);
- I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
BoxRec crtc_box;
xf86CrtcPtr crtc = i830_covering_crtc (pScrn, dst,
pPriv->desired_crtc,
@@ -2303,7 +2316,8 @@ I830PutImage(ScrnInfoPtr pScrn,
dstBox.y2 = drw_y + drw_h;
if (!i830_clip_video_helper(pScrn,
- pPriv->textured ? NULL : &crtc,
+ pPriv,
+ &crtc,
&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
width, height))
return Success;
@@ -2541,22 +2555,68 @@ I830PutImage(ScrnInfoPtr pScrn,
REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
i830_fill_colorkey (pScreen, pPriv->colorKey, clipBoxes);
}
- } else if (IS_I965G(pI830)) {
+ } else {
+ Bool sync = TRUE;
+
+ if (pPriv->xvsync == -1) {
+ sync = FALSE;
+ } else if (pPriv->xvsync == 0) {
+ BoxRec crtc_box;
+ BoxPtr pbox;
+ int nbox, crtc_area, coverage = 0;
+
+ i830_crtc_box(crtc, &crtc_box);
+ crtc_area = i830_box_area(&crtc_box);
+ pbox = REGION_RECTS(clipBoxes);
+ nbox = REGION_NUM_RECTS(clipBoxes);
+
+ while (nbox--) {
+ coverage += i830_box_area(pbox);
+ pbox++;
+ }
+
+ if ((coverage << 2) < crtc_area)
+ sync = FALSE;
+ }
+
+ if (sync) {
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int event;
+
+ if (IS_I965G(pI830)) {
+ if (intel_crtc->pipe == 0)
+ event = MI_WAIT_FOR_PIPEA_SVBLANK;
+ else
+ event = MI_WAIT_FOR_PIPEB_SVBLANK;
+ } else {
+ if (intel_crtc->pipe == 0)
+ event = MI_WAIT_FOR_PIPEA_VBLANK;
+ else
+ event = MI_WAIT_FOR_PIPEB_VBLANK;
+ }
+
+ BEGIN_BATCH(2);
+ OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+ OUT_BATCH(MI_NOOP);
+ ADVANCE_BATCH();
+ }
+ if (IS_I965G(pI830)) {
#ifdef INTEL_XVMC
- if (id == FOURCC_XVMC && pPriv->rotation == RR_Rotate_0) {
- pPriv->YBuf0offset = buf - pI830->FbBase;
- pPriv->UBuf0offset = pPriv->YBuf0offset + height*width;
- pPriv->VBuf0offset = pPriv->UBuf0offset + height*width/4;
- }
+ if (id == FOURCC_XVMC && pPriv->rotation == RR_Rotate_0) {
+ pPriv->YBuf0offset = buf - pI830->FbBase;
+ pPriv->UBuf0offset = pPriv->YBuf0offset + height*width;
+ pPriv->VBuf0offset = pPriv->UBuf0offset + height*width/4;
+ }
#endif
- I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
- dstPitch, x1, y1, x2, y2,
- src_w, src_h, drw_w, drw_h, pPixmap);
- } else {
- I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
- dstPitch, dstPitch2, x1, y1, x2, y2,
- src_w, src_h, drw_w, drw_h, pPixmap);
+ I965DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+ dstPitch, x1, y1, x2, y2,
+ src_w, src_h, drw_w, drw_h, pPixmap);
+ } else {
+ I915DisplayVideoTextured(pScrn, pPriv, destId, clipBoxes, width, height,
+ dstPitch, dstPitch2, x1, y1, x2, y2,
+ src_w, src_h, drw_w, drw_h, pPixmap);
+ }
}
if (pPriv->textured) {
DamageDamageRegion(pDraw, clipBoxes);
@@ -2867,7 +2927,7 @@ I830DisplaySurface(XF86SurfacePtr surface,
dstBox.y1 = drw_y;
dstBox.y2 = drw_y + drw_h;
- if (!i830_clip_video_helper (pScrn, &crtc, &dstBox,
+ if (!i830_clip_video_helper (pScrn, pI830Priv, &crtc, &dstBox,
&x1, &x2, &y1, &y2, clipBoxes,
surface->width, surface->height))
return Success;
diff --git a/src/i830_video.h b/src/i830_video.h
index 254ee32..b47ac90 100644
--- a/src/i830_video.h
+++ b/src/i830_video.h
@@ -65,6 +65,8 @@ typedef struct {
int scaleRatio;
Bool textured;
Rotation rotation; /* should remove I830->rotation later*/
+
+ int xvsync; /* -1: off, 0: auto, 1: on */
} I830PortPrivRec, *I830PortPrivPtr;
#define GET_PORT_PRIVATE(pScrn) \
--
1.5.6.3
More information about the Intel-gfx
mailing list