[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'debian-unstable'



 debian/changelog      |    2 
 debian/control        |    2 
 src/drmmode_display.c |    9 
 src/i830.h            |    3 
 src/i830_driver.c     |    2 
 src/i830_video.c      | 1505 +++++++++++++++++++++++---------------------------
 src/i830_video.h      |   20 
 src/i915_video.c      |   33 -
 src/i965_video.c      |   48 -
 9 files changed, 748 insertions(+), 876 deletions(-)

New commits:
commit cf2d7aa99f30737dbc15c385fbf6aa43d4f2b5b8
Author: Julien Cristau <jcristau@debian.org>
Date:   Wed Mar 17 20:10:15 2010 +0100

    Bump libdrm-dev build-dep for the kms video overlay changes

diff --git a/debian/changelog b/debian/changelog
index a793d60..473b1d7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,7 @@ xserver-xorg-video-intel (2:2.9.1-3) UNRELEASED; urgency=low
   * Remove myself from Uploaders
   * Add a NEWS.Debian entry about KMS.
   * Backport KMS video overlay from upstream 2.10 (closes: #565328).
+  * Bump libdrm-dev build-dep for the above.
 
  -- Julien Cristau <jcristau@debian.org>  Sat, 16 Jan 2010 16:47:17 +0000
 
diff --git a/debian/control b/debian/control
index e1f558e..40cc39e 100644
--- a/debian/control
+++ b/debian/control
@@ -15,7 +15,7 @@ Build-Depends:
  x11proto-xext-dev,
  x11proto-video-dev,
  libx11-dev,
- libdrm-dev (>= 2.4.11),
+ libdrm-dev (>= 2.4.18-3),
  x11proto-xf86dri-dev,
  x11proto-gl-dev,
  libgl1-mesa-dev | libgl-dev,

commit 2ae5615f76f255e34154953c1dabafc77b14eea4
Author: Julien Cristau <jcristau@debian.org>
Date:   Wed Mar 17 20:00:35 2010 +0100

    Xv: enable drmmode overlay
    
    Essentially the same as commit bd81734465912d79d6320a6fb021ce43d258b906
    but that one doesn't cherry-pick cleanly.

diff --git a/src/i830_video.c b/src/i830_video.c
index a2c9a98..2084131 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -360,7 +360,6 @@ I830SetOneLineModeRatio(ScrnInfoPtr pScrn);
 static Bool
 drmmode_has_overlay(ScrnInfoPtr pScrn)
 {
-#ifdef DRM_MODE_OVERLAY_LANDED
     I830Ptr p830 = I830PTR(pScrn);
     struct drm_i915_getparam gp;
     int has_overlay = 0;
@@ -371,15 +370,11 @@ drmmode_has_overlay(ScrnInfoPtr pScrn)
 			      &gp, sizeof(gp));
 
     return has_overlay ? TRUE : FALSE;
-#else
-    return FALSE;
-#endif
 }
 
 static void
 drmmode_overlay_update_attrs(ScrnInfoPtr pScrn)
 {
-#ifdef DRM_MODE_OVERLAY_LANDED
     I830Ptr p830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
     struct drm_intel_overlay_attrs attrs;
@@ -402,13 +397,11 @@ drmmode_overlay_update_attrs(ScrnInfoPtr pScrn)
 
     if (ret != 0)
 	    OVERLAY_DEBUG("overlay attrs ioctl failed: %i\n", ret);
-#endif
 }
 
 static void
 drmmode_overlay_off(ScrnInfoPtr pScrn)
 {
-#ifdef DRM_MODE_OVERLAY_LANDED
     I830Ptr p830 = I830PTR(pScrn);
     struct drm_intel_overlay_put_image request;
     int ret;
@@ -420,7 +413,6 @@ drmmode_overlay_off(ScrnInfoPtr pScrn)
 
     if (ret != 0)
 	    OVERLAY_DEBUG("overlay switch-off ioctl failed: %i\n", ret);
-#endif
 }
 
 static Bool
@@ -429,7 +421,6 @@ drmmode_overlay_put_image(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
 		   short src_w, short src_h, short drw_w, short drw_h)
 {
-#ifdef DRM_MODE_OVERLAY_LANDED
     I830Ptr p830 = I830PTR(pScrn);
     I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
     struct drm_intel_overlay_put_image request;
@@ -495,9 +486,6 @@ drmmode_overlay_put_image(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 	return FALSE;
     } else
 	return TRUE;
-#else
-    return FALSE;
-#endif
 }
 
 static void

commit 1dceba2603969870ee87ea4b467e454fff6ab18f
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Wed Oct 14 18:09:08 2009 +0200

    Xv overlay: fix planar YUV copy for right rotated crtcs
    
    While copying and rotating the buffer, array access was out of bounds when
    rotated to the right (RR_Rotate_270).  My buffer handling changes probably
    made this bug much more likely to actually result in a SIGSEGV.
    
    I've checked the logs and the bug exists since rotation has been supported,
    i.e.  this looks like a candidate for cherry-picking for all supported
    releases.
    
    Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: Eric Anholt <eric@anholt.net>
    (manually cherry-picked from commit aaedeffe00d9414bb03723dbc30b4938a07ce5fa)

diff --git a/src/i830_video.c b/src/i830_video.c
index 5e98f27..a2c9a98 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -1502,10 +1502,10 @@ I830CopyPackedData(I830PortPrivPtr pPriv,
 	    for (j = 0; j < w; j+=2) {
 		/* Copy U */
 		dst[(((h - i)*2) - 3) + (j * dstPitch)] = src[(j*2) + 1 + (i * srcPitch)];
-		dst[(((h - i)*2) - 3) + ((j - 1) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
+		dst[(((h - i)*2) - 3) + ((j + 1) * dstPitch)] = src[(j*2) + 1 + ((i+1) * srcPitch)];
 		/* Copy V */
 		dst[(((h - i)*2) - 1) + (j * dstPitch)] = src[(j*2) + 3 + (i * srcPitch)];
-		dst[(((h - i)*2) - 1) + ((j - 1) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
+		dst[(((h - i)*2) - 1) + ((j + 1) * dstPitch)] = src[(j*2) + 3 + ((i+1) * srcPitch)];
 	    }
 	}
 	break;

commit 2370af32fe31bed8e5715639023635bdb3b83b1b
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Tue Aug 11 16:06:47 2009 +0200

    Implement drmmode overlay
    
    This does not restore the overlay on EnterVT/disable it on LeaveVT.
    Does not look like this is necessary.
    
    Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    [anholt: Hacked in avoiding the actual kernel calls with
    Signed-off-by: Eric Anholt <eric@anholt.net>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index e8a6c01..00b17dc 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1415,3 +1415,12 @@ drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc)
 
 	return drm_intel_get_pipe_from_crtc_id (bufmgr, drmmode_crtc->mode_crtc->crtc_id);
 }
+
+/* for the drmmode overlay */
+int
+drmmode_crtc_id(xf86CrtcPtr crtc)
+{
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	return drmmode_crtc->mode_crtc->crtc_id;
+}
diff --git a/src/i830.h b/src/i830.h
index 009641a..c84fd0c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -388,7 +388,7 @@ typedef struct _I830Rec {
 
    /* For Xvideo */
    i830_memory *overlay_regs;
-   void *offscreenImages;          /**< remembered memory block for release */
+   Bool use_drmmode_overlay;
 #ifdef INTEL_XVMC
    /* For XvMC */
    Bool XvMCEnabled;
@@ -693,6 +693,7 @@ void I830DRI2CloseScreen(ScreenPtr pScreen);
 extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
 extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
 extern int drmmode_output_dpms_status(xf86OutputPtr output);
+extern int drmmode_crtc_id(xf86CrtcPtr crtc);
 void
 drmmode_crtc_set_cursor_bo(xf86CrtcPtr crtc, dri_bo *cursor);
 
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 316a1fa..585eb81 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -3088,8 +3088,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
    i830_allocator_fini(pScrn);
 
    i965_free_video(pScrn);
-   free(pI830->offscreenImages);
-   pI830->offscreenImages = NULL;
 
    pScreen->CloseScreen = pI830->CloseScreen;
    (*pScreen->CloseScreen) (scrnIndex, pScreen);
diff --git a/src/i830_video.c b/src/i830_video.c
index 80f7303..5e98f27 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -356,6 +356,150 @@ CompareOverlay(I830Ptr pI830, uint32_t * overlay, int size)
 static void
 I830SetOneLineModeRatio(ScrnInfoPtr pScrn);
 
+/* kernel modesetting overlay functions */
+static Bool
+drmmode_has_overlay(ScrnInfoPtr pScrn)
+{
+#ifdef DRM_MODE_OVERLAY_LANDED
+    I830Ptr p830 = I830PTR(pScrn);
+    struct drm_i915_getparam gp;
+    int has_overlay = 0;
+
+    gp.param = I915_PARAM_HAS_OVERLAY;
+    gp.value = &has_overlay;
+    drmCommandWriteRead(p830->drmSubFD, DRM_I915_GETPARAM,
+			      &gp, sizeof(gp));
+
+    return has_overlay ? TRUE : FALSE;
+#else
+    return FALSE;
+#endif
+}
+
+static void
+drmmode_overlay_update_attrs(ScrnInfoPtr pScrn)
+{
+#ifdef DRM_MODE_OVERLAY_LANDED
+    I830Ptr p830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+    struct drm_intel_overlay_attrs attrs;
+    int ret;
+
+    attrs.flags = I915_OVERLAY_UPDATE_ATTRS;
+    attrs.brightness = pPriv->brightness;
+    attrs.contrast = pPriv->contrast;
+    attrs.saturation = pPriv->saturation;
+    attrs.color_key = pPriv->colorKey;
+    attrs.gamma0 = pPriv->gamma0;
+    attrs.gamma1 = pPriv->gamma1;
+    attrs.gamma2 = pPriv->gamma2;
+    attrs.gamma3 = pPriv->gamma3;
+    attrs.gamma4 = pPriv->gamma4;
+    attrs.gamma5 = pPriv->gamma5;
+
+    ret = drmCommandWriteRead(p830->drmSubFD, DRM_I915_OVERLAY_ATTRS,
+			      &attrs, sizeof(attrs));
+
+    if (ret != 0)
+	    OVERLAY_DEBUG("overlay attrs ioctl failed: %i\n", ret);
+#endif
+}
+
+static void
+drmmode_overlay_off(ScrnInfoPtr pScrn)
+{
+#ifdef DRM_MODE_OVERLAY_LANDED
+    I830Ptr p830 = I830PTR(pScrn);
+    struct drm_intel_overlay_put_image request;
+    int ret;
+
+    request.flags = 0;
+
+    ret = drmCommandWrite(p830->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
+			      &request, sizeof(request));
+
+    if (ret != 0)
+	    OVERLAY_DEBUG("overlay switch-off ioctl failed: %i\n", ret);
+#endif
+}
+
+static Bool
+drmmode_overlay_put_image(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
+		   int id, short width, short height,
+		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
+		   short src_w, short src_h, short drw_w, short drw_h)
+{
+#ifdef DRM_MODE_OVERLAY_LANDED
+    I830Ptr p830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+    struct drm_intel_overlay_put_image request;
+    int ret;
+    int planar = is_planar_fourcc(id);
+    float scale;
+
+    request.flags = I915_OVERLAY_ENABLE;
+
+    request.bo_handle = pPriv->buf->handle;
+    if (planar) {
+	    request.stride_Y = dstPitch*2;
+	    request.stride_UV = dstPitch;
+    } else {
+	    request.stride_Y = dstPitch;
+	    request.stride_UV = 0;
+    }
+    request.offset_Y = pPriv->YBufOffset;
+    request.offset_U = pPriv->UBufOffset;
+    request.offset_V = pPriv->VBufOffset;
+    OVERLAY_DEBUG("off_Y: %i, off_U: %i, off_V: %i\n", request.offset_Y,
+		    request.offset_U, request.offset_V);
+
+    request.crtc_id = drmmode_crtc_id(crtc);
+    request.dst_x = dstBox->x1;
+    request.dst_y = dstBox->y1;
+    request.dst_width = dstBox->x2 - dstBox->x1;
+    request.dst_height = dstBox->y2 - dstBox->y1;
+
+    request.src_width = width;
+    request.src_height = height;
+    /* adjust src dimensions */
+    if (request.dst_height > 1) {
+	scale = ((float) request.dst_height - 1) / ((float) drw_h - 1);
+	request.src_scan_height = src_h * scale;
+    } else
+	request.src_scan_height = 1;
+
+    if (request.dst_width > 1) {
+	scale = ((float) request.dst_width - 1) / ((float) drw_w - 1);
+	request.src_scan_width = src_w * scale;
+    } else
+	request.src_scan_width = 1;
+
+    if (planar) {
+	request.flags |= I915_OVERLAY_YUV_PLANAR | I915_OVERLAY_YUV420;
+    } else {
+	request.flags |= I915_OVERLAY_YUV_PACKED | I915_OVERLAY_YUV422;
+	if (id == FOURCC_UYVY)
+	    request.flags |= I915_OVERLAY_Y_SWAP;
+    }
+
+    ret = drmCommandWrite(p830->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
+			      &request, sizeof(request));
+
+    /* drop the newly displaying buffer right away */
+    drm_intel_bo_disable_reuse(pPriv->buf);
+    drm_intel_bo_unreference(pPriv->buf);
+    pPriv->buf = NULL;
+
+    if (ret != 0) {
+	OVERLAY_DEBUG("overlay put-image ioctl failed: %i\n", ret);
+	return FALSE;
+    } else
+	return TRUE;
+#else
+    return FALSE;
+#endif
+}
+
 static void
 i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
 {
@@ -597,15 +741,18 @@ I830InitVideo(ScreenPtr pScreen)
     }
 
     /* Set up overlay video if we can do it at this depth. */
-    if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8 &&
-	!pI830->use_drm_mode && pI830->overlay_regs != NULL)
+    if (!OVERLAY_NOEXIST(pI830) && pScrn->bitsPerPixel != 8)
     {
-	overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
-	if (overlayAdaptor != NULL) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
-	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Failed to set up overlay video\n");
+	pI830->use_drmmode_overlay = drmmode_has_overlay(pScrn);
+	if ((!pI830->use_drm_mode  && pI830->overlay_regs != NULL)
+		|| pI830->use_drmmode_overlay) {
+	    overlayAdaptor = I830SetupImageVideoOverlay(pScreen);
+	    if (overlayAdaptor != NULL) {
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Set up overlay video\n");
+	    } else {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "Failed to set up overlay video\n");
+	    }
 	}
     }
 
@@ -942,9 +1089,12 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
 	xvGamma5 = MAKE_ATOM("XV_GAMMA5");
     }
 
-    /* XXX These two access the overlay regs, dont call with drmmode */
-    I830ResetVideo(pScrn);
-    I830UpdateGamma(pScrn);
+    if (pI830->use_drmmode_overlay)
+	drmmode_overlay_update_attrs(pScrn);
+    else {
+	I830ResetVideo(pScrn);
+	I830UpdateGamma(pScrn);
+    }
 
     return adapt;
 }
@@ -1052,6 +1202,7 @@ static void
 I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 {
     I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    I830Ptr pI830 = I830PTR(pScrn);
 
     if (pPriv->textured)
 	return;
@@ -1062,7 +1213,10 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 
     if (shutdown) {
 	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
-	    ums_overlay_off(pScrn);
+	    if (pI830->use_drmmode_overlay)
+		drmmode_overlay_off(pScrn);
+	    else
+		ums_overlay_off(pScrn);
 	}
 
 	i830_free_video_buffers(pPriv);
@@ -1191,7 +1345,10 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 	OVERLAY_DEBUG("GAMMA\n");
     }
 
-    ums_overlay_update_attrs(pScrn, pPriv);
+    if (pI830->use_drmmode_overlay)
+	drmmode_overlay_update_attrs(pScrn);
+    else
+	ums_overlay_update_attrs(pScrn, pPriv);
 
     if (attribute == xvColorKey)
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
@@ -2108,7 +2265,11 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     if (!crtc)
     {
 	pPriv->current_crtc = NULL;
-	ums_overlay_off(pScrn);
+	if (pI830->use_drmmode_overlay)
+	    drmmode_overlay_off(pScrn);
+	else
+	    ums_overlay_off(pScrn);
+
 	return TRUE;
     }
 
@@ -2126,8 +2287,12 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 	src_h = tmp;
     }
 
-    return ums_overlay_put_image(pScrn, crtc, id, width, height, dstPitch,
-	    x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h);
+    if (pI830->use_drmmode_overlay)
+	return drmmode_overlay_put_image(pScrn, crtc, id, width, height, dstPitch,
+		x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h);
+    else
+	return ums_overlay_put_image(pScrn, crtc, id, width, height, dstPitch,
+		x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h);
 }
 
 static Bool
@@ -2636,7 +2801,10 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout,
 		/* Turn off the overlay */
 		OVERLAY_DEBUG("BLOCKHANDLER\n");
 
-		ums_overlay_off (pScrn);
+		if (pI830->use_drmmode_overlay)
+		    drmmode_overlay_off(pScrn);
+		else
+		    ums_overlay_off (pScrn);
 
 		pPriv->videoStatus = FREE_TIMER;
 		pPriv->freeTime = now + FREE_DELAY;

commit 99230864050ea2f26c2412c4c87c50947fc3cbe1
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Tue Aug 11 16:06:46 2009 +0200

    Xv: introduce an overlay hal
    
    This is the last preparatory step for overlay support with drmmode.
    Safe two (specially marked) function calls in the setup code, all
    hw accessing code goes now through these three new functions with
    the ums_overlay prefix.
    
    Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: Eric Anholt <eric@anholt.net>

diff --git a/src/i830_video.c b/src/i830_video.c
index 15ada0f..80f7303 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -942,8 +942,8 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
 	xvGamma5 = MAKE_ATOM("XV_GAMMA5");
     }
 
+    /* XXX These two access the overlay regs, dont call with drmmode */
     I830ResetVideo(pScrn);
-
     I830UpdateGamma(pScrn);
 
     return adapt;
@@ -1043,6 +1043,12 @@ i830_free_video_buffers(I830PortPrivPtr pPriv)
 }
 
 static void
+ums_overlay_off(ScrnInfoPtr pScrn)
+{
+    i830_overlay_off (pScrn);
+}
+
+static void
 I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 {
     I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
@@ -1056,7 +1062,7 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 
     if (shutdown) {
 	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
-	    i830_overlay_off(pScrn);
+	    ums_overlay_off(pScrn);
 	}
 
 	i830_free_video_buffers(pPriv);
@@ -1089,7 +1095,6 @@ I830SetPortAttributeTextured(ScrnInfoPtr pScrn,
     } else if (attribute == xvSyncToVblank) {
         if ((value < -1) || (value > 1))
             return BadValue;
-        
         pPriv->SyncToVblank = value;
         return Success;
     } else {
@@ -1097,36 +1102,56 @@ I830SetPortAttributeTextured(ScrnInfoPtr pScrn,
     }
 }
 
+static void
+ums_overlay_update_attrs(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830OverlayRegPtr overlay;
+
+    overlay = I830OVERLAYREG(pI830);
+
+    overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
+    overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
+    overlay->OCLRC1 = pPriv->saturation;
+
+    switch (pScrn->depth) {
+    case 16:
+	overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
+	break;
+    case 15:
+	overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
+	break;
+    default:
+	overlay->DCLRKV = pPriv->colorKey;
+	break;
+    }
+
+    I830UpdateGamma(pScrn);
+
+    i830_overlay_continue(pScrn, FALSE);
+}
+
 static int
 I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 		     Atom attribute, INT32 value, pointer data)
 {
     I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
     I830Ptr pI830 = I830PTR(pScrn);
-    I830OverlayRegPtr overlay;
-
-    overlay = I830OVERLAYREG(pI830);
 
     if (attribute == xvBrightness) {
 	if ((value < -128) || (value > 127))
 	    return BadValue;
 	pPriv->brightness = value;
-	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("BRIGHTNESS\n");
-	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvContrast) {
 	if ((value < 0) || (value > 255))
 	    return BadValue;
 	pPriv->contrast = value;
-	overlay->OCLRC0 = (pPriv->contrast << 18) | (pPriv->brightness & 0xff);
 	OVERLAY_DEBUG("CONTRAST\n");
-	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvSaturation) {
 	if ((value < 0) || (value > 1023))
 	    return BadValue;
 	pPriv->saturation = value;
-	overlay->OCLRC1 = pPriv->saturation;
-	i830_overlay_continue (pScrn, FALSE);
     } else if (attribute == xvPipe) {
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 	if ((value < -1) || (value > xf86_config->num_crtc))
@@ -1139,7 +1164,7 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 	 * Leave this to be updated at the next frame
 	 */
     } else if (attribute == xvGamma0 && (IS_I9XX(pI830))) {
-	pPriv->gamma0 = value; 
+	pPriv->gamma0 = value;
     } else if (attribute == xvGamma1 && (IS_I9XX(pI830))) {
 	pPriv->gamma1 = value;
     } else if (attribute == xvGamma2 && (IS_I9XX(pI830))) {
@@ -1152,20 +1177,7 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 	pPriv->gamma5 = value;
     } else if (attribute == xvColorKey) {
 	pPriv->colorKey = value;
-	switch (pScrn->depth) {
-	case 16:
-	    overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey);
-	    break;
-	case 15:
-	    overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey);
-	    break;
-	default:
-	    overlay->DCLRKV = pPriv->colorKey;
-	    break;
-	}
 	OVERLAY_DEBUG("COLORKEY\n");
-	i830_overlay_continue (pScrn, FALSE);
-	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
     } else
 	return BadMatch;
 
@@ -1177,9 +1189,13 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 	 attribute == xvGamma4 ||
 	 attribute == xvGamma5) && (IS_I9XX(pI830))) {
 	OVERLAY_DEBUG("GAMMA\n");
-	I830UpdateGamma(pScrn);
     }
 
+    ums_overlay_update_attrs(pScrn, pPriv);
+
+    if (attribute == xvColorKey)
+	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
+
     return Success;
 }
 
@@ -1964,7 +1980,7 @@ xvmc_passthrough(int id, Rotation rotation)
 }
 
 static Bool
-i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
+ums_overlay_put_image(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 		   int id, short width, short height,
 		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
 		   short src_w, short src_h, short drw_w, short drw_h)
@@ -1974,29 +1990,12 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     I830OverlayRegPtr	overlay = I830OVERLAYREG(pI830);
     int			planar;
     uint32_t		swidth, swidthsw, sheigth;
-    int			tmp;
     Bool		scaleChanged;
     drm_intel_bo	*tmp_buf;
 
-    OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
-		  dstPitch);
-
-#if VIDEO_DEBUG
-    CompareOverlay(pI830, (uint32_t *) overlay, 0x100);
-#endif
-    
-    /*
-     * If the video isn't visible on any CRTC, turn it off
-     */
-    if (!crtc)
-    {
-	pPriv->current_crtc = NULL;
-	i830_overlay_off (pScrn);
-	return TRUE;
-    }
-    
     if (crtc != pPriv->current_crtc)
     {
+	/* this may adjust pPriv->oneLineMode */
 	i830_overlay_switch_to_crtc (pScrn, crtc);
 	if (pPriv->overlayOK) {
 	    pPriv->current_crtc = crtc;
@@ -2007,20 +2006,6 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
     if (!pPriv->overlayOK)
 	return TRUE;
 
-    i830_update_dst_box_to_crtc_coords(pScrn, crtc, dstBox);
-
-    if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	tmp = width;
-	width = height;
-	height = tmp;
-	tmp = drw_w;
-	drw_w = drw_h;
-	drw_h = tmp;
-	tmp = src_w;
-	src_w = src_h;
-	src_h = tmp;
-    }
-
     if (pPriv->oneLineMode) {
 	/* change the coordinates with panel fitting active */
 	dstBox->y1 = (((dstBox->y1 - 1) * pPriv->scaleRatio) >> 16) + 1;
@@ -2101,6 +2086,51 @@ i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
 }
 
 static Bool
+i830_display_overlay(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
+		   int id, short width, short height,
+		   int dstPitch, int x1, int y1, int x2, int y2, BoxPtr dstBox,
+		   short src_w, short src_h, short drw_w, short drw_h)
+{
+    I830Ptr		pI830 = I830PTR(pScrn);
+    I830PortPrivPtr	pPriv = pI830->adaptor->pPortPrivates[0].ptr;
+    int			tmp;
+
+    OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
+		  dstPitch);
+
+#if VIDEO_DEBUG
+    CompareOverlay(pI830, (uint32_t *) overlay, 0x100);
+#endif
+
+    /*
+     * If the video isn't visible on any CRTC, turn it off
+     */
+    if (!crtc)
+    {
+	pPriv->current_crtc = NULL;
+	ums_overlay_off(pScrn);
+	return TRUE;
+    }
+
+    i830_update_dst_box_to_crtc_coords(pScrn, crtc, dstBox);
+
+    if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+	tmp = width;
+	width = height;
+	height = tmp;
+	tmp = drw_w;
+	drw_w = drw_h;
+	drw_h = tmp;
+	tmp = src_w;
+	src_w = src_h;
+	src_h = tmp;
+    }
+
+    return ums_overlay_put_image(pScrn, crtc, id, width, height, dstPitch,
+	    x1, y1, x2, y2, dstBox, src_w, src_h, drw_w, drw_h);
+}
+
+static Bool
 i830_clip_video_helper (ScrnInfoPtr pScrn,
 			I830PortPrivPtr pPriv,
 			xf86CrtcPtr *crtc_ret,
@@ -2606,7 +2636,7 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout,
 		/* Turn off the overlay */
 		OVERLAY_DEBUG("BLOCKHANDLER\n");
 
-		i830_overlay_off (pScrn);
+		ums_overlay_off (pScrn);
 
 		pPriv->videoStatus = FREE_TIMER;
 		pPriv->freeTime = now + FREE_DELAY;

commit bb04e184fdc55325a362ebf291e16a7c112a5f1d
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Tue Aug 11 16:06:45 2009 +0200

    Xv: rework overlay buffer management
    
    The basic idea is to only pin the buffer into the gtt when
    the overlay hw is actually using it. This results in a few changes:
    
    - Unify data copied/buffer handling with textured video. Now offsets
      are always buffer relative and we just use drm_bo_map to access a
      buffer.
    - Implement double buffering using two bo's. This is necessary because
      we can't pin the same buffer to the gtt and map it as normal memory.
    - Kill XV_DOUBLE_BUFFER. With the above changes, overlay video is always
      doubel buffered.
    
    There is still the XvMC passthrough case, which makes the code slightly
    ugly. Unfortunately we can't get at the bo behind this buffer.
    
    Changes since the last review-round:
    - Don't overallocate by a factor of 2.
    - Prevent possible use-after-free issue.
    
    Signed-off-by: Eric Anholt <eric@anholt.net>

diff --git a/src/i830_video.c b/src/i830_video.c
index 8592750..15ada0f 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -103,7 +103,7 @@ static int I830QueryImageAttributes(ScrnInfoPtr, int, unsigned short *,
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
-static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvDoubleBuffer;
+static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe;
 static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
 static Atom xvSyncToVblank;
 
@@ -214,13 +214,12 @@ static XF86AttributeRec CloneAttributes[CLONE_ATTRIBUTES] = {
     {XvSettable | XvGettable, -1, 1, "XV_PIPE"}
 };
 
-#define NUM_ATTRIBUTES 5
+#define NUM_ATTRIBUTES 4
 static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
     {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
     {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
     {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"},
-    {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"},
-    {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}
+    {XvSettable | XvGettable, 0, 1023, "XV_SATURATION"}
 };
 
 #define NUM_TEXTURED_ATTRIBUTES 3
@@ -487,6 +486,8 @@ i830_overlay_continue(ScrnInfoPtr pScrn, Bool update_filter)
     OUT_BATCH(flip_addr);
     ADVANCE_BATCH();
     OVERLAY_DEBUG("overlay_continue\n");
+
+    I830Sync(pScrn);
 }
 
 static void
@@ -895,14 +896,14 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
     pPriv->current_crtc = NULL;
     pPriv->desired_crtc = NULL;
     pPriv->buf = NULL;
-    pPriv->currentBuf = 0;
+    pPriv->oldBuf = NULL;
+    pPriv->oldBuf_pinned = FALSE;
     pPriv->gamma5 = 0xc0c0c0;
     pPriv->gamma4 = 0x808080;
     pPriv->gamma3 = 0x404040;
     pPriv->gamma2 = 0x202020;
     pPriv->gamma1 = 0x101010;
     pPriv->gamma0 = 0x080808;
-    pPriv->doubleBuffer = 1;
 
     pPriv->rotation = RR_Rotate_0;
 
@@ -928,7 +929,6 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
     xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
     xvContrast = MAKE_ATOM("XV_CONTRAST");
     xvSaturation = MAKE_ATOM("XV_SATURATION");
-    xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
 
     /* Allow the pipe to be switched from pipe A to B when in clone mode */
     xvPipe = MAKE_ATOM("XV_PIPE");
@@ -1008,8 +1008,8 @@ I830SetupImageVideoTextured(ScreenPtr pScreen)
 	pPriv->textured = TRUE;
 	pPriv->videoStatus = 0;
 	pPriv->buf = NULL;
-	pPriv->currentBuf = 0;
-	pPriv->doubleBuffer = 0;
+	pPriv->oldBuf = NULL;
+	pPriv->oldBuf_pinned = FALSE;
 
 	pPriv->rotation = RR_Rotate_0;
 	pPriv->SyncToVblank = 1;
@@ -1026,6 +1026,23 @@ I830SetupImageVideoTextured(ScreenPtr pScreen)
 }
 
 static void
+i830_free_video_buffers(I830PortPrivPtr pPriv)
+{
+    if (pPriv->buf) {
+	drm_intel_bo_unreference(pPriv->buf);
+	pPriv->buf = NULL;
+    }
+
+    if (pPriv->oldBuf) {
+	if (pPriv->oldBuf_pinned)
+	    drm_intel_bo_unpin(pPriv->oldBuf);
+	drm_intel_bo_unreference(pPriv->oldBuf);
+	pPriv->oldBuf = NULL;
+	pPriv->oldBuf_pinned = FALSE;
+    }
+}
+
+static void
 I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 {
     I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
@@ -1042,12 +1059,8 @@ I830StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
 	    i830_overlay_off(pScrn);
 	}
 
-	if (pPriv->buf) {
-	    drm_intel_bo_unpin(pPriv->buf);
-	    drm_intel_bo_unreference(pPriv->buf);
-	    pPriv->buf = NULL;
-	    pPriv->videoStatus = 0;
-	}
+	i830_free_video_buffers(pPriv);
+	pPriv->videoStatus = 0;
     } else {
 	if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
 	    pPriv->videoStatus |= OFF_TIMER;
@@ -1153,12 +1166,6 @@ I830SetPortAttributeOverlay(ScrnInfoPtr pScrn,
 	OVERLAY_DEBUG("COLORKEY\n");
 	i830_overlay_continue (pScrn, FALSE);
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
-    } else if(attribute == xvDoubleBuffer) {
-	if ((value < 0) || (value > 1))
-	    return BadValue;
-	/* Do not allow buffer change while playing video */
-	if(!pI830->overlayOn)
-	    pPriv->doubleBuffer = value;
     } else
 	return BadMatch;
 
@@ -1212,8 +1219,6 @@ I830GetPortAttribute(ScrnInfoPtr pScrn,
 	*value = pPriv->gamma5;
     } else if (attribute == xvColorKey) {
 	*value = pPriv->colorKey;
-    } else if (attribute == xvDoubleBuffer) {
-	*value = pPriv->doubleBuffer;
     } else if (attribute == xvSyncToVblank) {
         *value = pPriv->SyncToVblank;
     } else
@@ -1239,12 +1244,11 @@ I830QueryBestSize(ScrnInfoPtr pScrn,
 }
 
 static void
-I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+I830CopyPackedData(I830PortPrivPtr pPriv,
 		   unsigned char *buf,
 		   int srcPitch,
 		   int dstPitch, int top, int left, int h, int w)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     unsigned char *src, *dst, *dst_base;
     int i,j;
     unsigned char *s;
@@ -1257,13 +1261,8 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 
     src = buf + (top * srcPitch) + (left << 1);
 
-    if (pPriv->textured) {
-	drm_intel_bo_map(pPriv->buf, TRUE);
-	dst_base = pPriv->buf->virtual;
-    } else {
-	drm_intel_gem_bo_start_gtt_access(pPriv->buf, TRUE);
-	dst_base = pI830->FbBase;
-    }
+    drm_intel_bo_map(pPriv->buf, TRUE);
+    dst_base = pPriv->buf->virtual;
 
     dst = dst_base + pPriv->YBufOffset;
 
@@ -1339,8 +1338,7 @@ I830CopyPackedData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
 	break;
     }
 
-    if (pPriv->textured)
-	drm_intel_bo_unmap(pPriv->buf);
+    drm_intel_bo_unmap(pPriv->buf);
 }
 
 static void i830_memcpy_plane(unsigned char *dst, unsigned char *src,
@@ -1393,12 +1391,11 @@ static void i830_memcpy_plane(unsigned char *dst, unsigned char *src,
 }
 
 static void
-I830CopyPlanarData(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+I830CopyPlanarData(I830PortPrivPtr pPriv,
 		   unsigned char *buf, int srcPitch,
 		   int srcPitch2, int dstPitch, int srcH, int top, int left,
 		   int h, int w, int id)
 {
-    I830Ptr pI830 = I830PTR(pScrn);
     unsigned char *src1, *src2, *src3, *dst_base, *dst1, *dst2, *dst3;
     int dstPitch2 = dstPitch << 1;
 


Reply to: