New fbWalkCompositeRegion() function

This new function walks the composite region and calls a rectangle
compositing function on each compositing rectangle. Previously there
were buggy duplicates of this code in fbcompose.c and
miext/rootles/safealpha/safeAlphaPicture.c.
This commit is contained in:
Soren Sandmann Pedersen 2007-05-02 19:10:22 -04:00
commit d2f813f7db
4 changed files with 183 additions and 682 deletions

View file

@ -4308,107 +4308,9 @@ fbCompositeGeneral (CARD8 op,
CARD16 width,
CARD16 height)
{
RegionRec region;
int n;
BoxPtr pbox;
Bool srcRepeat = FALSE;
Bool maskRepeat = FALSE;
int w, h;
CARD32 _scanline_buffer[SCANLINE_BUFFER_LENGTH*3];
CARD32 *scanline_buffer = _scanline_buffer;
FbComposeData compose_data;
if (pSrc->pDrawable)
srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
&& (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
if (pMask && pMask->pDrawable)
maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
&& (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
op = PictOpSrc;
if (!miComputeCompositeRegion (&region,
pSrc,
pMask,
pDst,
xSrc,
ySrc,
xMask,
yMask,
xDst,
yDst,
width,
height))
return;
compose_data.op = op;
compose_data.src = pSrc;
compose_data.mask = pMask;
compose_data.dest = pDst;
if (width > SCANLINE_BUFFER_LENGTH)
scanline_buffer = (CARD32 *) malloc(width * 3 * sizeof(CARD32));
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)
{
h = pbox->y2 - pbox->y1;
compose_data.ySrc = pbox->y1 - yDst + ySrc;
compose_data.yMask = pbox->y1 - yDst + yMask;
compose_data.yDest = pbox->y1;
while (h)
{
compose_data.height = h;
w = pbox->x2 - pbox->x1;
compose_data.xSrc = pbox->x1 - xDst + xSrc;
compose_data.xMask = pbox->x1 - xDst + xMask;
compose_data.xDest = pbox->x1;
if (maskRepeat)
{
compose_data.yMask = mod (compose_data.yMask, pMask->pDrawable->height);
if (compose_data.height > pMask->pDrawable->height - compose_data.yMask)
compose_data.height = pMask->pDrawable->height - compose_data.yMask;
}
if (srcRepeat)
{
compose_data.ySrc = mod (compose_data.ySrc, pSrc->pDrawable->height);
if (compose_data.height > pSrc->pDrawable->height - compose_data.ySrc)
compose_data.height = pSrc->pDrawable->height - compose_data.ySrc;
}
while (w)
{
compose_data.width = w;
if (maskRepeat)
{
compose_data.xMask = mod (compose_data.xMask, pMask->pDrawable->width);
if (compose_data.width > pMask->pDrawable->width - compose_data.xMask)
compose_data.width = pMask->pDrawable->width - compose_data.xMask;
}
if (srcRepeat)
{
compose_data.xSrc = mod (compose_data.xSrc, pSrc->pDrawable->width);
if (compose_data.width > pSrc->pDrawable->width - compose_data.xSrc)
compose_data.width = pSrc->pDrawable->width - compose_data.xSrc;
}
fbCompositeRect(&compose_data, scanline_buffer);
w -= compose_data.width;
compose_data.xSrc += compose_data.width;
compose_data.xMask += compose_data.width;
compose_data.xDest += compose_data.width;
}
h -= compose_data.height;
compose_data.ySrc += compose_data.height;
compose_data.yMask += compose_data.height;
compose_data.yDest += compose_data.height;
}
pbox++;
}
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
if (scanline_buffer != _scanline_buffer)
free(scanline_buffer);
return fbComposite (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height);
}
#endif

View file

@ -37,19 +37,6 @@
#include "fbpict.h"
#include "fbmmx.h"
typedef void (*CompositeFunc) (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
CARD32
fbOver (CARD32 x, CARD32 y)
{
@ -1477,6 +1464,110 @@ fbCompositeRectWrapper (CARD8 op,
free(scanline_buffer);
}
void
fbWalkCompositeRegion (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height,
Bool srcRepeat,
Bool maskRepeat,
CompositeFunc compositeRect)
{
RegionRec region;
int n;
BoxPtr pbox;
int w, h, w_this, h_this;
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pSrc->pDrawable)
{
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
}
if (pMask && pMask->pDrawable)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
}
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height))
return;
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)
{
h = pbox->y2 - pbox->y1;
y_src = pbox->y1 - yDst + ySrc;
y_msk = pbox->y1 - yDst + yMask;
y_dst = pbox->y1;
while (h)
{
h_this = h;
w = pbox->x2 - pbox->x1;
x_src = pbox->x1 - xDst + xSrc;
x_msk = pbox->x1 - xDst + xMask;
x_dst = pbox->x1;
if (maskRepeat)
{
y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
if (h_this > pMask->pDrawable->height - y_msk)
h_this = pMask->pDrawable->height - y_msk;
y_msk += pMask->pDrawable->y;
}
if (srcRepeat)
{
y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
if (h_this > pSrc->pDrawable->height - y_src)
h_this = pSrc->pDrawable->height - y_src;
y_src += pSrc->pDrawable->y;
}
while (w)
{
w_this = w;
if (maskRepeat)
{
x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
if (w_this > pMask->pDrawable->width - x_msk)
w_this = pMask->pDrawable->width - x_msk;
x_msk += pMask->pDrawable->x;
}
if (srcRepeat)
{
x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
if (w_this > pSrc->pDrawable->width - x_src)
w_this = pSrc->pDrawable->width - x_src;
x_src += pSrc->pDrawable->x;
}
(*compositeRect) (op, pSrc, pMask, pDst,
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
w_this, h_this);
w -= w_this;
x_src += w_this;
x_msk += w_this;
x_dst += w_this;
}
h -= h_this;
y_src += h_this;
y_msk += h_this;
y_dst += h_this;
}
pbox++;
}
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
}
void
fbComposite (CARD8 op,
PicturePtr pSrc,
@ -1491,10 +1582,6 @@ fbComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
RegionRec region;
int n;
BoxPtr pbox;
CompositeFunc func = NULL;
Bool srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
Bool maskRepeat = FALSE;
Bool srcTransform = pSrc->transform != 0;
@ -1502,8 +1589,7 @@ fbComposite (CARD8 op,
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;
CompositeFunc func = NULL;
#ifdef USE_MMX
static Bool mmx_setup = FALSE;
@ -1513,13 +1599,6 @@ fbComposite (CARD8 op,
}
#endif
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pSrc->pDrawable) {
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
}
if (srcRepeat && srcTransform &&
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
@ -1527,8 +1606,6 @@ fbComposite (CARD8 op,
if (pMask && pMask->pDrawable)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeatType == RepeatNormal;
if (pMask->filter == PictFilterConvolution)
@ -1688,7 +1765,8 @@ fbComposite (CARD8 op,
else if (!srcRepeat) /* has mask and non-repeating source */
{
if (pSrc->pDrawable == pMask->pDrawable &&
xSrc == xMask && ySrc == yMask &&
xSrc + pSrc->pDrawable->x == xMask + pMask->pDrawable->x &&
ySrc + pSrc->pDrawable->y == yMask + pMask->pDrawable->y &&
!pMask->componentAlpha && !maskRepeat)
{
/* source == mask: non-premultiplied data */
@ -2091,73 +2169,10 @@ fbComposite (CARD8 op,
srcRepeat = FALSE;
if (maskTransform)
maskRepeat = FALSE;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height))
return;
n = REGION_NUM_RECTS (&region);
pbox = REGION_RECTS (&region);
while (n--)
{
h = pbox->y2 - pbox->y1;
y_src = pbox->y1 - yDst + ySrc;
y_msk = pbox->y1 - yDst + yMask;
y_dst = pbox->y1;
while (h)
{
h_this = h;
w = pbox->x2 - pbox->x1;
x_src = pbox->x1 - xDst + xSrc;
x_msk = pbox->x1 - xDst + xMask;
x_dst = pbox->x1;
if (maskRepeat)
{
y_msk = mod (y_msk - pMask->pDrawable->y, pMask->pDrawable->height);
if (h_this > pMask->pDrawable->height - y_msk)
h_this = pMask->pDrawable->height - y_msk;
y_msk += pMask->pDrawable->y;
}
if (srcRepeat)
{
y_src = mod (y_src - pSrc->pDrawable->y, pSrc->pDrawable->height);
if (h_this > pSrc->pDrawable->height - y_src)
h_this = pSrc->pDrawable->height - y_src;
y_src += pSrc->pDrawable->y;
}
while (w)
{
w_this = w;
if (maskRepeat)
{
x_msk = mod (x_msk - pMask->pDrawable->x, pMask->pDrawable->width);
if (w_this > pMask->pDrawable->width - x_msk)
w_this = pMask->pDrawable->width - x_msk;
x_msk += pMask->pDrawable->x;
}
if (srcRepeat)
{
x_src = mod (x_src - pSrc->pDrawable->x, pSrc->pDrawable->width);
if (w_this > pSrc->pDrawable->width - x_src)
w_this = pSrc->pDrawable->width - x_src;
x_src += pSrc->pDrawable->x;
}
(*func) (op, pSrc, pMask, pDst,
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
w_this, h_this);
w -= w_this;
x_src += w_this;
x_msk += w_this;
x_dst += w_this;
}
h -= h_this;
y_src += h_this;
y_msk += h_this;
y_dst += h_this;
}
pbox++;
}
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
fbWalkCompositeRegion (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height,
srcRepeat, maskRepeat, func);
}
#endif /* RENDER */

View file

@ -630,6 +630,36 @@ fbComposite (CARD8 op,
CARD16 width,
CARD16 height);
typedef void (*CompositeFunc) (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
void
fbWalkCompositeRegion (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height,
Bool srcRepeat,
Bool maskRepeat,
CompositeFunc compositeRect);
/* fbtrap.c */
void