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 (®ion,
@@ -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 (®ion);
pbox = REGION_RECTS (®ion);
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