Optimize out computing a gradient pixel if the mask value is 0.

Obtained from:	kdrive CVS (DavidR XGL fb/ megapatch)
This commit is contained in:
Eric Anholt 2006-06-28 18:35:59 +02:00
parent a838fb70c5
commit cf46242e33

View File

@ -2635,7 +2635,8 @@ FbComposeFunctions composeFunctions = {
}; };
static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer) static void fbFetchSolid(PicturePtr pict, int x, int y, int width,
CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{ {
FbBits *bits; FbBits *bits;
FbStride stride; FbStride stride;
@ -2656,7 +2657,8 @@ static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffe
*buffer++ = color; *buffer++ = color;
} }
static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer) static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer,
CARD32 *mask, CARD32 maskBits)
{ {
FbBits *bits; FbBits *bits;
FbStride stride; FbStride stride;
@ -2711,7 +2713,8 @@ static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, uns
return pGradient->linear.colorTable[ipos]; return pGradient->linear.colorTable[ipos];
} }
static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer) static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width,
CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{ {
SourcePictPtr pGradient = pict->pSourcePict; SourcePictPtr pGradient = pict->pSourcePict;
CARD32 *end = buffer + width; CARD32 *end = buffer + width;
@ -2761,22 +2764,30 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16; inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
} }
while (buffer < end) { while (buffer < end) {
*buffer++ = gradientPixel(pGradient, t, pict->repeatType); if (mask == NULL || (*mask++ & maskBits) != 0) {
*buffer++ = gradientPixel(pGradient, t, pict->repeatType);
} else {
*buffer++ = 0; /* Set it to a value for valgrind */
}
t += inc; t += inc;
} }
} else { } else {
/* projective transformation */ /* projective transformation */
while (buffer < end) { while (buffer < end) {
xFixed_48_16 t; if (mask == NULL || (*mask++ & maskBits) != 0) {
if (v.vector[2] == 0) { xFixed_48_16 t;
t = 0; if (v.vector[2] == 0) {
} else { t = 0;
xFixed_48_16 x, y; } else {
x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2]; xFixed_48_16 x, y;
y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2]; x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
t = ((a*x + b*y) >> 16) + off; y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
} t = ((a*x + b*y) >> 16) + off;
*buffer++ = gradientPixel(pGradient, t, pict->repeatType); }
*buffer++ = gradientPixel(pGradient, t, pict->repeatType);
} else {
*buffer++ = 0; /* Set it to a value for valgrind */
}
v.vector[0] += unit.vector[0]; v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1]; v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2]; v.vector[2] += unit.vector[2];
@ -2816,37 +2827,45 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
ry -= pGradient->radial.fy; ry -= pGradient->radial.fy;
while (buffer < end) { while (buffer < end) {
double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy); if (mask == NULL || (*mask++ & maskBits) != 0) {
double c = -(rx*rx + ry*ry); double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
double det = (b * b) - (4 * pGradient->radial.a * c); double c = -(rx*rx + ry*ry);
double s = (-b + sqrt(det))/(2. * pGradient->radial.a); double det = (b * b) - (4 * pGradient->radial.a * c);
*buffer = gradientPixel(pGradient, double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536), *buffer++ = gradientPixel(pGradient,
pict->repeatType); (xFixed_48_16)((s * pGradient->radial.m +
++buffer; pGradient->radial.b) * 65536),
pict->repeatType);
} else {
*buffer++ = 0;
}
rx += cx; rx += cx;
ry += cy; ry += cy;
} }
} else { } else {
while (buffer < end) { while (buffer < end) {
double x, y; if (mask == NULL || (*mask++ & maskBits) != 0) {
double b, c, det, s; double x, y;
if (rz != 0) { double b, c, det, s;
x = rx/rz; if (rz != 0) {
y = ry/rz; x = rx/rz;
} else { y = ry/rz;
x = y = 0.; } else {
} x = y = 0.;
x -= pGradient->radial.fx; }
y -= pGradient->radial.fy; x -= pGradient->radial.fx;
b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy); y -= pGradient->radial.fy;
c = -(x*x + y*y); b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
det = (b * b) - (4 * pGradient->radial.a * c); c = -(x*x + y*y);
s = (-b + sqrt(det))/(2. * pGradient->radial.a); det = (b * b) - (4 * pGradient->radial.a * c);
*buffer = gradientPixel(pGradient, s = (-b + sqrt(det))/(2. * pGradient->radial.a);
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536), *buffer++ = gradientPixel(pGradient,
pict->repeatType); (xFixed_48_16)((s * pGradient->radial.m +
++buffer; pGradient->radial.b) * 65536),
pict->repeatType);
} else {
*buffer++ = 0;
}
rx += cx; rx += cx;
ry += cy; ry += cy;
rz += cz; rz += cz;
@ -2859,29 +2878,37 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
ry -= pGradient->conical.center.y/65536.; ry -= pGradient->conical.center.y/65536.;
while (buffer < end) { while (buffer < end) {
double angle = atan2(ry, rx) + a; if (mask == NULL || (*mask++ & maskBits) != 0) {
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))), double angle = atan2(ry, rx) + a;
pict->repeatType); *buffer++ = gradientPixel(pGradient,
++buffer; (xFixed_48_16) (angle * (65536. / (2*M_PI))),
pict->repeatType);
} else {
*buffer++ = 0;
}
rx += cx; rx += cx;
ry += cy; ry += cy;
} }
} else { } else {
while (buffer < end) { while (buffer < end) {
double x, y, angle; if (mask == NULL || (*mask++ & maskBits) != 0) {
if (rz != 0) { double x, y, angle;
x = rx/rz; if (rz != 0) {
y = ry/rz; x = rx/rz;
} else { y = ry/rz;
x = y = 0.; } else {
} x = y = 0.;
x -= pGradient->conical.center.x/65536.; }
y -= pGradient->conical.center.y/65536.; x -= pGradient->conical.center.x/65536.;
angle = atan2(y, x) + a; y -= pGradient->conical.center.y/65536.;
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))), angle = atan2(y, x) + a;
pict->repeatType); *buffer++ = gradientPixel(pGradient, (xFixed_48_16)
++buffer; (angle * (65536. / (2*M_PI))),
pict->repeatType);
} else {
*buffer++ = 0;
}
rx += cx; rx += cx;
ry += cy; ry += cy;
rz += cz; rz += cz;
@ -2893,7 +2920,8 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer) static void fbFetchTransformed(PicturePtr pict, int x, int y, int width,
CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{ {
FbBits *bits; FbBits *bits;
FbStride stride; FbStride stride;
@ -3357,21 +3385,24 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
} }
static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer) static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width,
CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{ {
int i; int i;
CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH]; CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
CARD32 *alpha_buffer = _alpha_buffer; CARD32 *alpha_buffer = _alpha_buffer;
if (!pict->alphaMap) { if (!pict->alphaMap) {
fbFetchTransformed(pict, x, y, width, buffer); fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
return; return;
} }
if (width > SCANLINE_BUFFER_LENGTH) if (width > SCANLINE_BUFFER_LENGTH)
alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32)); alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
fbFetchTransformed(pict, x, y, width, buffer); fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer); fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
y - pict->alphaOrigin.y, width, alpha_buffer,
mask, maskBits);
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
int a = alpha_buffer[i]>>24; int a = alpha_buffer[i]>>24;
buffer[i] = (a << 24) buffer[i] = (a << 24)
@ -3441,7 +3472,8 @@ static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD3
} }
typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *); typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *); typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *,
CARD32 *, CARD32);
static void static void
fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer) fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
@ -3503,12 +3535,16 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
for (i = 0; i < data->height; ++i) for (i = 0; i < data->height; ++i)
{ {
/* fill first half of scanline with source */ /* fill first half of scanline with source */
fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer); fetchMask(data->mask, data->xMask, data->yMask + i, data->width,
fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer); mask_buffer, NULL, 0);
fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width,
src_buffer, mask_buffer, 0);
/* fill dest into second half of scanline */ /* fill dest into second half of scanline */
if (fetchDest) if (fetchDest) {
fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); fetchDest(data->dest, data->xDest, data->yDest + i, data->width,
dest_buffer, NULL, 0);
}
/* blend */ /* blend */
compose(dest_buffer, src_buffer, mask_buffer, data->width); compose(dest_buffer, src_buffer, mask_buffer, data->width);
@ -3517,17 +3553,27 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
} }
} else { } else {
CARD32 *mask_buffer;
CombineFuncU compose = composeFunctions.combineU[data->op]; CombineFuncU compose = composeFunctions.combineU[data->op];
if (!compose) if (!compose)
return; return;
if (fetchMask)
mask_buffer = dest_buffer + data->width;
else
mask_buffer = NULL;
if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) { if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
if (fetchMask) { if (fetchMask) {
fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer); fetchMask(data->mask, data->xMask, data->yMask, data->width,
composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width); dest_buffer, NULL, 0);
} }
fetchSrc(data->src, data->xSrc, data->ySrc, data->width,
src_buffer, mask_buffer, 0xff000000);
if (mask_buffer != NULL) {
composeFunctions.combineMaskU(src_buffer, dest_buffer,
data->width);
}
fetchSrc = NULL; fetchSrc = NULL;
fetchMask = NULL; fetchMask = NULL;
} }
@ -3536,18 +3582,27 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
{ {
/* fill first half of scanline with source */ /* fill first half of scanline with source */
if (fetchSrc) { if (fetchSrc) {
fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer); /* Fetch mask before source so that fetching of source can be
* optimized out if possible.
*/
if (fetchMask) {
fetchMask(data->mask, data->xMask, data->yMask + i,
data->width, dest_buffer, NULL, 0);
}
fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width,
src_buffer, mask_buffer, 0xff000000);
/* add in mask */ /* add in mask */
if (fetchMask) { if (mask_buffer != NULL) {
fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width); composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
} }
} }
/* fill dest into second half of scanline */ /* fill dest into second half of scanline */
if (fetchDest) if (fetchDest != NULL) {
fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer); fetchDest(data->dest, data->xDest, data->yDest + i, data->width,
dest_buffer, NULL, 0);
}
/* blend */ /* blend */
compose(dest_buffer, src_buffer, data->width); compose(dest_buffer, src_buffer, data->width);