Blob Blame Raw
From 85577ae6bad8fd8673b9abc81e7f2531ae64fcec Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Mon, 21 Dec 2009 11:47:19 +1000
Subject: [PATCH] fb: backport fb changes from master for src window operations.

This rolls up the following commits and also keeps the image_from_pict
API compatiblity. It introduces a new image_from_pict_18 API that is
used by the server leaving the old API alone.

I've rolled this up as I don't want to introduce ABI breaks in bisection.

a72c65e9176c51de95db2fdbf4c5d946a4911695 fb: Adjust transform or composite coordinates for pixman operations
bd567061c8b84b268d9bbb01bc4d8981feefb862 Split fbGetDrawable into fbGetDrawablePixmap and fbGetPixmapBitsData
61335052972a78d67c0ba74f902273b34c63a198 Revert "Fix clipping when windows are used as sources"
071b3c1810d9f2602173acc8578caac20e0b771e Revert "Use IncludeInferiors when copying windows before compositing."
8e640d6b131d2865a9725d8997023865b0ef3d69 Revert "Reserve space for two GC values in copy_drawable()."

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 fb/fb.h        |   76 ++++++++++++++++++++++++++++---------------------
 fb/fbpict.c    |   85 +++++++++++++++++++++++++++++++++++++++----------------
 fb/fbtrap.c    |    6 ++-
 fb/wfbrename.h |    1 +
 4 files changed, 108 insertions(+), 60 deletions(-)

diff --git a/fb/fb.h b/fb/fb.h
index 37de71e..8b2839a 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -700,38 +700,41 @@ typedef struct {
 #define __fbPixOffXPix(pPix)	(__fbPixDrawableX(pPix))
 #define __fbPixOffYPix(pPix)	(__fbPixDrawableY(pPix))
 
-#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
-    PixmapPtr   _pPix; \
-    if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
-	_pPix = fbGetWindowPixmap(pDrawable); \
-	(xoff) = __fbPixOffXWin(_pPix); \
-	(yoff) = __fbPixOffYWin(_pPix); \
-    } else { \
-	_pPix = (PixmapPtr) (pDrawable); \
-	(xoff) = __fbPixOffXPix(_pPix); \
-	(yoff) = __fbPixOffYPix(_pPix); \
-    } \
-    fbPrepareAccess(pDrawable); \
-    (pointer) = (FbBits *) _pPix->devPrivate.ptr; \
-    (stride) = ((int) _pPix->devKind) / sizeof (FbBits); (void)(stride); \
-    (bpp) = _pPix->drawable.bitsPerPixel;  (void)(bpp); \
+#define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) {			\
+    if ((pDrawable)->type != DRAWABLE_PIXMAP) { 				\
+	(pixmap) = fbGetWindowPixmap(pDrawable);				\
+	(xoff) = __fbPixOffXWin(pixmap); 					\
+	(yoff) = __fbPixOffYWin(pixmap); 					\
+    } else { 									\
+	(pixmap) = (PixmapPtr) (pDrawable);					\
+	(xoff) = __fbPixOffXPix(pixmap); 					\
+	(yoff) = __fbPixOffYPix(pixmap); 					\
+    } 										\
+    fbPrepareAccess(pDrawable); 						\
 }
 
-#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \
-    PixmapPtr   _pPix; \
-    if ((pDrawable)->type != DRAWABLE_PIXMAP) { \
-	_pPix = fbGetWindowPixmap(pDrawable); \
-	(xoff) = __fbPixOffXWin(_pPix); \
-	(yoff) = __fbPixOffYWin(_pPix); \
-    } else { \
-	_pPix = (PixmapPtr) (pDrawable); \
-	(xoff) = __fbPixOffXPix(_pPix); \
-	(yoff) = __fbPixOffYPix(_pPix); \
-    } \
-    fbPrepareAccess(pDrawable); \
-    (pointer) = (FbStip *) _pPix->devPrivate.ptr; \
-    (stride) = ((int) _pPix->devKind) / sizeof (FbStip); (void)(stride); \
-    (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \
+#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) {			\
+    (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; 			       	\
+    (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);	\
+    (bpp) = (pixmap)->drawable.bitsPerPixel;  (void)(bpp); 			\
+}
+
+#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) {			\
+    (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; 			       	\
+    (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);	\
+    (bpp) = (pixmap)->drawable.bitsPerPixel;  (void)(bpp); 			\
+}
+
+#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { 		\
+    PixmapPtr   _pPix; 								\
+    fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); 				\
+    fbGetPixmapBitsData(_pPix, pointer, stride, bpp);				\
+}
+
+#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { 	\
+    PixmapPtr   _pPix; 								\
+    fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff);				\
+    fbGetPixmapStipData(_pPix, pointer, stride, bpp);				\
 }
 
 /*
@@ -2079,9 +2082,16 @@ fbFillRegionSolid (DrawablePtr	pDrawable,
 		   FbBits	xor);
 
 extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr pict,
-		 Bool       has_clip,
-		 Bool       is_src);
+image_from_pict (PicturePtr	pict,
+		 Bool		has_clip,
+		 Bool		is_src);
+
+extern _X_EXPORT pixman_image_t *
+image_from_pict_18 (PicturePtr	pict,
+		 Bool		has_clip,
+		 int		*xoff,
+		 int		*yoff);
+
 extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
 
 #endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 8fdaa58..f9f4343 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -158,19 +158,24 @@ fbComposite (CARD8      op,
 	     CARD16     height)
 {
     pixman_image_t *src, *mask, *dest;
+    int src_xoff, src_yoff;
+    int msk_xoff, msk_yoff;
+    int dst_xoff, dst_yoff;
     
-    miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
+    miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
     if (pMask)
-	miCompositeSourceValidate (pMask, xMask, yMask, width, height);
+	miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
     
-    src = image_from_pict (pSrc, TRUE, TRUE);
-    mask = image_from_pict (pMask, TRUE, TRUE);
-    dest = image_from_pict (pDst, TRUE, FALSE);
+    src = image_from_pict_18 (pSrc, FALSE, &src_xoff, &src_yoff);
+    mask = image_from_pict_18 (pMask, FALSE, &msk_xoff, &msk_yoff);
+    dest = image_from_pict_18 (pDst, TRUE, &dst_xoff, &dst_yoff);
 
     if (src && dest && !(pMask && !mask))
     {
 	pixman_image_composite (op, src, mask, dest,
-				xSrc, ySrc, xMask, yMask, xDst, yDst,
+				xSrc + src_xoff, ySrc + src_yoff,
+				xMask + msk_xoff, yMask + msk_yoff,
+				xDst + dst_xoff, yDst + dst_yoff,
 				width, height);
     }
 
@@ -270,22 +275,22 @@ create_conical_gradient_image (PictGradient *gradient)
 
 static pixman_image_t *
 create_bits_picture (PicturePtr pict,
-		     Bool       has_clip)
+		     Bool       has_clip,
+		     int	*xoff,
+		     int	*yoff)
 {
+    PixmapPtr pixmap;
     FbBits *bits;
     FbStride stride;
-    int bpp, xoff, yoff;
+    int bpp;
     pixman_image_t *image;
     
-    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-
-    bits = (FbBits*)((CARD8*)bits +
-		     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
-		     (pict->pDrawable->x + xoff) * (bpp / 8));
+    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
+    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
 
     image = pixman_image_create_bits (
 	pict->format,
-	pict->pDrawable->width, pict->pDrawable->height,
+	pixmap->drawable.width, pixmap->drawable.height,
 	(uint32_t *)bits, stride * sizeof (FbStride));
     
     
@@ -311,30 +316,52 @@ create_bits_picture (PicturePtr pict,
 	if (pict->clientClipType != CT_NONE)
 	    pixman_image_set_has_client_clip (image, TRUE);
 
-	pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
+	if (*xoff || *yoff)
+	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
 
 	pixman_image_set_clip_region (image, pict->pCompositeClip);
 
-	pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
+	if (*xoff || *yoff)
+	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
     }
     
     /* Indexed table */
     if (pict->pFormat->index.devPrivate)
 	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
 
+    /* Add in drawable origin to position within the image */
+    *xoff += pict->pDrawable->x;
+    *yoff += pict->pDrawable->y;
+
     return image;
 }
 
 static void
-set_image_properties (pixman_image_t *image, PicturePtr pict)
+set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
     
     if (pict->transform)
     {
-	pixman_image_set_transform (
-	    image, (pixman_transform_t *)pict->transform);
+	/* For source images, adjust the transform to account
+	 * for the drawable offset within the pixman image,
+	 * then set the offset to 0 as it will be used
+	 * to compute positions within the transformed image.
+	 */
+	if (!has_clip) {
+	    struct pixman_transform	adjusted;
+
+	    adjusted = *pict->transform;
+	    pixman_transform_translate(&adjusted,
+				       NULL,
+				       pixman_int_to_fixed(*xoff),
+				       pixman_int_to_fixed(*yoff));
+	    pixman_image_set_transform (image, &adjusted);
+	    *xoff = 0;
+	    *yoff = 0;
+	} else
+	    pixman_image_set_transform (image, pict->transform);
     }
     
     switch (pict->repeatType)
@@ -361,7 +388,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict)
     
     if (pict->alphaMap)
     {
-	pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE, TRUE);
+	int alpha_xoff, alpha_yoff;
+	pixman_image_t *alpha_map = image_from_pict_18 (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -393,10 +421,9 @@ set_image_properties (pixman_image_t *image, PicturePtr pict)
     pixman_image_set_source_clipping (image, TRUE);
 }
 
+
 pixman_image_t *
-image_from_pict (PicturePtr pict,
-		 Bool has_clip,
-		 Bool is_src)
+image_from_pict_18 (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
 {
     pixman_image_t *image = NULL;
 
@@ -405,7 +432,7 @@ image_from_pict (PicturePtr pict,
 
     if (pict->pDrawable)
     {
-	image = create_bits_picture (pict, has_clip);
+	image = create_bits_picture (pict, has_clip, xoff, yoff);
     }
     else if (pict->pSourcePict)
     {
@@ -429,11 +456,18 @@ image_from_pict (PicturePtr pict,
     }
     
     if (image)
-	set_image_properties (image, pict);
+	set_image_properties (image, pict, has_clip, xoff, yoff);
     
     return image;
 }
 
+pixman_image_t *
+image_from_pict (PicturePtr pict, Bool has_clip, Bool is_src)
+{
+    int xoff = 0, yoff = 0;
+    return image_from_pict_18(pict, has_clip, &xoff, &yoff);
+}
+
 void
 free_pixman_pict (PicturePtr pict, pixman_image_t *image)
 {
@@ -463,3 +497,4 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
 
     return TRUE;
 }
+
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index b1e1eff..5b5aeae 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -40,7 +40,8 @@ fbAddTraps (PicturePtr	pPicture,
 	    int		ntrap,
 	    xTrap	*traps)
 {
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE);
+    int image_xoff, image_yoff;
+    pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &image_xoff, &image_yoff);
 
     if (!image)
 	return;
@@ -56,7 +57,8 @@ fbRasterizeTrapezoid (PicturePtr    pPicture,
 		      int	    x_off,
 		      int	    y_off)
 {
-    pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE);
+    int	mask_xoff, mask_yoff;
+    pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &mask_xoff, &mask_yoff);
 
     if (!image)
 	return;
diff --git a/fb/wfbrename.h b/fb/wfbrename.h
index 73ee510..e9cdca8 100644
--- a/fb/wfbrename.h
+++ b/fb/wfbrename.h
@@ -187,4 +187,5 @@
 #define fbZeroSegment wfbZeroSegment
 #define free_pixman_pict wfb_free_pixman_pict
 #define image_from_pict wfb_image_from_pict
+#define image_from_pict_18 wfb_image_from_pict_18
 #define composeFunctions wfbComposeFunctions
-- 
1.6.5.2