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,
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
......@@ -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 */
......
......@@ -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
......
......@@ -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
......@@ -148,46 +132,22 @@ SafeAlphaCompositeSolidMask_nx8x8888(
}
void
SafeAlphaComposite (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
SafeAlphaComposite (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
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 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;
}
int oldDepth = pDst->pDrawable->depth;
int oldFormat = pDst->format;
/*
* 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
*/
......@@ -205,441 +166,34 @@ 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 &&
pSrc->pDrawable->width == 1 &&
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:
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;
}
}
}