[PATCH] exa: implement a UTS based upload through CopyArea

Maarten Maathuis madman2003 at gmail.com
Thu Apr 9 06:55:17 PDT 2009


- Some image viewers (eog, gqview) trigger the CopyArea path of Xext/shm.c
- I'm not aware of any bad path that wouldn't like UTS and trigger this code.
- I don't think the boxes need to be clipped to src dimensions.
---
 exa/exa_accel.c |   67 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index b1ab2d1..eadb1db 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -466,27 +466,56 @@ exaHWCopyNtoN (DrawablePtr    pSrcDrawable,
 	goto fallback;
     }
 
-    if (!exaPixmapIsOffscreen(pSrcPixmap) ||
-	!exaPixmapIsOffscreen(pDstPixmap) ||
-	!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
-					upsidedown ? -1 : 1,
-					pGC ? pGC->alu : GXcopy,
-					pGC ? pGC->planemask : FB_ALLONES)) {
-	goto fallback;
-    }
+    if (exaPixmapIsOffscreen(pDstPixmap)) {
+	/* Normal blitting. */
+	if (exaPixmapIsOffscreen(pSrcPixmap)) {
+	    if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
+						upsidedown ? -1 : 1,
+						pGC ? pGC->alu : GXcopy,
+						pGC ? pGC->planemask : FB_ALLONES)) {
+		goto fallback;
+	    }
 
-    while (nbox--)
-    {
-	(*pExaScr->info->Copy) (pDstPixmap,
-				pbox->x1 + dx + src_off_x,
-				pbox->y1 + dy + src_off_y,
-				pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
-				pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
-	pbox++;
-    }
+	    while (nbox--)
+	    {
+		(*pExaScr->info->Copy) (pDstPixmap,
+					pbox->x1 + dx + src_off_x,
+					pbox->y1 + dy + src_off_y,
+					pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
+					pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+		pbox++;
+	    }
+
+	    (*pExaScr->info->DoneCopy) (pDstPixmap);
+	    exaMarkSync (pDstDrawable->pScreen);
+	/* UTS: mainly for SHM PutImage's secondary path. */
+	} else {
+	    int bpp = pSrcDrawable->bitsPerPixel;
+	    int src_stride = exaGetPixmapPitch(pSrcPixmap);
+	    CARD8 *src = NULL;
+
+	    if (!pExaScr->info->UploadToScreen)
+		goto fallback;
+
+	    if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
+		goto fallback;
+
+	    if (pSrcDrawable->bitsPerPixel < 8)
+		goto fallback;
+
+	    while (nbox--)
+	    { 
+		src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8);
+		if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, 
+				pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 
+				(char *) src, src_stride))
+		    goto fallback;
 
-    (*pExaScr->info->DoneCopy) (pDstPixmap);
-    exaMarkSync (pDstDrawable->pScreen);
+		pbox++;
+	    }
+	}
+    } else
+	goto fallback;
 
     goto out;
 
-- 
1.6.2.2



More information about the xorg-devel mailing list