xf86-video-intel: 2 commits - src/intel_video.c src/intel_video.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 16 02:49:12 PDT 2010


 src/intel_video.c |  155 +++++++++++++++++++++++++++---------------------------
 src/intel_video.h |    3 -
 2 files changed, 82 insertions(+), 76 deletions(-)

New commits:
commit d48d584a822ae5adae64f6d5f09faa4ac9b8de73
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 15 14:37:59 2010 +0100

    video: Free the buffers immediately after turning off.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_video.c b/src/intel_video.c
index 1fe3a37..197cb79 100644
--- a/src/intel_video.c
+++ b/src/intel_video.c
@@ -78,14 +78,10 @@
 #include "intel_hwmc.h"
 #endif
 
-#define OFF_DELAY 	250	/* milliseconds */
-#define FREE_DELAY 	15000
+#define OFF_DELAY	250	/* milliseconds */
 
-#define OFF_TIMER 	0x01
-#define FREE_TIMER	0x02
-#define CLIENT_VIDEO_ON	0x04
-
-#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
+#define OFF_TIMER	0x01
+#define CLIENT_VIDEO_ON	0x02
 
 static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr);
 static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr);
@@ -1774,28 +1770,13 @@ intel_video_block_handler(intel_screen_private *intel)
 		return;
 
 	adaptor_priv = intel_get_adaptor_private(intel);
-
-	if (adaptor_priv->videoStatus & TIMER_MASK) {
-#if 1
+	if (adaptor_priv->videoStatus & OFF_TIMER) {
 		Time now = currentTime.milliseconds;
-#else
-		UpdateCurrentTime();
-#endif
-		if (adaptor_priv->videoStatus & OFF_TIMER) {
-			if (adaptor_priv->offTime < now) {
-				/* Turn off the overlay */
-				OVERLAY_DEBUG("BLOCKHANDLER\n");
-
-				drmmode_overlay_off(intel);
-
-				adaptor_priv->videoStatus = FREE_TIMER;
-				adaptor_priv->freeTime = now + FREE_DELAY;
-			}
-		} else {	/* FREE_TIMER */
-			if (adaptor_priv->freeTime < now) {
-				intel_free_video_buffers(adaptor_priv);
-				adaptor_priv->videoStatus = 0;
-			}
+		if (adaptor_priv->offTime < now) {
+			/* Turn off the overlay */
+			drmmode_overlay_off(intel);
+			intel_free_video_buffers(adaptor_priv);
+			adaptor_priv->videoStatus = 0;
 		}
 	}
 }
commit 24bdfe0d5eb4e890e9c63bbb4617efaa0768ab7f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jul 15 13:54:04 2010 +0100

    video: Reuse the old buffers.
    
    After passing the new buffer to the kernel, the old buffer is unpinned
    and becomes available for re-use. So keep hold of the old buffer and
    swap after a PutImage. This greatly reduces the amount of CPU time
    consumed by the kernel on behalf of the video overlay -- by only
    allocating two buffers for an entire sequence, we avoid clflushing and
    page allocation on every frame.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/intel_video.c b/src/intel_video.c
index f99cad8..1fe3a37 100644
--- a/src/intel_video.c
+++ b/src/intel_video.c
@@ -53,6 +53,7 @@
 #include <math.h>
 #include <string.h>
 #include <assert.h>
+#include <errno.h>
 
 #include "xf86.h"
 #include "xf86_OSproc.h"
@@ -214,12 +215,15 @@ static Bool drmmode_has_overlay(intel_screen_private *intel)
 {
 	struct drm_i915_getparam gp;
 	int has_overlay = 0;
+	int ret;
 
 	gp.param = I915_PARAM_HAS_OVERLAY;
 	gp.value = &has_overlay;
-	drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, sizeof(gp));
+	do {
+		ret = drmCommandWriteRead(intel->drmSubFD, DRM_I915_GETPARAM, &gp, sizeof(gp));
+	} while (ret == -EINTR);
 
-	return has_overlay ? TRUE : FALSE;
+	return !! has_overlay;
 }
 
 static void drmmode_overlay_update_attrs(intel_screen_private *intel)
@@ -240,11 +244,10 @@ static void drmmode_overlay_update_attrs(intel_screen_private *intel)
 	attrs.gamma4 = adaptor_priv->gamma4;
 	attrs.gamma5 = adaptor_priv->gamma5;
 
-	ret = drmCommandWriteRead(intel->drmSubFD, DRM_I915_OVERLAY_ATTRS,
-				  &attrs, sizeof(attrs));
-
-	if (ret != 0)
-		OVERLAY_DEBUG("overlay attrs ioctl failed: %i\n", ret);
+	do {
+		ret = drmCommandWriteRead(intel->drmSubFD, DRM_I915_OVERLAY_ATTRS,
+					  &attrs, sizeof(attrs));
+	} while (ret == -EINTR);
 }
 
 static void drmmode_overlay_off(intel_screen_private *intel)
@@ -254,11 +257,10 @@ static void drmmode_overlay_off(intel_screen_private *intel)
 
 	request.flags = 0;
 
-	ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
-			      &request, sizeof(request));
-
-	if (ret != 0)
-		OVERLAY_DEBUG("overlay switch-off ioctl failed: %i\n", ret);
+	do {
+		ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
+				      &request, sizeof(request));
+	} while (ret == -EINTR);
 }
 
 static Bool
@@ -274,6 +276,7 @@ drmmode_overlay_put_image(intel_screen_private *intel,
 	int ret;
 	int planar = is_planar_fourcc(id);
 	float scale;
+	dri_bo *tmp;
 
 	request.flags = I915_OVERLAY_ENABLE;
 
@@ -320,19 +323,24 @@ drmmode_overlay_put_image(intel_screen_private *intel,
 			request.flags |= I915_OVERLAY_Y_SWAP;
 	}
 
-	ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
-			      &request, sizeof(request));
+	do {
+		ret = drmCommandWrite(intel->drmSubFD, DRM_I915_OVERLAY_PUT_IMAGE,
+				      &request, sizeof(request));
+	} while (ret == -EINTR);
+	if (ret)
+		return FALSE;
 
-	/* drop the newly displaying buffer right away */
-	drm_intel_bo_disable_reuse(adaptor_priv->buf);
-	drm_intel_bo_unreference(adaptor_priv->buf);
-	adaptor_priv->buf = NULL;
+	if (!adaptor_priv->reusable) {
+		drm_intel_bo_unreference(adaptor_priv->buf);
+		adaptor_priv->buf = NULL;
+		adaptor_priv->reusable = TRUE;
+	}
 
-	if (ret != 0) {
-		OVERLAY_DEBUG("overlay put-image ioctl failed: %i\n", ret);
-		return FALSE;
-	} else
-		return TRUE;
+	tmp = adaptor_priv->old_buf;
+	adaptor_priv->old_buf = adaptor_priv->buf;
+	adaptor_priv->buf = tmp;
+
+	return TRUE;
 }
 
 void I830InitVideo(ScreenPtr screen)
@@ -484,6 +492,7 @@ static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr screen)
 	adaptor_priv->saturation = 146;	/* 128/112 * 128 */
 	adaptor_priv->desired_crtc = NULL;
 	adaptor_priv->buf = NULL;
+	adaptor_priv->old_buf = NULL;
 	adaptor_priv->gamma5 = 0xc0c0c0;
 	adaptor_priv->gamma4 = 0x808080;
 	adaptor_priv->gamma3 = 0x404040;
@@ -585,6 +594,7 @@ static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr screen)
 		adaptor_priv->textured = TRUE;
 		adaptor_priv->videoStatus = 0;
 		adaptor_priv->buf = NULL;
+		adaptor_priv->old_buf = NULL;
 
 		adaptor_priv->rotation = RR_Rotate_0;
 		adaptor_priv->SyncToVblank = 1;
@@ -602,6 +612,12 @@ static XF86VideoAdaptorPtr I830SetupImageVideoTextured(ScreenPtr screen)
 
 static void intel_free_video_buffers(intel_adaptor_private *adaptor_priv)
 {
+	if (adaptor_priv->old_buf) {
+		drm_intel_bo_disable_reuse(adaptor_priv->old_buf);
+		drm_intel_bo_unreference(adaptor_priv->old_buf);
+		adaptor_priv->old_buf = NULL;
+	}
+
 	if (adaptor_priv->buf) {
 		drm_intel_bo_unreference(adaptor_priv->buf);
 		adaptor_priv->buf = NULL;
@@ -784,7 +800,7 @@ I830QueryBestSize(ScrnInfoPtr scrn,
 	*p_h = drw_h;
 }
 
-static void
+static Bool
 I830CopyPackedData(intel_adaptor_private *adaptor_priv,
 		   unsigned char *buf,
 		   int srcPitch, int dstPitch, int top, int left, int h, int w)
@@ -801,7 +817,9 @@ I830CopyPackedData(intel_adaptor_private *adaptor_priv,
 
 	src = buf + (top * srcPitch) + (left << 1);
 
-	drm_intel_bo_map(adaptor_priv->buf, TRUE);
+	if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf))
+		return FALSE;
+
 	dst_base = adaptor_priv->buf->virtual;
 
 	dst = dst_base + adaptor_priv->YBufOffset;
@@ -892,7 +910,8 @@ I830CopyPackedData(intel_adaptor_private *adaptor_priv,
 		break;
 	}
 
-	drm_intel_bo_unmap(adaptor_priv->buf);
+	drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf);
+	return TRUE;
 }
 
 static void intel_memcpy_plane(unsigned char *dst, unsigned char *src,
@@ -945,7 +964,7 @@ static void intel_memcpy_plane(unsigned char *dst, unsigned char *src,
 	}
 }
 
-static void
+static Bool
 I830CopyPlanarData(intel_adaptor_private *adaptor_priv,
 		   unsigned char *buf, int srcPitch, int srcPitch2,
 		   int dstPitch, int dstPitch2,
@@ -967,7 +986,9 @@ I830CopyPlanarData(intel_adaptor_private *adaptor_priv,
 	       (unsigned long)src1 - (unsigned long)buf);
 #endif
 
-	drm_intel_bo_map(adaptor_priv->buf, TRUE);
+	if (drm_intel_gem_bo_map_gtt(adaptor_priv->buf))
+		return FALSE;
+
 	dst_base = adaptor_priv->buf->virtual;
 
 	dst1 = dst_base + adaptor_priv->YBufOffset;
@@ -1011,7 +1032,8 @@ I830CopyPlanarData(intel_adaptor_private *adaptor_priv,
 	intel_memcpy_plane(dst3, src3, h / 2, w / 2,
 			  dstPitch, srcPitch2, adaptor_priv->rotation);
 
-	drm_intel_bo_unmap(adaptor_priv->buf);
+	drm_intel_gem_bo_unmap_gtt(adaptor_priv->buf);
+	return TRUE;
 }
 
 static void intel_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
@@ -1348,17 +1370,16 @@ intel_setup_video_buffer(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv,
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 
 	/* Free the current buffer if we're going to have to reallocate */
-	if (adaptor_priv->buf && adaptor_priv->buf->size < alloc_size) {
-		drm_intel_bo_unreference(adaptor_priv->buf);
-		adaptor_priv->buf = NULL;
-	}
+	if (adaptor_priv->buf && adaptor_priv->buf->size < alloc_size)
+		intel_free_video_buffers(adaptor_priv);
 
 	if (adaptor_priv->buf == NULL) {
-		adaptor_priv->buf = drm_intel_bo_alloc(intel->bufmgr,
-						"xv buffer", alloc_size,
-						4096);
+		adaptor_priv->buf = drm_intel_bo_alloc(intel->bufmgr, "xv buffer",
+						       alloc_size, 4096);
 		if (adaptor_priv->buf == NULL)
 			return FALSE;
+
+		adaptor_priv->reusable = TRUE;
 	}
 
 	return TRUE;
@@ -1471,16 +1492,14 @@ intel_copy_video_data(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv,
 
 	/* copy data */
 	if (is_planar_fourcc(id)) {
-		I830CopyPlanarData(adaptor_priv, buf, srcPitch, srcPitch2,
-				   *dstPitch, *dstPitch2,
-				   height, top, left, nlines,
-				   npixels, id);
+		return I830CopyPlanarData(adaptor_priv, buf, srcPitch, srcPitch2,
+					  *dstPitch, *dstPitch2,
+					  height, top, left, nlines,
+					  npixels, id);
 	} else {
-		I830CopyPackedData(adaptor_priv, buf, srcPitch, *dstPitch, top, left,
-				   nlines, npixels);
+		return I830CopyPackedData(adaptor_priv, buf, srcPitch, *dstPitch, top, left,
+					  nlines, npixels);
 	}
-
-	return TRUE;
 }
 
 /*
@@ -1533,10 +1552,8 @@ I830PutImageTextured(ScrnInfoPtr scrn,
 		return Success;
 
 	if (xvmc_passthrough(id)) {
-		int size;
 		uint32_t *gem_handle = (uint32_t *)buf;
-
-		intel_free_video_buffers(adaptor_priv);
+		int size;
 
 		intel_setup_dst_params(scrn, adaptor_priv, width, height,
 				&dstPitch, &dstPitch2, &size, id);
@@ -1547,10 +1564,17 @@ I830PutImageTextured(ScrnInfoPtr scrn,
 			return BadAlloc;
 		}
 
+		if (adaptor_priv->buf)
+			drm_intel_bo_unreference(adaptor_priv->buf);
+
 		adaptor_priv->buf =
 			drm_intel_bo_gem_create_from_name(intel->bufmgr,
 							  "xvmc surface",
 							  *gem_handle);
+		if (adaptor_priv->buf == NULL)
+			return BadAlloc;
+
+		adaptor_priv->reusable = FALSE;
 	} else {
 		if (!intel_copy_video_data(scrn, adaptor_priv, width, height,
 					  &dstPitch, &dstPitch2,
diff --git a/src/intel_video.h b/src/intel_video.h
index e1ba09a..d567eac 100644
--- a/src/intel_video.h
+++ b/src/intel_video.h
@@ -52,7 +52,8 @@ typedef struct {
 	Time offTime;
 	Time freeTime;
 	/** YUV data buffers */
-	drm_intel_bo *buf;
+	drm_intel_bo *buf, *old_buf;
+	Bool reusable;
 
 	Bool textured;
 	Rotation rotation;	/* should remove intel->rotation later */


More information about the xorg-commit mailing list