Merge David Reveman's gradient optimization patch from pixman
This commit is contained in:
parent
d0e55774e0
commit
0a9239ec25
507
fb/fbcompose.c
507
fb/fbcompose.c
|
@ -40,6 +40,65 @@
|
||||||
#include "mipict.h"
|
#include "mipict.h"
|
||||||
#include "fbpict.h"
|
#include "fbpict.h"
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
SourcePictureClassify (PicturePtr pict,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
if (pict->pSourcePict->type == SourcePictTypeSolidFill)
|
||||||
|
{
|
||||||
|
pict->pSourcePict->solidFill.class = SourcePictClassHorizontal;
|
||||||
|
}
|
||||||
|
else if (pict->pSourcePict->type == SourcePictTypeLinear)
|
||||||
|
{
|
||||||
|
PictVector v;
|
||||||
|
xFixed_32_32 l;
|
||||||
|
xFixed_48_16 dx, dy, a, b, off;
|
||||||
|
xFixed_48_16 factors[4];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dx = pict->pSourcePict->linear.p2.x - pict->pSourcePict->linear.p1.x;
|
||||||
|
dy = pict->pSourcePict->linear.p2.y - pict->pSourcePict->linear.p1.y;
|
||||||
|
l = dx * dx + dy * dy;
|
||||||
|
if (l)
|
||||||
|
{
|
||||||
|
a = (dx << 32) / l;
|
||||||
|
b = (dy << 32) / l;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a = b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
off = (-a * pict->pSourcePict->linear.p1.x
|
||||||
|
-b * pict->pSourcePict->linear.p1.y) >> 16;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
v.vector[0] = IntToxFixed ((i % 2) * (width - 1) + x);
|
||||||
|
v.vector[1] = IntToxFixed ((i / 2) * (height - 1) + y);
|
||||||
|
v.vector[2] = xFixed1;
|
||||||
|
|
||||||
|
if (pict->transform)
|
||||||
|
{
|
||||||
|
if (!PictureTransformPoint3d (pict->transform, &v))
|
||||||
|
return SourcePictClassUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (factors[2] == factors[0])
|
||||||
|
pict->pSourcePict->linear.class = SourcePictClassHorizontal;
|
||||||
|
else if (factors[1] == factors[0])
|
||||||
|
pict->pSourcePict->linear.class = SourcePictClassVertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pict->pSourcePict->solidFill.class;
|
||||||
|
}
|
||||||
|
|
||||||
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
|
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
|
||||||
|
|
||||||
#define SCANLINE_BUFFER_LENGTH 2048
|
#define SCANLINE_BUFFER_LENGTH 2048
|
||||||
|
@ -2634,7 +2693,7 @@ 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 +2715,7 @@ static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffe
|
||||||
fbFinishAccess (pict->pDrawable);
|
fbFinishAccess (pict->pDrawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -2679,40 +2738,75 @@ static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
|
||||||
#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
|
#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
|
||||||
((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
|
((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
|
||||||
|
|
||||||
|
static CARD32
|
||||||
|
xRenderColorMultToCard32 (xRenderColor *c)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
((((CARD32) c->red * c->alpha) >> 24) << 16) |
|
||||||
|
((((CARD32) c->green * c->alpha) >> 24) << 8) |
|
||||||
|
((((CARD32) c->blue * c->alpha) >> 24) << 0) |
|
||||||
|
((((CARD32) c->alpha ) >> 8) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
|
static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
|
||||||
{
|
{
|
||||||
int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
|
int ipos = (pos * pGradient->gradient.stopRange - 1) >> 16;
|
||||||
|
|
||||||
/* calculate the actual offset. */
|
/* calculate the actual offset. */
|
||||||
if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
|
if (ipos < 0 || ipos >= pGradient->gradient.stopRange)
|
||||||
if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
|
{
|
||||||
ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
|
if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal)
|
||||||
ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
|
{
|
||||||
|
ipos = ipos % pGradient->gradient.stopRange;
|
||||||
|
ipos = ipos < 0 ? pGradient->gradient.stopRange + ipos : ipos;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (spread == RepeatReflect)
|
||||||
|
{
|
||||||
|
const int limit = pGradient->gradient.stopRange * 2 - 1;
|
||||||
|
|
||||||
} else if (spread == RepeatReflect) {
|
|
||||||
const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
|
|
||||||
ipos = ipos % limit;
|
ipos = ipos % limit;
|
||||||
ipos = ipos < 0 ? limit + ipos : ipos;
|
ipos = ipos < 0 ? limit + ipos : ipos;
|
||||||
ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
|
ipos = ipos >= pGradient->gradient.stopRange ? limit - ipos : ipos;
|
||||||
|
|
||||||
} else if (spread == RepeatPad) {
|
}
|
||||||
|
else if (spread == RepeatPad)
|
||||||
|
{
|
||||||
if (ipos < 0)
|
if (ipos < 0)
|
||||||
ipos = 0;
|
ipos = 0;
|
||||||
else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
|
else
|
||||||
ipos = PICT_GRADIENT_STOPTABLE_SIZE-1;
|
ipos = pGradient->gradient.stopRange - 1;
|
||||||
} else { /* RepeatNone */
|
}
|
||||||
|
else /* RepeatNone */
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(ipos >= 0);
|
if (pGradient->gradient.colorTableSize)
|
||||||
assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
|
{
|
||||||
|
return pGradient->gradient.colorTable[ipos];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
return pGradient->linear.colorTable[ipos];
|
if (ipos <= pGradient->gradient.stops->x)
|
||||||
|
return xRenderColorMultToCard32 (&pGradient->gradient.stops->color);
|
||||||
|
|
||||||
|
for (i = 1; i < pGradient->gradient.nstops; i++)
|
||||||
|
{
|
||||||
|
if (pGradient->gradient.stops[i].x >= ipos)
|
||||||
|
return PictureGradientColor (&pGradient->gradient.stops[i - 1],
|
||||||
|
&pGradient->gradient.stops[i],
|
||||||
|
ipos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
|
return xRenderColorMultToCard32 (&pGradient->gradient.stops[--i].color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,14 +2855,58 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
|
||||||
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
|
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
|
||||||
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
|
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pGradient->linear.class == SourcePictClassVertical)
|
||||||
|
{
|
||||||
|
register CARD32 color;
|
||||||
|
|
||||||
|
color = gradientPixel (pGradient, t, pict->repeat);
|
||||||
|
while (buffer < end)
|
||||||
|
*buffer++ = color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (buffer < end) {
|
while (buffer < end) {
|
||||||
WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
|
if (!mask || *mask++ & maskBits)
|
||||||
|
{
|
||||||
|
*buffer = gradientPixel (pGradient, t, pict->repeat);
|
||||||
|
}
|
||||||
|
++buffer;
|
||||||
t += inc;
|
t += inc;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
/* projective transformation */
|
}
|
||||||
while (buffer < end) {
|
else /* projective transformation */
|
||||||
|
{
|
||||||
xFixed_48_16 t;
|
xFixed_48_16 t;
|
||||||
|
|
||||||
|
if (pGradient->linear.class == SourcePictClassVertical)
|
||||||
|
{
|
||||||
|
register CARD32 color;
|
||||||
|
|
||||||
|
if (v.vector[2] == 0)
|
||||||
|
{
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xFixed_48_16 x, y;
|
||||||
|
|
||||||
|
x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
|
||||||
|
y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
|
||||||
|
t = ((a * x + b * y) >> 16) + off;
|
||||||
|
}
|
||||||
|
|
||||||
|
color = gradientPixel (pGradient, t, pict->repeat);
|
||||||
|
while (buffer < end)
|
||||||
|
*buffer++ = color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (buffer < end)
|
||||||
|
{
|
||||||
|
if (!mask || *mask++ & maskBits)
|
||||||
|
{
|
||||||
if (v.vector[2] == 0) {
|
if (v.vector[2] == 0) {
|
||||||
t = 0;
|
t = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2777,12 +2915,15 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
|
||||||
y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
|
y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
|
||||||
t = ((a*x + b*y) >> 16) + off;
|
t = ((a*x + b*y) >> 16) + off;
|
||||||
}
|
}
|
||||||
WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
|
*buffer = gradientPixel(pGradient, t, pict->repeat);
|
||||||
|
}
|
||||||
|
++buffer;
|
||||||
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* radial or conical */
|
/* radial or conical */
|
||||||
Bool affine = TRUE;
|
Bool affine = TRUE;
|
||||||
|
@ -2817,14 +2958,20 @@ 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);
|
double b, c, det, s;
|
||||||
double c = -(rx*rx + ry*ry);
|
|
||||||
double det = (b * b) - (4 * pGradient->radial.a * c);
|
if (!mask || *mask++ & maskBits)
|
||||||
double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
|
{
|
||||||
|
b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
|
||||||
|
c = -(rx*rx + ry*ry);
|
||||||
|
det = (b * b) - (4 * pGradient->radial.a * c);
|
||||||
|
s = (-b + sqrt(det))/(2. * pGradient->radial.a);
|
||||||
WRITE(buffer, gradientPixel(pGradient,
|
WRITE(buffer, gradientPixel(pGradient,
|
||||||
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
|
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
|
||||||
pict->repeatType));
|
pict->repeatType));
|
||||||
|
}
|
||||||
++buffer;
|
++buffer;
|
||||||
|
|
||||||
rx += cx;
|
rx += cx;
|
||||||
ry += cy;
|
ry += cy;
|
||||||
}
|
}
|
||||||
|
@ -2832,6 +2979,9 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
|
||||||
while (buffer < end) {
|
while (buffer < end) {
|
||||||
double x, y;
|
double x, y;
|
||||||
double b, c, det, s;
|
double b, c, det, s;
|
||||||
|
|
||||||
|
if (!mask || *mask++ & maskBits)
|
||||||
|
{
|
||||||
if (rz != 0) {
|
if (rz != 0) {
|
||||||
x = rx/rz;
|
x = rx/rz;
|
||||||
y = ry/rz;
|
y = ry/rz;
|
||||||
|
@ -2844,10 +2994,12 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
|
||||||
c = -(x*x + y*y);
|
c = -(x*x + y*y);
|
||||||
det = (b * b) - (4 * pGradient->radial.a * c);
|
det = (b * b) - (4 * pGradient->radial.a * c);
|
||||||
s = (-b + sqrt(det))/(2. * pGradient->radial.a);
|
s = (-b + sqrt(det))/(2. * pGradient->radial.a);
|
||||||
WRITE(buffer, gradientPixel(pGradient,
|
*buffer = gradientPixel(pGradient,
|
||||||
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
|
(xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
|
||||||
pict->repeatType));
|
pict->repeat);
|
||||||
|
}
|
||||||
++buffer;
|
++buffer;
|
||||||
|
|
||||||
rx += cx;
|
rx += cx;
|
||||||
ry += cy;
|
ry += cy;
|
||||||
rz += cz;
|
rz += cz;
|
||||||
|
@ -2860,17 +3012,25 @@ 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;
|
double angle;
|
||||||
WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
|
|
||||||
pict->repeatType));
|
if (!mask || *mask++ & maskBits)
|
||||||
|
{
|
||||||
|
angle = atan2(ry, rx) + a;
|
||||||
|
|
||||||
|
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
|
||||||
|
pict->repeat);
|
||||||
|
}
|
||||||
|
|
||||||
++buffer;
|
++buffer;
|
||||||
rx += cx;
|
rx += cx;
|
||||||
ry += cy;
|
ry += cy;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
while (buffer < end) {
|
while (buffer < end) {
|
||||||
double x, y, angle;
|
double x, y, angle;
|
||||||
|
if (!mask || *mask++ & maskBits)
|
||||||
|
{
|
||||||
if (rz != 0) {
|
if (rz != 0) {
|
||||||
x = rx/rz;
|
x = rx/rz;
|
||||||
y = ry/rz;
|
y = ry/rz;
|
||||||
|
@ -2880,8 +3040,9 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
|
||||||
x -= pGradient->conical.center.x/65536.;
|
x -= pGradient->conical.center.x/65536.;
|
||||||
y -= pGradient->conical.center.y/65536.;
|
y -= pGradient->conical.center.y/65536.;
|
||||||
angle = atan2(y, x) + a;
|
angle = atan2(y, x) + a;
|
||||||
WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
|
*buffer = gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
|
||||||
pict->repeatType));
|
pict->repeat);
|
||||||
|
}
|
||||||
++buffer;
|
++buffer;
|
||||||
rx += cx;
|
rx += cx;
|
||||||
ry += cy;
|
ry += cy;
|
||||||
|
@ -2892,9 +3053,7 @@ 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, CARD32 *mask, CARD32 maskBits)
|
||||||
|
|
||||||
static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
|
|
||||||
{
|
{
|
||||||
FbBits *bits;
|
FbBits *bits;
|
||||||
FbStride stride;
|
FbStride stride;
|
||||||
|
@ -2943,8 +3102,10 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
if (pict->repeatType == RepeatNormal) {
|
if (pict->repeatType == RepeatNormal) {
|
||||||
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
buffer[i] = 0;
|
||||||
} else {
|
} else {
|
||||||
if (!affine) {
|
if (!affine) {
|
||||||
y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
|
y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
|
||||||
|
@ -2953,16 +3114,20 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
y = MOD(v.vector[1]>>16, pict->pDrawable->height);
|
y = MOD(v.vector[1]>>16, pict->pDrawable->height);
|
||||||
x = MOD(v.vector[0]>>16, pict->pDrawable->width);
|
x = MOD(v.vector[0]>>16, pict->pDrawable->width);
|
||||||
}
|
}
|
||||||
WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
|
buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
buffer[i] = 0;
|
||||||
} else {
|
} else {
|
||||||
if (!affine) {
|
if (!affine) {
|
||||||
y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
|
y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
|
||||||
|
@ -2971,11 +3136,13 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
y = MOD(v.vector[1]>>16, pict->pDrawable->height);
|
y = MOD(v.vector[1]>>16, pict->pDrawable->height);
|
||||||
x = MOD(v.vector[0]>>16, pict->pDrawable->width);
|
x = MOD(v.vector[0]>>16, pict->pDrawable->width);
|
||||||
}
|
}
|
||||||
if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
|
if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
|
||||||
WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
|
buffer[i] = fetch(bits + (y + pict->pDrawable->y)*stride, x + pict->pDrawable->x, indexed);
|
||||||
else
|
else
|
||||||
WRITE(buffer + i, 0);
|
buffer[i] = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -2985,6 +3152,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||||
box = pict->pCompositeClip->extents;
|
box = pict->pCompositeClip->extents;
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2998,12 +3167,15 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
|
WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
|
||||||
0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
|
0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3019,6 +3191,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
else
|
else
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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];
|
||||||
|
@ -3035,6 +3208,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
if (pict->repeatType == RepeatNormal) {
|
if (pict->repeatType == RepeatNormal) {
|
||||||
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3090,12 +3265,15 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
||||||
WRITE(buffer + i, r);
|
WRITE(buffer + i, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3155,6 +3333,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
||||||
WRITE(buffer + i, r);
|
WRITE(buffer + i, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -3164,6 +3344,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
|
||||||
box = pict->pCompositeClip->extents;
|
box = pict->pCompositeClip->extents;
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3221,12 +3403,16 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
||||||
WRITE(buffer + i, r);
|
WRITE(buffer + i, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3282,6 +3468,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
|
||||||
WRITE(buffer + i, r);
|
WRITE(buffer + i, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -3296,6 +3484,8 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
int yoff = (params[1] - xFixed1) >> 1;
|
int yoff = (params[1] - xFixed1) >> 1;
|
||||||
params += 2;
|
params += 2;
|
||||||
for (i = 0; i < width; ++i) {
|
for (i = 0; i < width; ++i) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
if (!v.vector[2]) {
|
if (!v.vector[2]) {
|
||||||
WRITE(buffer + i, 0);
|
WRITE(buffer + i, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3352,6 +3542,7 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
|
||||||
(sgtot << 8) |
|
(sgtot << 8) |
|
||||||
(sbtot )));
|
(sbtot )));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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];
|
||||||
|
@ -3362,28 +3553,33 @@ 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) {
|
||||||
|
if (!mask || mask[i] & maskBits)
|
||||||
|
{
|
||||||
int a = alpha_buffer[i]>>24;
|
int a = alpha_buffer[i]>>24;
|
||||||
WRITE(buffer + i, (a << 24)
|
WRITE(buffer + i, (a << 24)
|
||||||
| (div_255(Red(READ(buffer + i)) * a) << 16)
|
| (div_255(Red(READ(buffer + i)) * a) << 16)
|
||||||
| (div_255(Green(READ(buffer + i)) * a) << 8)
|
| (div_255(Green(READ(buffer + i)) * a) << 8)
|
||||||
| (div_255(Blue(READ(buffer + i)) * a)));
|
| (div_255(Blue(READ(buffer + i)) * a)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (alpha_buffer != _alpha_buffer)
|
if (alpha_buffer != _alpha_buffer)
|
||||||
free(alpha_buffer);
|
free(alpha_buffer);
|
||||||
|
@ -3450,7 +3646,7 @@ 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)
|
||||||
|
@ -3460,17 +3656,30 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
||||||
int i;
|
int i;
|
||||||
scanStoreProc store;
|
scanStoreProc store;
|
||||||
scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
|
scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
|
||||||
|
unsigned int srcClass = SourcePictClassUnknown;
|
||||||
|
unsigned int maskClass = SourcePictClassUnknown;
|
||||||
|
FbBits *bits;
|
||||||
|
FbStride stride;
|
||||||
|
int xoff, yoff;
|
||||||
|
|
||||||
if (data->op == PictOpClear)
|
if (data->op == PictOpClear)
|
||||||
fetchSrc = NULL;
|
fetchSrc = NULL;
|
||||||
else if (!data->src->pDrawable) {
|
else if (!data->src->pDrawable) {
|
||||||
if (data->src->pSourcePict)
|
if (data->src->pSourcePict)
|
||||||
|
{
|
||||||
fetchSrc = fbFetchSourcePict;
|
fetchSrc = fbFetchSourcePict;
|
||||||
|
srcClass = SourcePictureClassify (data->src,
|
||||||
|
data->xSrc, data->ySrc,
|
||||||
|
data->width, data->height);
|
||||||
|
}
|
||||||
} else if (data->src->alphaMap)
|
} else if (data->src->alphaMap)
|
||||||
fetchSrc = fbFetchExternalAlpha;
|
fetchSrc = fbFetchExternalAlpha;
|
||||||
else if (data->src->repeatType == RepeatNormal &&
|
else if (data->src->repeatType == RepeatNormal &&
|
||||||
data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
|
data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
|
||||||
|
{
|
||||||
fetchSrc = fbFetchSolid;
|
fetchSrc = fbFetchSolid;
|
||||||
|
srcClass = SourcePictClassHorizontal;
|
||||||
|
}
|
||||||
else if (!data->src->transform && data->src->filter != PictFilterConvolution)
|
else if (!data->src->transform && data->src->filter != PictFilterConvolution)
|
||||||
fetchSrc = fbFetch;
|
fetchSrc = fbFetch;
|
||||||
else
|
else
|
||||||
|
@ -3481,10 +3690,18 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
||||||
if (data->mask->pSourcePict)
|
if (data->mask->pSourcePict)
|
||||||
fetchMask = fbFetchSourcePict;
|
fetchMask = fbFetchSourcePict;
|
||||||
} else if (data->mask->alphaMap)
|
} else if (data->mask->alphaMap)
|
||||||
|
{
|
||||||
fetchMask = fbFetchExternalAlpha;
|
fetchMask = fbFetchExternalAlpha;
|
||||||
|
maskClass = SourcePictureClassify (data->mask,
|
||||||
|
data->xMask, data->yMask,
|
||||||
|
data->width, data->height);
|
||||||
|
}
|
||||||
else if (data->mask->repeatType == RepeatNormal
|
else if (data->mask->repeatType == RepeatNormal
|
||||||
&& data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
|
&& data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
|
||||||
|
{
|
||||||
fetchMask = fbFetchSolid;
|
fetchMask = fbFetchSolid;
|
||||||
|
maskClass = SourcePictClassHorizontal;
|
||||||
|
}
|
||||||
else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
|
else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
|
||||||
fetchMask = fbFetch;
|
fetchMask = fbFetch;
|
||||||
else
|
else
|
||||||
|
@ -3493,76 +3710,204 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
|
||||||
fetchMask = NULL;
|
fetchMask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->dest->alphaMap) {
|
if (data->dest->alphaMap)
|
||||||
|
{
|
||||||
fetchDest = fbFetchExternalAlpha;
|
fetchDest = fbFetchExternalAlpha;
|
||||||
store = fbStoreExternalAlpha;
|
store = fbStoreExternalAlpha;
|
||||||
} else {
|
|
||||||
fetchDest = fbFetch;
|
|
||||||
store = fbStore;
|
|
||||||
}
|
|
||||||
if (data->op == PictOpClear || data->op == PictOpSrc)
|
if (data->op == PictOpClear || data->op == PictOpSrc)
|
||||||
fetchDest = NULL;
|
fetchDest = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetchDest = fbFetch;
|
||||||
|
store = fbStore;
|
||||||
|
|
||||||
if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) {
|
switch (data->op) {
|
||||||
|
case PictOpClear:
|
||||||
|
case PictOpSrc:
|
||||||
|
fetchDest = NULL;
|
||||||
|
/* fall-through */
|
||||||
|
case PictOpAdd:
|
||||||
|
case PictOpOver:
|
||||||
|
switch (data->dest->format) {
|
||||||
|
case PICT_a8r8g8b8:
|
||||||
|
case PICT_x8r8g8b8:
|
||||||
|
store = NULL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!store)
|
||||||
|
{
|
||||||
|
int bpp;
|
||||||
|
|
||||||
|
fbGetDrawable (data->dest->pDrawable, bits, stride, bpp, xoff, yoff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bits = NULL;
|
||||||
|
stride = 0;
|
||||||
|
xoff = yoff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetchSrc &&
|
||||||
|
fetchMask &&
|
||||||
|
data->mask &&
|
||||||
|
data->mask->componentAlpha &&
|
||||||
|
PICT_FORMAT_RGB (data->mask->format))
|
||||||
|
{
|
||||||
CARD32 *mask_buffer = dest_buffer + data->width;
|
CARD32 *mask_buffer = dest_buffer + data->width;
|
||||||
CombineFuncC compose = composeFunctions.combineC[data->op];
|
CombineFuncC compose = composeFunctions.combineC[data->op];
|
||||||
if (!compose)
|
if (!compose)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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);
|
if (fetchSrc)
|
||||||
fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer);
|
{
|
||||||
|
if (fetchMask)
|
||||||
|
{
|
||||||
|
/* fetch mask before source so that fetching of
|
||||||
|
source can be optimized */
|
||||||
|
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||||
|
data->width, mask_buffer, 0, 0);
|
||||||
|
|
||||||
|
if (maskClass == SourcePictClassHorizontal)
|
||||||
|
fetchMask = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srcClass == SourcePictClassHorizontal)
|
||||||
|
{
|
||||||
|
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||||
|
data->width, src_buffer, 0, 0);
|
||||||
|
fetchSrc = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||||
|
data->width, src_buffer, mask_buffer,
|
||||||
|
0xffffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fetchMask)
|
||||||
|
{
|
||||||
|
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||||
|
data->width, mask_buffer, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store)
|
||||||
|
{
|
||||||
/* 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, 0, 0);
|
||||||
|
|
||||||
/* blend */
|
/* blend */
|
||||||
compose (dest_buffer, src_buffer, mask_buffer, data->width);
|
compose (dest_buffer, src_buffer, mask_buffer, data->width);
|
||||||
|
|
||||||
/* write back */
|
/* write back */
|
||||||
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
|
||||||
|
{
|
||||||
|
/* blend */
|
||||||
|
compose (bits + (data->yDest + i+ yoff) * stride +
|
||||||
|
data->xDest + xoff,
|
||||||
|
src_buffer, mask_buffer, data->width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CARD32 *src_mask_buffer = 0, *mask_buffer = 0;
|
||||||
CombineFuncU compose = composeFunctions.combineU[data->op];
|
CombineFuncU compose = composeFunctions.combineU[data->op];
|
||||||
if (!compose)
|
if (!compose)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
|
if (fetchMask)
|
||||||
fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
|
mask_buffer = dest_buffer + data->width;
|
||||||
if (fetchMask) {
|
|
||||||
fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer);
|
for (i = 0; i < data->height; ++i) {
|
||||||
composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
|
/* fill first half of scanline with source */
|
||||||
}
|
if (fetchSrc)
|
||||||
fetchSrc = NULL;
|
{
|
||||||
|
if (fetchMask)
|
||||||
|
{
|
||||||
|
/* fetch mask before source so that fetching of
|
||||||
|
source can be optimized */
|
||||||
|
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||||
|
data->width, mask_buffer, 0, 0);
|
||||||
|
|
||||||
|
if (maskClass == SourcePictClassHorizontal)
|
||||||
fetchMask = NULL;
|
fetchMask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < data->height; ++i)
|
if (srcClass == SourcePictClassHorizontal)
|
||||||
{
|
{
|
||||||
/* fill first half of scanline with source */
|
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||||
if (fetchSrc) {
|
data->width, src_buffer, 0, 0);
|
||||||
fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
|
|
||||||
|
|
||||||
/* add in mask */
|
if (mask_buffer)
|
||||||
if (fetchMask) {
|
{
|
||||||
fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
|
fbCombineInU (mask_buffer, src_buffer, data->width);
|
||||||
composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
|
src_mask_buffer = mask_buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
src_mask_buffer = src_buffer;
|
||||||
|
|
||||||
|
fetchSrc = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetchSrc (data->src, data->xSrc, data->ySrc + i,
|
||||||
|
data->width, src_buffer, mask_buffer,
|
||||||
|
0xff000000);
|
||||||
|
|
||||||
|
if (mask_buffer)
|
||||||
|
composeFunctions.combineMaskU (src_buffer,
|
||||||
|
mask_buffer,
|
||||||
|
data->width);
|
||||||
|
|
||||||
|
src_mask_buffer = src_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (fetchMask)
|
||||||
|
{
|
||||||
|
fetchMask (data->mask, data->xMask, data->yMask + i,
|
||||||
|
data->width, mask_buffer, 0, 0);
|
||||||
|
|
||||||
|
fbCombineInU (mask_buffer, src_buffer, data->width);
|
||||||
|
|
||||||
|
src_mask_buffer = mask_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store)
|
||||||
|
{
|
||||||
/* 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, 0, 0);
|
||||||
|
|
||||||
/* blend */
|
/* blend */
|
||||||
compose(dest_buffer, src_buffer, data->width);
|
compose (dest_buffer, src_mask_buffer, data->width);
|
||||||
|
|
||||||
/* write back */
|
/* write back */
|
||||||
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
|
||||||
|
{
|
||||||
|
/* blend */
|
||||||
|
compose (bits + (data->yDest + i+ yoff) * stride +
|
||||||
|
data->xDest + xoff,
|
||||||
|
src_mask_buffer, data->width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -890,54 +890,22 @@ static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initGradientColorTable(SourcePictPtr pGradient, int *error)
|
CARD32
|
||||||
|
PictureGradientColor (PictGradientStopPtr stop1,
|
||||||
|
PictGradientStopPtr stop2,
|
||||||
|
CARD32 x)
|
||||||
{
|
{
|
||||||
int begin_pos, end_pos;
|
CARD32 current_color, next_color;
|
||||||
xFixed incr, dpos;
|
int dist, idist;
|
||||||
int pos, current_stop;
|
|
||||||
PictGradientStopPtr stops = pGradient->linear.stops;
|
|
||||||
int nstops = pGradient->linear.nstops;
|
|
||||||
|
|
||||||
/* The position where the gradient begins and ends */
|
current_color = xRenderColorToCard32 (stop1->color);
|
||||||
begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
|
next_color = xRenderColorToCard32 (stop2->color);
|
||||||
end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
|
|
||||||
|
|
||||||
pos = 0; /* The position in the color table. */
|
dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
|
||||||
|
idist = 256 - dist;
|
||||||
|
|
||||||
/* Up to first point */
|
return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
|
||||||
while (pos <= begin_pos) {
|
next_color, dist));
|
||||||
pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
|
|
||||||
dpos = incr * pos; /* The position in terms of 0-1. */
|
|
||||||
|
|
||||||
current_stop = 0; /* We always interpolate between current and current + 1. */
|
|
||||||
|
|
||||||
/* Gradient area */
|
|
||||||
while (pos < end_pos) {
|
|
||||||
unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
|
|
||||||
unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
|
|
||||||
|
|
||||||
int dist = (int)(256*(dpos - stops[current_stop].x)
|
|
||||||
/ (stops[current_stop+1].x - stops[current_stop].x));
|
|
||||||
int idist = 256 - dist;
|
|
||||||
|
|
||||||
pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
|
|
||||||
|
|
||||||
++pos;
|
|
||||||
dpos += incr;
|
|
||||||
|
|
||||||
if (dpos > stops[current_stop + 1].x)
|
|
||||||
++current_stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* After last point */
|
|
||||||
while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
|
|
||||||
pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initGradient(SourcePictPtr pGradient, int stopCount,
|
static void initGradient(SourcePictPtr pGradient, int stopCount,
|
||||||
|
@ -953,26 +921,30 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
|
||||||
|
|
||||||
dpos = -1;
|
dpos = -1;
|
||||||
for (i = 0; i < stopCount; ++i) {
|
for (i = 0; i < stopCount; ++i) {
|
||||||
if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
|
if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) {
|
||||||
*error = BadValue;
|
*error = BadValue;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dpos = stopPoints[i];
|
dpos = stopPoints[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
|
pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop));
|
||||||
if (!pGradient->linear.stops) {
|
if (!pGradient->gradient.stops) {
|
||||||
*error = BadAlloc;
|
*error = BadAlloc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pGradient->linear.nstops = stopCount;
|
pGradient->gradient.nstops = stopCount;
|
||||||
|
|
||||||
for (i = 0; i < stopCount; ++i) {
|
for (i = 0; i < stopCount; ++i) {
|
||||||
pGradient->linear.stops[i].x = stopPoints[i];
|
pGradient->gradient.stops[i].x = stopPoints[i];
|
||||||
pGradient->linear.stops[i].color = stopColors[i];
|
pGradient->gradient.stops[i].color = stopColors[i];
|
||||||
}
|
}
|
||||||
initGradientColorTable(pGradient, error);
|
|
||||||
|
pGradient->gradient.class = SourcePictClassUnknown;
|
||||||
|
pGradient->gradient.stopRange = 0xffff;
|
||||||
|
pGradient->gradient.colorTable = NULL;
|
||||||
|
pGradient->gradient.colorTableSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PicturePtr createSourcePicture(void)
|
static PicturePtr createSourcePicture(void)
|
||||||
|
@ -980,9 +952,9 @@ static PicturePtr createSourcePicture(void)
|
||||||
PicturePtr pPicture;
|
PicturePtr pPicture;
|
||||||
pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
|
pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
|
||||||
pPicture->pDrawable = 0;
|
pPicture->pDrawable = 0;
|
||||||
pPicture->format = PICT_a8r8g8b8;
|
|
||||||
pPicture->pFormat = 0;
|
pPicture->pFormat = 0;
|
||||||
pPicture->pNext = 0;
|
pPicture->pNext = 0;
|
||||||
|
pPicture->format = PICT_a8r8g8b8;
|
||||||
pPicture->devPrivates = 0;
|
pPicture->devPrivates = 0;
|
||||||
|
|
||||||
SetPictureToDefaults(pPicture);
|
SetPictureToDefaults(pPicture);
|
||||||
|
@ -1027,10 +999,6 @@ CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
|
||||||
*error = BadAlloc;
|
*error = BadAlloc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (p1->x == p2->x && p1->y == p2->y) {
|
|
||||||
*error = BadValue;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pPicture->id = pid;
|
pPicture->id = pid;
|
||||||
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
|
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
|
||||||
|
@ -1072,14 +1040,6 @@ CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer
|
||||||
*error = BadAlloc;
|
*error = BadAlloc;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
double dx = (double)(inner->x - outer->x);
|
|
||||||
double dy = (double)(inner->y - outer->y);
|
|
||||||
if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
|
|
||||||
*error = BadValue;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pPicture->id = pid;
|
pPicture->id = pid;
|
||||||
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
|
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
|
||||||
|
@ -1627,13 +1587,17 @@ FreePicture (pointer value,
|
||||||
{
|
{
|
||||||
if (pPicture->transform)
|
if (pPicture->transform)
|
||||||
xfree (pPicture->transform);
|
xfree (pPicture->transform);
|
||||||
if (!pPicture->pDrawable) {
|
|
||||||
if (pPicture->pSourcePict) {
|
if (pPicture->pSourcePict)
|
||||||
|
{
|
||||||
if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
|
if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
|
||||||
xfree(pPicture->pSourcePict->linear.stops);
|
xfree(pPicture->pSourcePict->linear.stops);
|
||||||
|
|
||||||
xfree(pPicture->pSourcePict);
|
xfree(pPicture->pSourcePict);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
if (pPicture->pDrawable)
|
||||||
|
{
|
||||||
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
PictureScreenPtr ps = GetPictureScreen(pScreen);
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,13 @@ typedef struct _PictTransform {
|
||||||
#define SourcePictTypeRadial 2
|
#define SourcePictTypeRadial 2
|
||||||
#define SourcePictTypeConical 3
|
#define SourcePictTypeConical 3
|
||||||
|
|
||||||
|
#define SourcePictClassUnknown 0
|
||||||
|
#define SourcePictClassHorizontal 1
|
||||||
|
#define SourcePictClassVertical 2
|
||||||
|
|
||||||
typedef struct _PictSolidFill {
|
typedef struct _PictSolidFill {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
unsigned int class;
|
||||||
CARD32 color;
|
CARD32 color;
|
||||||
} PictSolidFill, *PictSolidFillPtr;
|
} PictSolidFill, *PictSolidFillPtr;
|
||||||
|
|
||||||
|
@ -80,16 +85,22 @@ typedef struct _PictGradientStop {
|
||||||
|
|
||||||
typedef struct _PictGradient {
|
typedef struct _PictGradient {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
unsigned int class;
|
||||||
int nstops;
|
int nstops;
|
||||||
PictGradientStopPtr stops;
|
PictGradientStopPtr stops;
|
||||||
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
|
int stopRange;
|
||||||
|
CARD32 *colorTable;
|
||||||
|
int colorTableSize;
|
||||||
} PictGradient, *PictGradientPtr;
|
} PictGradient, *PictGradientPtr;
|
||||||
|
|
||||||
typedef struct _PictLinearGradient {
|
typedef struct _PictLinearGradient {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
unsigned int class;
|
||||||
int nstops;
|
int nstops;
|
||||||
PictGradientStopPtr stops;
|
PictGradientStopPtr stops;
|
||||||
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
|
int stopRange;
|
||||||
|
CARD32 *colorTable;
|
||||||
|
int colorTableSize;
|
||||||
xPointFixed p1;
|
xPointFixed p1;
|
||||||
xPointFixed p2;
|
xPointFixed p2;
|
||||||
} PictLinearGradient, *PictLinearGradientPtr;
|
} PictLinearGradient, *PictLinearGradientPtr;
|
||||||
|
@ -98,7 +109,6 @@ typedef struct _PictRadialGradient {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
int nstops;
|
int nstops;
|
||||||
PictGradientStopPtr stops;
|
PictGradientStopPtr stops;
|
||||||
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
|
|
||||||
double fx;
|
double fx;
|
||||||
double fy;
|
double fy;
|
||||||
double dx;
|
double dx;
|
||||||
|
@ -110,9 +120,12 @@ typedef struct _PictRadialGradient {
|
||||||
|
|
||||||
typedef struct _PictConicalGradient {
|
typedef struct _PictConicalGradient {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
|
unsigned int class;
|
||||||
int nstops;
|
int nstops;
|
||||||
PictGradientStopPtr stops;
|
PictGradientStopPtr stops;
|
||||||
CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
|
int stopRange;
|
||||||
|
CARD32 *colorTable;
|
||||||
|
int colorTableSize;
|
||||||
xPointFixed center;
|
xPointFixed center;
|
||||||
xFixed angle;
|
xFixed angle;
|
||||||
} PictConicalGradient, *PictConicalGradientPtr;
|
} PictConicalGradient, *PictConicalGradientPtr;
|
||||||
|
@ -624,6 +637,11 @@ Bool
|
||||||
PictureTransformPoint3d (PictTransformPtr transform,
|
PictureTransformPoint3d (PictTransformPtr transform,
|
||||||
PictVectorPtr vector);
|
PictVectorPtr vector);
|
||||||
|
|
||||||
|
CARD32
|
||||||
|
PictureGradientColor (PictGradientStopPtr stop1,
|
||||||
|
PictGradientStopPtr stop2,
|
||||||
|
CARD32 x);
|
||||||
|
|
||||||
void RenderExtensionInit (void);
|
void RenderExtensionInit (void);
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
|
Loading…
Reference in New Issue
Block a user