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
parent e0959adcd8
commit d2f813f7db
4 changed files with 184 additions and 683 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 */
@ -2092,72 +2170,9 @@ fbComposite (CARD8 op,
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

View File

@ -46,22 +46,6 @@
#include "fbpict.h"
#include "safeAlpha.h"
#include "rootlessCommon.h"
# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
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);
/* Optimized version of fbCompositeSolidMask_nx8x8888 */
void
@ -161,33 +145,9 @@ SafeAlphaComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
RegionRec region;
int n;
BoxPtr pbox;
CompositeFunc func = 0;
Bool srcRepeat = pSrc->repeat;
Bool maskRepeat = 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;
int dstDepth = pDst->pDrawable->depth;
int oldDepth = pDst->pDrawable->depth;
int oldFormat = pDst->format;
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (pMask)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeat;
maskAlphaMap = pMask->alphaMap != 0;
}
/*
* We can use the more optimized fbpict code, but it sets bits above
* the depth to zero. Temporarily adjust destination depth if needed.
@ -198,6 +158,7 @@ SafeAlphaComposite (CARD8 op,
{
pDst->pDrawable->depth = 32;
}
/* For rootless preserve the alpha in x8r8g8b8 which really is
* a8r8g8b8
*/
@ -206,440 +167,33 @@ SafeAlphaComposite (CARD8 op,
pDst->format = PICT_a8r8g8b8;
}
if (!pSrc->transform && !(pMask && pMask->transform))
if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
switch (op) {
case PictOpSrc:
#ifdef USE_MMX
if (!pMask && pSrc->format == pDst->format &&
pSrc->pDrawable != pDst->pDrawable)
{
func = fbCompositeCopyAreammx;
}
#endif
break;
case PictOpOver:
if (pMask)
{
if (srcRepeat &&
if (pSrc->pDrawable && pMask->pDrawable &&
!pSrc->transform && !pMask->transform &&
!pSrc->alphaMap && !pMask->alphaMap &&
!pMask->repeat && !pMask->componentAlpha && !pDst->alphaMap &&
pMask->format == PICT_a8 &&
pSrc->repeatType == RepeatNormal &&
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
pSrc->pDrawable->height == 1 &&
(pDst->format == PICT_a8r8g8b8 ||
pDst->format == PICT_x8r8g8b8 ||
pDst->format == PICT_a8b8g8r8 ||
pDst->format == PICT_x8b8g8r8))
{
srcRepeat = FALSE;
if (PICT_FORMAT_COLOR(pSrc->format)) {
switch (pMask->format) {
case PICT_a8:
switch (pDst->format) {
case PICT_r5g6b5:
case PICT_b5g6r5:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSolidMask_nx8x0565mmx;
else
#endif
func = fbCompositeSolidMask_nx8x0565;
break;
case PICT_r8g8b8:
case PICT_b8g8r8:
func = fbCompositeSolidMask_nx8x0888;
break;
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = SafeAlphaCompositeSolidMask_nx8x8888;
break;
}
break;
case PICT_a8r8g8b8:
if (pMask->componentAlpha) {
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSolidMask_nx8888x8888Cmmx;
else
#endif
func = fbCompositeSolidMask_nx8888x8888C;
break;
case PICT_r5g6b5:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSolidMask_nx8888x0565Cmmx;
else
#endif
func = fbCompositeSolidMask_nx8888x0565C;
break;
}
}
break;
case PICT_a8b8g8r8:
if (pMask->componentAlpha) {
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSolidMask_nx8888x8888Cmmx;
else
#endif
func = fbCompositeSolidMask_nx8888x8888C;
break;
case PICT_b5g6r5:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSolidMask_nx8888x0565Cmmx;
else
#endif
func = fbCompositeSolidMask_nx8888x0565C;
break;
}
}
break;
case PICT_a1:
switch (pDst->format) {
case PICT_r5g6b5:
case PICT_b5g6r5:
case PICT_r8g8b8:
case PICT_b8g8r8:
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
func = fbCompositeSolidMask_nx1xn;
break;
}
break;
}
}
}
else /* has mask and non-repeating source */
{
if (pSrc->pDrawable == pMask->pDrawable &&
xSrc == xMask && ySrc == yMask &&
!pMask->componentAlpha)
{
/* source == mask: non-premultiplied data */
switch (pSrc->format) {
case PICT_x8b8g8r8:
switch (pMask->format) {
case PICT_a8r8g8b8:
case PICT_a8b8g8r8:
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888RevNPx8888mmx;
#endif
break;
case PICT_r5g6b5:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888RevNPx0565mmx;
#endif
break;
}
break;
}
break;
case PICT_x8r8g8b8:
switch (pMask->format) {
case PICT_a8r8g8b8:
case PICT_a8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888RevNPx8888mmx;
#endif
break;
case PICT_r5g6b5:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888RevNPx0565mmx;
#endif
break;
}
break;
}
break;
}
break;
fbWalkCompositeRegion (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height,
TRUE /* srcRepeat */,
FALSE /* maskRepeat */,
SafeAlphaCompositeSolidMask_nx8x8888);
}
else
{
/* non-repeating source, repeating mask => translucent window */
if (maskRepeat &&
pMask->pDrawable->width == 1 &&
pMask->pDrawable->height == 1)
{
if (pSrc->format == PICT_x8r8g8b8 &&
pDst->format == PICT_x8r8g8b8 &&
pMask->format == PICT_a8)
{
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888x8x8888mmx;
#endif
}
}
}
}
}
else /* no mask */
{
if (srcRepeat &&
pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1)
{
/* no mask and repeating source */
switch (pSrc->format) {
case PICT_a8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
{
srcRepeat = FALSE;
func = fbCompositeSolid_nx8888mmx;
}
#endif
break;
case PICT_r5g6b5:
#ifdef USE_MMX
if (fbHaveMMX())
{
srcRepeat = FALSE;
func = fbCompositeSolid_nx0565mmx;
}
#endif
break;
}
break;
}
}
else
{
switch (pSrc->format) {
case PICT_a8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888x8888mmx;
else
#endif
func = fbCompositeSrc_8888x8888;
break;
case PICT_r8g8b8:
func = fbCompositeSrc_8888x0888;
break;
case PICT_r5g6b5:
func = fbCompositeSrc_8888x0565;
break;
}
break;
case PICT_x8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
case PICT_x8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeCopyAreammx;
#endif
break;
}
case PICT_x8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeCopyAreammx;
#endif
break;
}
break;
case PICT_a8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
case PICT_x8b8g8r8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrc_8888x8888mmx;
else
#endif
func = fbCompositeSrc_8888x8888;
break;
case PICT_b8g8r8:
func = fbCompositeSrc_8888x0888;
break;
case PICT_b5g6r5:
func = fbCompositeSrc_8888x0565;
break;
}
break;
case PICT_r5g6b5:
switch (pDst->format) {
case PICT_r5g6b5:
func = fbCompositeSrc_0565x0565;
break;
}
break;
case PICT_b5g6r5:
switch (pDst->format) {
case PICT_b5g6r5:
func = fbCompositeSrc_0565x0565;
break;
}
break;
}
}
}
break;
case PictOpAdd:
if (pMask == 0)
{
switch (pSrc->format) {
case PICT_a8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrcAdd_8888x8888mmx;
else
#endif
func = fbCompositeSrcAdd_8888x8888;
break;
}
break;
case PICT_a8b8g8r8:
switch (pDst->format) {
case PICT_a8b8g8r8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrcAdd_8888x8888mmx;
else
#endif
func = fbCompositeSrcAdd_8888x8888;
break;
}
break;
case PICT_a8:
switch (pDst->format) {
case PICT_a8:
#ifdef USE_MMX
if (fbHaveMMX())
func = fbCompositeSrcAdd_8000x8000mmx;
else
#endif
func = fbCompositeSrcAdd_8000x8000;
break;
}
break;
case PICT_a1:
switch (pDst->format) {
case PICT_a1:
func = fbCompositeSrcAdd_1000x1000;
break;
}
break;
}
}
break;
fbComposite (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
}
if (!func) {
/* no fast path, use the general code */
fbCompositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
// Reset destination depth and format to their true value
pDst->pDrawable->depth = dstDepth;
pDst->format = oldFormat;
return;
}
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->height);
if (h_this > pMask->pDrawable->height - y_msk)
h_this = pMask->pDrawable->height - y_msk;
}
if (srcRepeat)
{
y_src = mod (y_src, pSrc->pDrawable->height);
if (h_this > pSrc->pDrawable->height - y_src)
h_this = pSrc->pDrawable->height - y_src;
}
while (w)
{
w_this = w;
if (maskRepeat)
{
x_msk = mod (x_msk, pMask->pDrawable->width);
if (w_this > pMask->pDrawable->width - x_msk)
w_this = pMask->pDrawable->width - x_msk;
}
if (srcRepeat)
{
x_src = mod (x_src, pSrc->pDrawable->width);
if (w_this > pSrc->pDrawable->width - x_src)
w_this = pSrc->pDrawable->width - x_src;
}
(*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);
// Reset destination depth/format to its true value
pDst->pDrawable->depth = dstDepth;
pDst->pDrawable->depth = oldDepth;
pDst->format = oldFormat;
}