[Intel-gfx] [PATCH 09/13] Xv: split up I830PutImage

Daniel Vetter daniel.vetter at ffwll.ch
Tue Jun 30 13:12:51 CEST 2009


This was the last monster-function. Also so small cleanups in
I830PutImage.

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 src/i830_video.c |  394 +++++++++++++++++++++++++++++-------------------------
 1 files changed, 212 insertions(+), 182 deletions(-)

diff --git a/src/i830_video.c b/src/i830_video.c
index 305530a..ff227ab 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2158,101 +2158,91 @@ i830_fill_colorkey (ScreenPtr pScreen, uint32_t key, RegionPtr clipboxes)
    FreeScratchGC (gc);
 }
 
-/*
- * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
- * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
- * id is a fourcc code for the format of the video.
- * buf is the pointer to the source data in system memory.
- * width and height are the w/h of the source data.
- * If "sync" is TRUE, then we must be finished with *buf at the point of return
- * (which we always are).
- * clipBoxes is the clipping region in screen space.
- * data is a pointer to our port private.
- * pDraw is a Drawable, which might not be the screen in the case of
- * compositing.  It's a new argument to the function in the 1.1 server.
- */
-static int
-I830PutImage(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,
-	     int id, unsigned char *buf,
-	     short width, short height,
-	     Bool sync, RegionPtr clipBoxes, pointer data,
-	     DrawablePtr pDraw)
+static void
+i830_wait_for_scanline(ScrnInfoPtr pScrn, PixmapPtr pPixmap,
+	xf86CrtcPtr crtc, RegionPtr clipBoxes)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-    I830OverlayRegPtr overlay;
-    PixmapPtr pPixmap = get_drawable_pixmap(pDraw);;
-    INT32 x1, x2, y1, y2;
-    int srcPitch = 0, srcPitch2 = 0, dstPitch;
-    int dstPitch2 = 0;
-    int top, left, npixels, nlines, size;
-    BoxRec dstBox;
-    int pitchAlignMask;
-    int alloc_size;
-    xf86CrtcPtr	crtc;
+    BoxPtr box;
+    int y1, y2;
+    int pipe = -1, event, load_scan_lines_pipe;
 
-    if (pPriv->textured)
-	overlay = NULL;
-    else
-	overlay = I830OVERLAYREG(pI830);
+    if (pixmap_is_scanout(pPixmap)) 
+	pipe = i830_crtc_to_pipe(crtc);
 
-#if 0
-    ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
-	   "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
-	   drw_w, drw_h, width, height);
-#endif
-
-    if (!pPriv->textured) {
-        /* If dst width and height are less than 1/8th the src size, the
-         * src/dst scale factor becomes larger than 8 and doesn't fit in
-         * the scale register. */
-        if(src_w >= (drw_w * 8))
-            drw_w = src_w/7;
+    if (pipe >= 0) {
+	if (pipe == 0) {
+	    event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
+	    load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
+	} else {
+	    event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
+	    load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
+	}
 
-        if(src_h >= (drw_h * 8))
-            drw_h = src_h/7;
+	box = REGION_EXTENTS(unused, clipBoxes);
+	y1 = box->y1 - crtc->y;
+	y2 = box->y2 - crtc->y;
+
+	BEGIN_BATCH(5);
+	/* The documentation says that the LOAD_SCAN_LINES command
+	 * always comes in pairs. Don't ask me why. */
+	OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
+	OUT_BATCH((y1 << 16) | y2);
+	OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
+	OUT_BATCH((y1 << 16) | y2);
+	OUT_BATCH(MI_WAIT_FOR_EVENT | event);
+	ADVANCE_BATCH();
     }
+}
 
-    /* Clip */
-    x1 = src_x;
-    x2 = src_x + src_w;
-    y1 = src_y;
-    y2 = src_y + src_h;
-
-    dstBox.x1 = drw_x;
-    dstBox.x2 = drw_x + drw_w;
-    dstBox.y1 = drw_y;
-    dstBox.y2 = drw_y + drw_h;
-
-    if (!i830_clip_video_helper(pScrn, 
-				pPriv,
-				&crtc,
-				&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
-				width, height))
-	return Success;
-
-     if (!pPriv->textured) {
-	 /* texture video handles rotation differently. */
-	if (crtc)
-	    pPriv->rotation = crtc->rotation;
-	else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		    "Fail to clip video to any crtc!\n");
-	    return Success;
-	}
-     }
+static Bool
+i830_setup_video_buffer(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
+	int alloc_size, int id)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    /* Free the current buffer if we're going to have to reallocate */
+    if (pPriv->buf && pPriv->buf->size < alloc_size) {
+	if (!pPriv->textured)
+	    drm_intel_bo_unpin(pPriv->buf);
+	drm_intel_bo_unreference(pPriv->buf);
+	pPriv->buf = NULL;
+    }
 
-    if (is_planar_fourcc(id)) {
-	srcPitch = (width + 0x3) & ~0x3;
-	srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+#ifdef INTEL_XVMC
+    if (id == FOURCC_XVMC && 
+        pPriv->rotation == RR_Rotate_0) {
+        if (pPriv->buf) {
+            assert(pPriv->textured);
+            drm_intel_bo_unreference(pPriv->buf);
+            pPriv->buf = NULL;
+        }
     } else {
-	srcPitch = width << 1;
+#endif
+        if (pPriv->buf == NULL) {
+            pPriv->buf = drm_intel_bo_alloc(pI830->bufmgr,
+                                         "xv buffer", alloc_size, 4096);
+            if (pPriv->buf == NULL)
+                return FALSE;
+            if (!pPriv->textured && drm_intel_bo_pin(pPriv->buf, 4096) != 0) {
+                drm_intel_bo_unreference(pPriv->buf);
+                pPriv->buf = NULL;
+                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                           "Failed to pin xv buffer\n");
+                return FALSE;
+            }
+        }
+#ifdef INTEL_XVMC
     }
+#endif
+    return TRUE;
+}
+
+static void
+i830_dst_pitch_and_size(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, short width,
+	short height, int *dstPitch, int *dstPitch2, int *size, int id)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int pitchAlignMask;
 
     /* Only needs to be DWORD-aligned for textured on i915, but overlay has
      * stricter requirements.
@@ -2278,85 +2268,75 @@ I830PutImage(ScrnInfoPtr pScrn,
     case FOURCC_YV12:
     case FOURCC_I420:
 	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	    dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
-	    size = dstPitch * width * 3;
+	    *dstPitch = ((height / 2) + pitchAlignMask) & ~pitchAlignMask;
+	    *size = *dstPitch * width * 3;
 	} else {
-	    dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
-	    size = dstPitch * height * 3;
+	    *dstPitch = ((width / 2) + pitchAlignMask) & ~pitchAlignMask;
+	    *size = *dstPitch * height * 3;
 	}
 	break;
     case FOURCC_UYVY:
     case FOURCC_YUY2:
 
 	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	    dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
-	    size = dstPitch * width;
+	    *dstPitch = ((height << 1) + pitchAlignMask) & ~pitchAlignMask;
+	    *size = *dstPitch * width;
 	} else {
-	    dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
-	    size = dstPitch * height;
+	    *dstPitch = ((width << 1) + pitchAlignMask) & ~pitchAlignMask;
+	    *size = *dstPitch * height;
 	}
 	break;
 #ifdef INTEL_XVMC
     case FOURCC_XVMC:
-	dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask;
-	dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask;
-	size = 0;
+	*dstPitch = ((width / 2) + pitchAlignMask ) & ~pitchAlignMask;
+	*dstPitch2 = (width + pitchAlignMask ) & ~pitchAlignMask;
+	*size = 0;
 	break;
 #endif
     default:
-	dstPitch = 0;
-	size = 0;
+	*dstPitch = 0;
+	*size = 0;
 	break;
     }
 #if 0
-    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, dstPitch, size);
+    ErrorF("srcPitch: %d, dstPitch: %d, size: %d\n", srcPitch, *dstPitch, size);
 #endif
+}
+
+static Bool
+i830_copy_video_data(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, 
+	     short width, short height, int *dstPitch, int *dstPitch2,
+	     INT32 x1, INT32 y1, INT32 x2, INT32 y2,
+	     int id, unsigned char *buf)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int srcPitch = 0, srcPitch2 = 0;
+    int top, left, npixels, nlines, size;
+    int alloc_size;
+
+    if (is_planar_fourcc(id)) {
+	srcPitch = (width + 0x3) & ~0x3;
+	srcPitch2 = ((width >> 1) + 0x3) & ~0x3;
+    } else {
+	srcPitch = width << 1;
+    }
+
+    i830_dst_pitch_and_size(pScrn, pPriv, width, height, dstPitch, dstPitch2,
+	    &size, id);
 
     alloc_size = size;
     if (pPriv->doubleBuffer)
 	alloc_size *= 2;
 
-    /* Free the current buffer if we're going to have to reallocate */
-    if (pPriv->buf && pPriv->buf->size < alloc_size) {
-	if (!pPriv->textured)
-	    drm_intel_bo_unpin(pPriv->buf);
-	drm_intel_bo_unreference(pPriv->buf);
-	pPriv->buf = NULL;
-    }
-
-#ifdef INTEL_XVMC
-    if (id == FOURCC_XVMC && 
-        pPriv->rotation == RR_Rotate_0) {
-        if (pPriv->buf) {
-            assert(pPriv->textured);
-            drm_intel_bo_unreference(pPriv->buf);
-            pPriv->buf = NULL;
-        }
-    } else {
-#endif
-        if (pPriv->buf == NULL) {
-            pPriv->buf = drm_intel_bo_alloc(pI830->bufmgr,
-                                         "xv buffer", alloc_size, 4096);
-            if (pPriv->buf == NULL)
-                return BadAlloc;
-            if (!pPriv->textured && drm_intel_bo_pin(pPriv->buf, 4096) != 0) {
-                drm_intel_bo_unreference(pPriv->buf);
-                pPriv->buf = NULL;
-                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                           "Failed to pin xv buffer\n");
-                return BadAlloc;
-            }
-        }
-#ifdef INTEL_XVMC
-    }
-#endif
+    if (!i830_setup_video_buffer(pScrn, pPriv, alloc_size, id))
+	return FALSE;
 
     /* fixup pointers */
 #ifdef INTEL_XVMC
     if (id == FOURCC_XVMC && IS_I915(pI830)) {
 	pPriv->YBufOffset = (uint32_t)((uintptr_t)buf);
-	pPriv->VBufOffset = pPriv->YBufOffset + (dstPitch2 * height);
-	pPriv->UBufOffset = pPriv->VBufOffset + (dstPitch * height / 2);
+	pPriv->VBufOffset = pPriv->YBufOffset + (*dstPitch2 * height);
+	pPriv->UBufOffset = pPriv->VBufOffset + (*dstPitch * height / 2);
     } else {
 #endif
 	if (pPriv->textured)
@@ -2375,11 +2355,11 @@ I830PutImage(ScrnInfoPtr pScrn,
 	}
 
 	if (pPriv->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
-	    pPriv->UBufOffset = pPriv->YBufOffset + (dstPitch * 2 * width);
-	    pPriv->VBufOffset = pPriv->UBufOffset + (dstPitch * width / 2);
+	    pPriv->UBufOffset = pPriv->YBufOffset + (*dstPitch * 2 * width);
+	    pPriv->VBufOffset = pPriv->UBufOffset + (*dstPitch * width / 2);
 	} else {
-	    pPriv->UBufOffset = pPriv->YBufOffset + (dstPitch * 2 * height);
-	    pPriv->VBufOffset = pPriv->UBufOffset + (dstPitch * height / 2);
+	    pPriv->UBufOffset = pPriv->YBufOffset + (*dstPitch * 2 * height);
+	    pPriv->VBufOffset = pPriv->UBufOffset + (*dstPitch * height / 2);
 	}
 #ifdef INTEL_XVMC
     }
@@ -2395,15 +2375,103 @@ I830PutImage(ScrnInfoPtr pScrn,
 		|| pPriv->rotation != RR_Rotate_0) {
 	    top &= ~1;
 	    nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-	    I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, dstPitch,
+	    I830CopyPlanarData(pScrn, pPriv, buf, srcPitch, srcPitch2, *dstPitch,
 		    height, top, left, nlines, npixels, id);
 	}
     } else {
 	nlines = ((y2 + 0xffff) >> 16) - top;
-	I830CopyPackedData(pScrn, pPriv, buf, srcPitch, dstPitch, top, left,
+	I830CopyPackedData(pScrn, pPriv, buf, srcPitch, *dstPitch, top, left,
 			   nlines, npixels);
     }
 
+    return TRUE;
+}
+
+/*
+ * The source rectangle of the video is defined by (src_x, src_y, src_w, src_h).
+ * The dest rectangle of the video is defined by (drw_x, drw_y, drw_w, drw_h).
+ * id is a fourcc code for the format of the video.
+ * buf is the pointer to the source data in system memory.
+ * width and height are the w/h of the source data.
+ * If "sync" is TRUE, then we must be finished with *buf at the point of return
+ * (which we always are).
+ * clipBoxes is the clipping region in screen space.
+ * data is a pointer to our port private.
+ * pDraw is a Drawable, which might not be the screen in the case of
+ * compositing.  It's a new argument to the function in the 1.1 server.
+ */
+static int
+I830PutImage(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,
+	     int id, unsigned char *buf,
+	     short width, short height,
+	     Bool sync, RegionPtr clipBoxes, pointer data,
+	     DrawablePtr pDraw)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    I830PortPrivPtr pPriv = (I830PortPrivPtr) data;
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+    PixmapPtr pPixmap = get_drawable_pixmap(pDraw);;
+    INT32 x1, x2, y1, y2;
+    int dstPitch;
+    int dstPitch2 = 0;
+    BoxRec dstBox;
+    xf86CrtcPtr	crtc;
+
+#if 0
+    ErrorF("I830PutImage: src: (%d,%d)(%d,%d), dst: (%d,%d)(%d,%d)\n"
+	   "width %d, height %d\n", src_x, src_y, src_w, src_h, drw_x, drw_y,
+	   drw_w, drw_h, width, height);
+#endif
+
+    if (!pPriv->textured) {
+        /* If dst width and height are less than 1/8th the src size, the
+         * src/dst scale factor becomes larger than 8 and doesn't fit in
+         * the scale register. */
+        if(src_w >= (drw_w * 8))
+            drw_w = src_w/7;
+
+        if(src_h >= (drw_h * 8))
+            drw_h = src_h/7;
+    }
+
+    /* Clip */
+    x1 = src_x;
+    x2 = src_x + src_w;
+    y1 = src_y;
+    y2 = src_y + src_h;
+
+    dstBox.x1 = drw_x;
+    dstBox.x2 = drw_x + drw_w;
+    dstBox.y1 = drw_y;
+    dstBox.y2 = drw_y + drw_h;
+
+    if (!i830_clip_video_helper(pScrn, 
+				pPriv,
+				&crtc,
+				&dstBox, &x1, &x2, &y1, &y2, clipBoxes,
+				width, height))
+	return Success;
+
+    if (!pPriv->textured) {
+	 /* texture video handles rotation differently. */
+	if (crtc)
+	    pPriv->rotation = crtc->rotation;
+	else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		    "Fail to clip video to any crtc!\n");
+	    return Success;
+	}
+    }
+
+    if (!i830_copy_video_data(pScrn, pPriv, width, height,
+		&dstPitch, &dstPitch2,
+		x1, y1, x2, y2, id, buf))
+	return BadAlloc;
+
     if (!pPriv->textured) {
 	i830_display_overlay(pScrn, crtc, id, width, height, dstPitch,
 			   x1, y1, x2, y2, &dstBox, src_w, src_h,
@@ -2415,45 +2483,8 @@ I830PutImage(ScrnInfoPtr pScrn,
 	    i830_fill_colorkey (pScreen, pPriv->colorKey, clipBoxes);
 	}
     } else {
-        Bool sync = TRUE;
-        
-        if (crtc == NULL) {
-            sync = FALSE;
-        } else if (pPriv->SyncToVblank == 0) {
-            sync = FALSE;
-        }
-
-        if (sync) {
-	    BoxPtr box;
-	    int y1, y2;
-	    int pipe = -1, event, load_scan_lines_pipe;
-
-	    if (pixmap_is_scanout(pPixmap))
-		pipe = i830_crtc_to_pipe(crtc);
-
-	    if (pipe >= 0) {
-		if (pipe == 0) {
-		    event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
-		    load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
-		} else {
-		    event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
-		    load_scan_lines_pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
-		}
-
-		box = REGION_EXTENTS(unused, clipBoxes);
-		y1 = box->y1 - crtc->y;
-		y2 = box->y2 - crtc->y;
-
-		BEGIN_BATCH(5);
-		/* The documentation says that the LOAD_SCAN_LINES command
-		 * always comes in pairs. Don't ask me why. */
-		OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
-		OUT_BATCH((y1 << 16) | y2);
-		OUT_BATCH(MI_LOAD_SCAN_LINES_INCL | load_scan_lines_pipe);
-		OUT_BATCH((y1 << 16) | y2);
-		OUT_BATCH(MI_WAIT_FOR_EVENT | event);
-		ADVANCE_BATCH();
-	    }
+        if (!crtc || pPriv->SyncToVblank != 0) {
+	    i830_wait_for_scanline(pScrn, pPixmap, crtc, clipBoxes);
         }
 
         if (IS_I965G(pI830)) {
@@ -2472,8 +2503,7 @@ I830PutImage(ScrnInfoPtr pScrn,
                                      dstPitch, dstPitch2, x1, y1, x2, y2,
                                      src_w, src_h, drw_w, drw_h, pPixmap);
         }
-    }
-    if (pPriv->textured) {
+
 	DamageDamageRegion(pDraw, clipBoxes);
     }
 
-- 
1.6.3.3




More information about the Intel-gfx mailing list