xf86-video-intel: src/i830_video.c

Ian Romanick idr at kemper.freedesktop.org
Thu Jul 2 13:38:26 PDT 2009


 src/i830_video.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

New commits:
commit 74227141923a2f5049592219ab80e8733062a5d9
Author: Barry Scott <barry.scott at onelan.co.uk>
Date:   Tue Jun 23 14:14:50 2009 +0100

    Fix segv for clipped movie window
    
    When playing a movie that is clipped on its left and right edges the Xorg
    server will SEGV sometimes. This is because the intel driver ignores the
    clipping info when it copies the planes out of the XV data.
    
    The check for the optimised copy was wrong to ignore the width required.
    Which leads to too much data being copied by the memcpy. It the source buffer
    happens to end exactly on a page boundary the server will SEGV.
    
    As we reviewed the code we checked the calculation of src1, src2 and src3.
    The patch includes additional comments to make it clear what the elements of
    the calculation are.
    
    This bug exists in git head and we also see it in 2.4.1.
    
    Barry
    
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/src/i830_video.c b/src/i830_video.c
index c295159..573d681 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1399,7 +1399,8 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 
     switch (pPriv->rotation) {
     case RR_Rotate_0:
-	if (srcPitch == dstPitch2)
+       /* optimise for the case of no clipping */
+	if (srcPitch == dstPitch2 && srcPitch == w)
 	    memcpy (dst1, src1, srcPitch * h);
 	else
 	    for (i = 0; i < h; i++) {
@@ -1438,7 +1439,11 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
     }
 
     /* Copy V data for YV12, or U data for I420 */
-    src2 = buf + (srcH * srcPitch) + ((top * srcPitch) >> 2) + (left >> 1);
+    src2 = buf +                            /* start of YUV data */
+                (srcH * srcPitch) +         /* move over Luma plane */
+                ((top * srcPitch) >> 2) +   /* move down from by top lines */
+                    (left >> 1);            /* move left by left pixels */
+
 #if 0
     ErrorF("src2 is %p, offset is %ld\n", src2,
 	   (unsigned long)src2 - (unsigned long)buf);
@@ -1457,7 +1462,8 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 
     switch (pPriv->rotation) {
     case RR_Rotate_0:
-	if (srcPitch2 == dstPitch)
+       /* optimise for the case of no clipping */
+	if (srcPitch2 == dstPitch && srcPitch2 == (w/2))
 	    memcpy (dst2, src2, h/2 * srcPitch2);
 	else
 	    for (i = 0; i < h / 2; i++) {
@@ -1496,8 +1502,11 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
     }
 
     /* Copy U data for YV12, or V data for I420 */
-    src3 = buf + (srcH * srcPitch) + ((srcH >> 1) * srcPitch2) +
-    ((top * srcPitch) >> 2) + (left >> 1);
+    src3 = buf +                            /* start of YUV data */
+                (srcH * srcPitch) +         /* move over Luma plane */
+                ((srcH >> 1) * srcPitch2) + /* move over Chroma plane */
+                ((top * srcPitch) >> 2) +   /* move down from by top lines */
+                    (left >> 1);            /* move left by left pixels */
 #if 0
     ErrorF("src3 is %p, offset is %ld\n", src3,
 	   (unsigned long)src3 - (unsigned long)buf);
@@ -1516,7 +1525,8 @@ I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 
     switch (pPriv->rotation) {
     case RR_Rotate_0:
-	if (srcPitch2 == dstPitch)
+       /* optimise for the case of no clipping */
+	if (srcPitch2 == dstPitch && srcPitch2 == (w/2))
 	    memcpy (dst3, src3, srcPitch2 * h/2);
 	else
 	    for (i = 0; i < h / 2; i++) {


More information about the xorg-commit mailing list