xserver/fb fbcompose.c, 1.21, 1.22 fbpict.c, 1.31, 1.32 fbpict.h, 1.18, 1.19

David Reveman xserver-commit@pdx.freedesktop.org
Wed Jan 26 02:20:18 PST 2005


Committed by: davidr

Update of /cvs/xserver/xserver/fb
In directory gabe:/tmp/cvs-serv24446/fb

Modified Files:
	fbcompose.c fbpict.c fbpict.h 
Log Message:
Add transform+repeat and convolution filter support

Index: fbcompose.c
===================================================================
RCS file: /cvs/xserver/xserver/fb/fbcompose.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- fbcompose.c	13 May 2004 21:09:30 -0000	1.21
+++ fbcompose.c	26 Jan 2005 10:20:15 -0000	1.22
@@ -2426,6 +2426,8 @@
     (*op[2].store) (&op[2], value & 0xff000000);
 }
 
+#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
+
 CARD32
 fbFetch_transform (FbCompositeOperand *op)
 {
@@ -2437,16 +2439,24 @@
     CARD32	rtot, gtot, btot, atot;
     CARD32	xerr, yerr;
     CARD32	bits;
+    INT32	srtot, sgtot, sbtot, satot;
+    xFixed	sum, *params;
 
     v.vector[0] = IntToxFixed(op->u.transform.x);
     v.vector[1] = IntToxFixed(op->u.transform.y);
     v.vector[2] = xFixed1;
-    if (!PictureTransformPoint (op->u.transform.transform, &v))
-	return 0;
+    if (op->u.transform.transform)
+	if (!PictureTransformPoint (op->u.transform.transform, &v))
+	    return 0;
     switch (op->u.transform.filter) {
     case PictFilterNearest:
 	y = xFixedToInt (v.vector[1]) + op->u.transform.top_y;
 	x = xFixedToInt (v.vector[0]) + op->u.transform.left_x;
+	if (op->u.transform.repeat)
+	{
+	    y = MOD (y, op->u.transform.height);
+	    x = MOD (x, op->u.transform.width);
+	}
 	if (POINT_IN_REGION (0, op->clip, x, y, &box))
 	{
 	    (*op[1].set) (&op[1], x, y);
@@ -2467,13 +2477,24 @@
 	for (y = miny; y <= maxy; y++)
 	{
 	    CARD32	lrtot = 0, lgtot = 0, lbtot = 0, latot = 0;
+	    int		tx, ty;
+  	 
+	    if (op->u.transform.repeat)
+		ty = MOD (y, op->u.transform.height);
+	    else
+		ty = y;
 	    
 	    xerr = xFixed1 - xFixedFrac (v.vector[0]);
 	    for (x = minx; x <= maxx; x++)
 	    {
-		if (POINT_IN_REGION (0, op->clip, x, y, &box))
+		 if (op->u.transform.repeat)
+		     tx = MOD (x, op->u.transform.width);
+		 else
+		     tx = x;
+		 
+		if (POINT_IN_REGION (0, op->clip, tx, ty, &box))
 		{
-		    (*op[1].set) (&op[1], x, y);
+		    (*op[1].set) (&op[1], tx, ty);
 		    bits = (*op[1].fetch) (&op[1]);
 		    {
 			Splita(bits);
@@ -2501,6 +2522,72 @@
 		(gtot <<  8) |
 		(btot       ));
 	break;
+    case PictFilterConvolution:
+	srtot = sgtot = sbtot = satot = sum = 0;
+	params = op->u.transform.filter_params;
+
+	maxx = xFixedToInt (v.vector[0] + xFixedFloor (*params / 2)) +
+	    op->u.transform.left_x;
+	minx = maxx - xFixedToInt (*params++) + 1;
+	
+	maxy = xFixedToInt (v.vector[1] + xFixedFloor (*params / 2)) +
+	    op->u.transform.top_y;
+	miny = maxy - xFixedToInt (*params++) + 1;
+	
+	for (y = miny; y <= maxy; y++)
+	{
+	    int tx, ty;
+
+	    if (op->u.transform.repeat)
+		ty = MOD (y, op->u.transform.height);
+	    else
+		ty = y;
+	    
+	    for (x = minx; x <= maxx; x++)
+	    {
+		if (*params)
+		{
+		    if (op->u.transform.repeat)
+			tx = MOD (x, op->u.transform.width);
+		    else
+			tx = x;
+		 
+		    if (POINT_IN_REGION (0, op->clip, tx, ty, &box))
+		    {
+			(*op[1].set) (&op[1], tx, ty);
+			bits = (*op[1].fetch) (&op[1]);
+			{
+			    Splita(bits);
+			    
+			    srtot += r * *params;
+			    sgtot += g * *params;
+			    sbtot += b * *params;
+			    satot += a * *params;
+			}
+		    }
+		    sum += *params;
+		}
+		params++;
+	    }
+	}
+
+	if (sum)
+	{
+	    satot /= sum;
+	    srtot /= sum;
+	    sgtot /= sum;
+	    sbtot /= sum;
+	}
+	if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+	if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+	if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+	if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+	
+	bits = ((satot << 24) |
+		(srtot << 16) |
+		(sgtot <<  8) |
+		(sbtot       ));
+	break;
     default:
 	bits = 0;
 	break;
@@ -2519,16 +2606,24 @@
     CARD32	rtot, gtot, btot, atot;
     CARD32	xerr, yerr;
     CARD32	bits;
+    INT32	srtot, sgtot, sbtot, satot;
+    xFixed	sum, *params;
 
     v.vector[0] = IntToxFixed(op->u.transform.x);
     v.vector[1] = IntToxFixed(op->u.transform.y);
     v.vector[2] = xFixed1;
-    if (!PictureTransformPoint (op->u.transform.transform, &v))
-	return 0;
+    if (op->u.transform.transform)
+	if (!PictureTransformPoint (op->u.transform.transform, &v))
+	    return 0;
     switch (op->u.transform.filter) {
     case PictFilterNearest:
-	y = xFixedToInt (v.vector[1]) + op->u.transform.left_x;
-	x = xFixedToInt (v.vector[0]) + op->u.transform.top_y;
+	y = xFixedToInt (v.vector[1]) + op->u.transform.top_y;
+	x = xFixedToInt (v.vector[0]) + op->u.transform.left_x;
+	if (op->u.transform.repeat)
+	{
+	    y = MOD (y, op->u.transform.height);
+	    x = MOD (x, op->u.transform.width);
+	}
 	if (POINT_IN_REGION (0, op->clip, x, y, &box))
 	{
 	    (*op[1].set) (&op[1], x, y);
@@ -2550,12 +2645,24 @@
 	for (y = miny; y <= maxy; y++)
 	{
 	    CARD32	lrtot = 0, lgtot = 0, lbtot = 0, latot = 0;
+	    int		tx, ty;
+  	 
+	    if (op->u.transform.repeat)
+		ty = MOD (y, op->u.transform.height);
+	    else
+		ty = y;
+	    
 	    xerr = xFixed1 - xFixedFrac (v.vector[0]);
 	    for (x = minx; x <= maxx; x++)
 	    {
-		if (POINT_IN_REGION (0, op->clip, x, y, &box))
+		 if (op->u.transform.repeat)
+		     tx = MOD (x, op->u.transform.width);
+		 else
+		     tx = x;
+		 
+		if (POINT_IN_REGION (0, op->clip, tx, ty, &box))
 		{
-		    (*op[1].set) (&op[1], x, y);
+		    (*op[1].set) (&op[1], tx, ty);
 		    bits = (*op[1].fetcha) (&op[1]);
 		    {
 			Splita(bits);
@@ -2566,14 +2673,12 @@
 			n++;
 		    }
 		}
-		x++;
 		xerr = xFixed1 - xerr;
 	    }
 	    rtot += (lrtot >> 10) * yerr;
 	    gtot += (lgtot >> 10) * yerr;
 	    btot += (lbtot >> 10) * yerr;
 	    atot += (latot >> 10) * yerr;
-	    y++;
 	    yerr = xFixed1 - yerr;
 	}
 	if ((atot >>= 22) > 0xff) atot = 0xff;
@@ -2585,6 +2690,72 @@
 		(gtot <<  8) |
 		(btot       ));
 	break;
+    case PictFilterConvolution:
+	srtot = sgtot = sbtot = satot = sum = 0;
+	params = op->u.transform.filter_params;
+
+	maxx = xFixedToInt (v.vector[0] + xFixedFloor (*params / 2)) +
+	    op->u.transform.left_x;
+	minx = maxx - xFixedToInt (*params++) + 1;
+	
+	maxy = xFixedToInt (v.vector[1] + xFixedFloor (*params / 2)) +
+	    op->u.transform.top_y;
+	miny = maxy - xFixedToInt (*params++) + 1;
+	
+	for (y = miny; y <= maxy; y++)
+	{
+	    int tx, ty;
+
+	    if (op->u.transform.repeat)
+		ty = MOD (y, op->u.transform.height);
+	    else
+		ty = y;
+	    
+	    for (x = minx; x <= maxx; x++)
+	    {
+		if (*params)
+		{
+		    if (op->u.transform.repeat)
+			tx = MOD (x, op->u.transform.width);
+		    else
+			tx = x;
+		 
+		    if (POINT_IN_REGION (0, op->clip, tx, ty, &box))
+		    {
+			(*op[1].set) (&op[1], tx, ty);
+			bits = (*op[1].fetcha) (&op[1]);
+			{
+			    Splita(bits);
+			    
+			    srtot += r * *params;
+			    sgtot += g * *params;
+			    sbtot += b * *params;
+			    satot += a * *params;
+			}
+		    }
+		    sum += *params;
+		}
+		params++;
+	    }
+	}
+
+	if (sum)
+	{
+	    satot /= sum;
+	    srtot /= sum;
+	    sgtot /= sum;
+	    sbtot /= sum;
+	}
+	if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+	if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+	if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+	if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+	
+	bits = ((satot << 24) |
+		(srtot << 16) |
+		(sgtot <<  8) |
+		(sbtot       ));
+	break;
     default:
 	bits = 0;
 	break;
@@ -2712,7 +2883,8 @@
 			 Bool		    alpha)
 {
     /* Check for transform */
-    if (transform && pPict->transform)
+    if (transform && (pPict->transform ||
+		      pPict->filter == PictFilterConvolution))
     {
 	if (!fbBuildCompositeOperand (pPict, &op[1], 0, 0, FALSE, alpha))
 	    return FALSE;
@@ -2725,6 +2897,11 @@
 	op->u.transform.y = y - op->u.transform.top_y;
 	op->u.transform.transform = pPict->transform;
 	op->u.transform.filter = pPict->filter;
+	op->u.transform.filter_params = pPict->filter_params;
+	op->u.transform.filter_nparams = pPict->filter_nparams;
+	op->u.transform.repeat = pPict->repeat;
+	op->u.transform.width = pPict->pDrawable->width;
+	op->u.transform.height = pPict->pDrawable->height;
 	
 	op->fetch = fbFetch_transform;
 	op->fetcha = fbFetcha_transform;

Index: fbpict.c
===================================================================
RCS file: /cvs/xserver/xserver/fb/fbpict.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- fbpict.c	29 Jul 2004 08:10:15 -0000	1.31
+++ fbpict.c	26 Jan 2005 10:20:15 -0000	1.32
@@ -1422,22 +1422,42 @@
     CompositeFunc   func;
     Bool	    srcRepeat = pSrc->repeat;
     Bool	    maskRepeat = FALSE;
+    Bool	    srcTransform = pSrc->transform;
+    Bool	    maskTransform = FALSE;
     Bool	    srcAlphaMap = pSrc->alphaMap != 0;
     Bool	    maskAlphaMap = FALSE;
     Bool	    dstAlphaMap = pDst->alphaMap != 0;
     int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;
     int		    w, h, w_this, h_this;
+
+    if (pSrc->filter == PictFilterConvolution)
+	srcTransform = TRUE;
     
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
     xSrc += pSrc->pDrawable->x;
     ySrc += pSrc->pDrawable->y;
+
+    if (srcRepeat && srcTransform &&
+	pSrc->pDrawable->width == 1 &&
+	pSrc->pDrawable->height == 1)
+	srcTransform = FALSE;
+    
     if (pMask)
     {
 	xMask += pMask->pDrawable->x;
 	yMask += pMask->pDrawable->y;
 	maskRepeat = pMask->repeat;
+	maskTransform = pMask->transform;
+	if (pMask->filter == PictFilterConvolution)
+	    maskTransform = TRUE;
+	
 	maskAlphaMap = pMask->alphaMap != 0;
+
+	if (maskRepeat && maskTransform &&
+	    pMask->pDrawable->width == 1 &&
+	    pMask->pDrawable->height == 1)
+	    maskTransform = FALSE;
     }
     
     if (!miComputeCompositeRegion (&region,
@@ -1455,7 +1475,7 @@
 	return;
 				   
     func = fbCompositeGeneral;
-    if (!pSrc->transform && !(pMask && pMask->transform))
+    if (!srcTransform && !maskTransform)
     if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
     switch (op) {
     case PictOpOver:
@@ -1649,6 +1669,13 @@
 	}
 	break;
     }
+    
+    /* if we are transforming, we handle repeats in IcFetch[a]_transform */
+    if (srcTransform)
+	srcRepeat = 0;
+    if (maskTransform)
+	maskRepeat = 0;
+    
     n = REGION_NUM_RECTS (&region);
     pbox = REGION_RECTS (&region);
     while (n--)

Index: fbpict.h
===================================================================
RCS file: /cvs/xserver/xserver/fb/fbpict.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- fbpict.h	29 Jul 2004 08:10:15 -0000	1.18
+++ fbpict.h	26 Jan 2005 10:20:15 -0000	1.19
@@ -104,6 +104,11 @@
 	    int			y;
 	    PictTransformPtr	transform;
 	    int			filter;
+	    xFixed		*filter_params;
+	    int			filter_nparams;
+	    int			repeat;
+	    int			width;
+	    int			height;
 	} transform;
     } u;
     FbCompositeFetch	fetch;



More information about the xserver-commit mailing list