Commit d2f813f7 authored by Soren Sandmann Pedersen's avatar Soren Sandmann Pedersen
Browse files

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.
parent e0959adc
...@@ -4308,107 +4308,9 @@ fbCompositeGeneral (CARD8 op, ...@@ -4308,107 +4308,9 @@ fbCompositeGeneral (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
RegionRec region; return fbComposite (op, pSrc, pMask, pDst,
int n; xSrc, ySrc, xMask, yMask, xDst, yDst,
BoxPtr pbox; width, height);
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);
} }
#endif #endif
...@@ -37,19 +37,6 @@ ...@@ -37,19 +37,6 @@
#include "fbpict.h" #include "fbpict.h"
#include "fbmmx.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 CARD32
fbOver (CARD32 x, CARD32 y) fbOver (CARD32 x, CARD32 y)
{ {
...@@ -1477,6 +1464,110 @@ fbCompositeRectWrapper (CARD8 op, ...@@ -1477,6 +1464,110 @@ fbCompositeRectWrapper (CARD8 op,
free(scanline_buffer); 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 void
fbComposite (CARD8 op, fbComposite (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
...@@ -1491,10 +1582,6 @@ fbComposite (CARD8 op, ...@@ -1491,10 +1582,6 @@ fbComposite (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
RegionRec region;
int n;
BoxPtr pbox;
CompositeFunc func = NULL;
Bool srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal; Bool srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
Bool maskRepeat = FALSE; Bool maskRepeat = FALSE;
Bool srcTransform = pSrc->transform != 0; Bool srcTransform = pSrc->transform != 0;
...@@ -1502,8 +1589,7 @@ fbComposite (CARD8 op, ...@@ -1502,8 +1589,7 @@ fbComposite (CARD8 op,
Bool srcAlphaMap = pSrc->alphaMap != 0; Bool srcAlphaMap = pSrc->alphaMap != 0;
Bool maskAlphaMap = FALSE; Bool maskAlphaMap = FALSE;
Bool dstAlphaMap = pDst->alphaMap != 0; Bool dstAlphaMap = pDst->alphaMap != 0;
int x_msk, y_msk, x_src, y_src, x_dst, y_dst; CompositeFunc func = NULL;
int w, h, w_this, h_this;
#ifdef USE_MMX #ifdef USE_MMX
static Bool mmx_setup = FALSE; static Bool mmx_setup = FALSE;
...@@ -1513,13 +1599,6 @@ fbComposite (CARD8 op, ...@@ -1513,13 +1599,6 @@ fbComposite (CARD8 op,
} }
#endif #endif
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pSrc->pDrawable) {
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
}
if (srcRepeat && srcTransform && if (srcRepeat && srcTransform &&
pSrc->pDrawable->width == 1 && pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1) pSrc->pDrawable->height == 1)
...@@ -1527,8 +1606,6 @@ fbComposite (CARD8 op, ...@@ -1527,8 +1606,6 @@ fbComposite (CARD8 op,
if (pMask && pMask->pDrawable) if (pMask && pMask->pDrawable)
{ {
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeatType == RepeatNormal; maskRepeat = pMask->repeatType == RepeatNormal;
if (pMask->filter == PictFilterConvolution) if (pMask->filter == PictFilterConvolution)
...@@ -1688,7 +1765,8 @@ fbComposite (CARD8 op, ...@@ -1688,7 +1765,8 @@ fbComposite (CARD8 op,
else if (!srcRepeat) /* has mask and non-repeating source */ else if (!srcRepeat) /* has mask and non-repeating source */
{ {
if (pSrc->pDrawable == pMask->pDrawable && 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) !pMask->componentAlpha && !maskRepeat)
{ {
/* source == mask: non-premultiplied data */ /* source == mask: non-premultiplied data */
...@@ -2091,73 +2169,10 @@ fbComposite (CARD8 op, ...@@ -2091,73 +2169,10 @@ fbComposite (CARD8 op,
srcRepeat = FALSE; srcRepeat = FALSE;
if (maskTransform) if (maskTransform)
maskRepeat = FALSE; maskRepeat = FALSE;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height))
return;
n = REGION_NUM_RECTS (&region); fbWalkCompositeRegion (op, pSrc, pMask, pDst, xSrc, ySrc,
pbox = REGION_RECTS (&region); xMask, yMask, xDst, yDst, width, height,
while (n--) srcRepeat, maskRepeat, func);
{
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);
} }
#endif /* RENDER */ #endif /* RENDER */
......
...@@ -630,6 +630,36 @@ fbComposite (CARD8 op, ...@@ -630,6 +630,36 @@ fbComposite (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height); 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 */ /* fbtrap.c */
void void
......
...@@ -46,22 +46,6 @@ ...@@ -46,22 +46,6 @@
#include "fbpict.h" #include "fbpict.h"
#include "safeAlpha.h" #include "safeAlpha.h"
#include "rootlessCommon.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 */ /* Optimized version of fbCompositeSolidMask_nx8x8888 */
void void
...@@ -148,46 +132,22 @@ SafeAlphaCompositeSolidMask_nx8x8888( ...@@ -148,46 +132,22 @@ SafeAlphaCompositeSolidMask_nx8x8888(
} }
void void
SafeAlphaComposite (CARD8 op, SafeAlphaComposite (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pMask, PicturePtr pMask,
PicturePtr pDst, PicturePtr pDst,
INT16 xSrc, INT16 xSrc,
INT16 ySrc, INT16 ySrc,
INT16 xMask, INT16 xMask,
INT16 yMask, INT16 yMask,
INT16 xDst, INT16 xDst,
INT16 yDst, INT16 yDst,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
RegionRec region; int oldDepth = pDst->pDrawable->depth;
int n; int oldFormat = pDst->format;
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 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 * We can use the more optimized fbpict code, but it sets bits above
* the depth to zero. Temporarily adjust destination depth if needed. * the depth to zero. Temporarily adjust destination depth if needed.
...@@ -198,6 +158,7 @@ SafeAlphaComposite (CARD8 op, ...@@ -198,6 +158,7 @@ SafeAlphaComposite (CARD8 op,
{ {
pDst->pDrawable->depth = 32; pDst->pDrawable->depth = 32;
} }
/* For rootless preserve the alpha in x8r8g8b8 which really is /* For rootless preserve the alpha in x8r8g8b8 which really is
* a8r8g8b8 * a8r8g8b8
*/ */
...@@ -205,441 +166,34 @@ SafeAlphaComposite (CARD8 op, ...@@ -205,441 +166,34 @@ SafeAlphaComposite (CARD8 op,
{ {
pDst->format = PICT_a8r8g8b8; pDst->format = PICT_a8r8g8b8;
} }
if (pSrc->pDrawable && pMask->pDrawable &&
!pSrc->transform && !pMask->transform &&
if (!pSrc->transform && !(pMask && pMask->transform)) !pSrc->alphaMap && !pMask->alphaMap &&
if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap) !pMask->repeat && !pMask->componentAlpha && !pDst->alphaMap &&
switch (op) { pMask->format == PICT_a8 &&
case PictOpSrc: pSrc->repeatType == RepeatNormal &&
#ifdef USE_MMX pSrc->pDrawable->width == 1 &&
if (!pMask && pSrc->format == pDst->format && pSrc->pDrawable->height == 1 &&
pSrc->pDrawable != pDst->pDrawable) (pDst->format == PICT_a8r8g8b8 ||
{ pDst->format == PICT_x8r8g8b8 ||
func = fbCompositeCopyAreammx; pDst->format == PICT_a8b8g8r8 ||
} pDst->format == PICT_x8b8g8r8))
#endif {
break; fbWalkCompositeRegion (op, pSrc, pMask, pDst,
case PictOpOver: xSrc, ySrc, xMask, yMask, xDst, yDst,
if (pMask) width, height,
{ TRUE /* srcRepeat */,
if (srcRepeat && FALSE /* maskRepeat */,
pSrc->pDrawable->width == 1 && SafeAlphaCompositeSolidMask_nx8x8888);
pSrc->pDrawable->height == 1)
{
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: