Merge remote branch 'sandmann/for-keithp'

This commit is contained in:
Keith Packard 2011-03-03 14:12:36 -08:00
commit 3f41f4adea
10 changed files with 158 additions and 525 deletions

View File

@ -795,7 +795,7 @@ LIBGLIB="glib-2.0 >= 2.16"
LIBUDEV="libudev >= 143"
LIBSELINUX="libselinux >= 2.0.86"
LIBDBUS="dbus-1 >= 1.0"
LIBPIXMAN="pixman-1 >= 0.15.20"
LIBPIXMAN="pixman-1 >= 0.21.6"
dnl Pixman is always required, but we separate it out so we can link
dnl specific modules against it

View File

@ -1423,237 +1423,3 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
}
return pRgn;
}
#define ExchangeSpans(a, b) \
{ \
DDXPointRec tpt; \
int tw; \
\
tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
}
/* ||| I should apply the merge sort code to rectangle sorting above, and see
if mapping time can be improved. But right now I've been at work 12 hours,
so forget it.
*/
static void QuickSortSpans(
DDXPointRec spans[],
int widths[],
int numSpans)
{
int y;
int i, j, m;
DDXPointPtr r;
/* Always called with numSpans > 1 */
/* Sorts only by y, doesn't bother to sort by x */
do
{
if (numSpans < 9)
{
/* Do insertion sort */
int yprev;
yprev = spans[0].y;
i = 1;
do
{ /* while i != numSpans */
y = spans[i].y;
if (yprev > y)
{
/* spans[i] is out of order. Move into proper location. */
DDXPointRec tpt;
int tw, k;
for (j = 0; y >= spans[j].y; j++) {}
tpt = spans[i];
tw = widths[i];
for (k = i; k != j; k--)
{
spans[k] = spans[k-1];
widths[k] = widths[k-1];
}
spans[j] = tpt;
widths[j] = tw;
y = spans[i].y;
} /* if out of order */
yprev = y;
i++;
} while (i != numSpans);
return;
}
/* Choose partition element, stick in location 0 */
m = numSpans / 2;
if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
y = spans[0].y;
/* Partition array */
i = 0;
j = numSpans;
do
{
r = &(spans[i]);
do
{
r++;
i++;
} while (i != numSpans && r->y < y);
r = &(spans[j]);
do
{
r--;
j--;
} while (y < r->y);
if (i < j)
ExchangeSpans(i, j);
} while (i < j);
/* Move partition element back to middle */
ExchangeSpans(0, j);
/* Recurse */
if (numSpans-j-1 > 1)
QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
numSpans = j;
} while (numSpans > 1);
}
#define NextBand() \
{ \
clipy1 = pboxBandStart->y1; \
clipy2 = pboxBandStart->y2; \
pboxBandEnd = pboxBandStart + 1; \
while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
pboxBandEnd++; \
} \
for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
}
/*
Clip a list of scanlines to a region. The caller has allocated the
space. FSorted is non-zero if the scanline origins are in ascending
order.
returns the number of new, clipped scanlines.
*/
int
RegionClipSpans(
RegionPtr prgnDst,
DDXPointPtr ppt,
int *pwidth,
int nspans,
DDXPointPtr pptNew,
int *pwidthNew,
int fSorted)
{
DDXPointPtr pptLast;
int *pwidthNewStart; /* the vengeance of Xerox! */
int y, x1, x2;
int numRects;
good(prgnDst);
pptLast = ppt + nspans;
pwidthNewStart = pwidthNew;
if (!prgnDst->data)
{
/* Do special fast code with clip boundaries in registers(?) */
/* It doesn't pay much to make use of fSorted in this case,
so we lump everything together. */
int clipx1, clipx2, clipy1, clipy2;
clipx1 = prgnDst->extents.x1;
clipy1 = prgnDst->extents.y1;
clipx2 = prgnDst->extents.x2;
clipy2 = prgnDst->extents.y2;
for (; ppt != pptLast; ppt++, pwidth++)
{
y = ppt->y;
x1 = ppt->x;
if (clipy1 <= y && y < clipy2)
{
x2 = x1 + *pwidth;
if (x1 < clipx1) x1 = clipx1;
if (x2 > clipx2) x2 = clipx2;
if (x1 < x2)
{
/* part of span in clip rectangle */
pptNew->x = x1;
pptNew->y = y;
*pwidthNew = x2 - x1;
pptNew++;
pwidthNew++;
}
}
} /* end for */
}
else if ((numRects = prgnDst->data->numRects))
{
/* Have to clip against many boxes */
BoxPtr pboxBandStart, pboxBandEnd;
BoxPtr pbox;
BoxPtr pboxLast;
int clipy1, clipy2;
/* In this case, taking advantage of sorted spans gains more than
the sorting costs. */
if ((! fSorted) && (nspans > 1))
QuickSortSpans(ppt, pwidth, nspans);
pboxBandStart = RegionBoxptr(prgnDst);
pboxLast = pboxBandStart + numRects;
NextBand();
for (; ppt != pptLast; )
{
y = ppt->y;
if (y < clipy2)
{
/* span is in the current band */
pbox = pboxBandStart;
x1 = ppt->x;
x2 = x1 + *pwidth;
do
{ /* For each box in band */
int newx1, newx2;
newx1 = x1;
newx2 = x2;
if (newx1 < pbox->x1) newx1 = pbox->x1;
if (newx2 > pbox->x2) newx2 = pbox->x2;
if (newx1 < newx2)
{
/* Part of span in clip rectangle */
pptNew->x = newx1;
pptNew->y = y;
*pwidthNew = newx2 - newx1;
pptNew++;
pwidthNew++;
}
pbox++;
} while (pbox != pboxBandEnd);
ppt++;
pwidth++;
}
else
{
/* Move to next band, adjust ppt as needed */
pboxBandStart = pboxBandEnd;
if (pboxBandStart == pboxLast)
break; /* We're completely done */
NextBand();
}
}
}
return pwidthNew - pwidthNewStart;
}

View File

@ -364,8 +364,10 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->Glyphs = miGlyphs;
ps->CompositeRects = miCompositeRects;
ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
ps->Trapezoids = fbTrapezoids;
ps->AddTraps = fbAddTraps;
ps->AddTriangles = fbAddTriangles;
ps->Triangles = fbTriangles;
return TRUE;
}

View File

@ -65,4 +65,24 @@ fbAddTriangles (PicturePtr pPicture,
int ntri,
xTriangle *tris);
extern _X_EXPORT void
fbTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntrap,
xTrapezoid *traps);
extern _X_EXPORT void
fbTriangles (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntris,
xTriangle *tris);
#endif /* _FBPICT_H_ */

View File

@ -65,32 +65,6 @@ fbRasterizeTrapezoid (PicturePtr pPicture,
free_pixman_pict (pPicture, image);
}
static int
_GreaterY (xPointFixed *a, xPointFixed *b)
{
if (a->y == b->y)
return a->x > b->x;
return a->y > b->y;
}
/*
* Note that the definition of this function is a bit odd because
* of the X coordinate space (y increasing downwards).
*/
static int
_Clockwise (xPointFixed *ref, xPointFixed *a, xPointFixed *b)
{
xPointFixed ad, bd;
ad.x = a->x - ref->x;
ad.y = a->y - ref->y;
bd.x = b->x - ref->x;
bd.y = b->y - ref->y;
return ((xFixed_32_32) bd.y * ad.x - (xFixed_32_32) ad.y * bd.x) < 0;
}
/* FIXME -- this could be made more efficient */
void
fbAddTriangles (PicturePtr pPicture,
INT16 x_off,
@ -98,62 +72,139 @@ fbAddTriangles (PicturePtr pPicture,
int ntri,
xTriangle *tris)
{
xPointFixed *top, *left, *right, *tmp;
xTrapezoid trap;
int image_xoff, image_yoff;
pixman_image_t *image =
image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff);
for (; ntri; ntri--, tris++)
{
top = &tris->p1;
left = &tris->p2;
right = &tris->p3;
if (_GreaterY (top, left)) {
tmp = left; left = top; top = tmp;
}
if (_GreaterY (top, right)) {
tmp = right; right = top; top = tmp;
}
if (_Clockwise (top, right, left)) {
tmp = right; right = left; left = tmp;
}
/*
* Two cases:
*
* + +
* / \ / \
* / \ / \
* / + + \
* / -- -- \
* / -- -- \
* / --- --- \
* +-- --+
*/
trap.top = top->y;
trap.left.p1 = *top;
trap.left.p2 = *left;
trap.right.p1 = *top;
trap.right.p2 = *right;
if (right->y < left->y)
trap.bottom = right->y;
else
trap.bottom = left->y;
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
if (right->y < left->y)
{
trap.top = right->y;
trap.bottom = left->y;
trap.right.p1 = *right;
trap.right.p2 = *left;
}
else
{
trap.top = left->y;
trap.bottom = right->y;
trap.left.p1 = *left;
trap.left.p2 = *right;
}
fbRasterizeTrapezoid (pPicture, &trap, x_off, y_off);
}
if (!image)
return;
pixman_add_triangles (image, x_off, y_off, ntri, (pixman_triangle_t *)tris);
free_pixman_pict (pPicture, image);
}
typedef void (* CompositeShapesFunc) (pixman_op_t op,
pixman_image_t *src,
pixman_image_t *dst,
pixman_format_code_t mask_format,
int x_src, int y_src,
int x_dst, int y_dst,
int n_shapes, const uint8_t *shapes);
static void
fbShapes (CompositeShapesFunc composite,
pixman_op_t op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
int16_t xSrc,
int16_t ySrc,
int16_t xDst,
int16_t yDst,
int nshapes,
int shape_size,
const uint8_t * shapes)
{
pixman_image_t *src, *dst;
int src_xoff, src_yoff;
int dst_xoff, dst_yoff;
src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
dst = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
if (src && dst)
{
pixman_format_code_t format;
if (!maskFormat)
{
int i;
if (pDst->polyEdge == PolyEdgeSharp)
format = PIXMAN_a1;
else
format = PIXMAN_a8;
for (i = 0; i < nshapes; ++i)
{
composite (op, src, dst, format,
xSrc + src_xoff,
ySrc + src_yoff,
xDst + dst_xoff,
yDst + dst_yoff,
1, shapes + i * shape_size);
}
}
else
{
switch (PICT_FORMAT_A (maskFormat->format))
{
case 1:
format = PIXMAN_a1;
break;
case 4:
format = PIXMAN_a4;
break;
default:
case 8:
format = PIXMAN_a8;
break;
}
composite (op, src, dst, format,
xSrc + src_xoff,
ySrc + src_yoff,
xDst + dst_xoff,
yDst + dst_yoff,
nshapes, shapes);
}
}
free_pixman_pict (pSrc, src);
free_pixman_pict (pDst, dst);
}
void
fbTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntrap,
xTrapezoid *traps)
{
int xDst, yDst;
xDst = traps[0].left.p1.x >> 16;
yDst = traps[0].left.p1.y >> 16;
fbShapes ((CompositeShapesFunc)pixman_composite_trapezoids,
op, pSrc, pDst, maskFormat,
xSrc, ySrc, xDst, yDst,
ntrap, sizeof (xTrapezoid), (const uint8_t *)traps);
}
void
fbTriangles (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntris,
xTriangle *tris)
{
int xDst, yDst;
xDst = tris[0].p1.x >> 16;
yDst = tris[0].p1.y >> 16;
fbShapes ((CompositeShapesFunc)pixman_composite_triangles,
op, pSrc, pDst, maskFormat,
xSrc, ySrc, xDst, yDst,
ntris, sizeof (xTriangle), (const uint8_t *)tris);
}

View File

@ -318,16 +318,6 @@ extern _X_EXPORT Bool RegionIsValid(
extern _X_EXPORT void RegionPrint(
RegionPtr /*pReg*/);
extern _X_EXPORT int RegionClipSpans(
RegionPtr /*prgnDst*/,
DDXPointPtr /*ppt*/,
int * /*pwidth*/,
int /*nspans*/,
DDXPointPtr /*pptNew*/,
int * /*pwidthNew*/,
int /*fSorted*/
);
#define INCLUDE_LEGACY_REGION_DEFINES
#ifdef INCLUDE_LEGACY_REGION_DEFINES

View File

@ -631,8 +631,8 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
ps->Composite = 0; /* requires DDX support */
ps->Glyphs = miGlyphs;
ps->CompositeRects = miCompositeRects;
ps->Trapezoids = miTrapezoids;
ps->Triangles = miTriangles;
ps->Trapezoids = 0;
ps->Triangles = 0;
ps->TriStrip = miTriStrip;
ps->TriFan = miTriFan;

View File

@ -145,32 +145,12 @@ miCompositeRects (CARD8 op,
extern _X_EXPORT void
miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
extern _X_EXPORT void
miTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntrap,
xTrapezoid *traps);
extern _X_EXPORT void
miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
extern _X_EXPORT void
miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
extern _X_EXPORT void
miTriangles (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntri,
xTriangle *tris);
extern _X_EXPORT void
miTriStrip (CARD8 op,
PicturePtr pSrc,
@ -191,13 +171,6 @@ miTriFan (CARD8 op,
int npoint,
xPointFixed *points);
extern _X_EXPORT PicturePtr
miCreateAlphaPicture (ScreenPtr pScreen,
PicturePtr pDst,
PictFormatPtr pPictFormat,
CARD16 width,
CARD16 height);
extern _X_EXPORT Bool
miInitIndexed (ScreenPtr pScreen,
PictFormatPtr pFormat);

View File

@ -34,55 +34,6 @@
#include "picturestr.h"
#include "mipict.h"
PicturePtr
miCreateAlphaPicture (ScreenPtr pScreen,
PicturePtr pDst,
PictFormatPtr pPictFormat,
CARD16 width,
CARD16 height)
{
PixmapPtr pPixmap;
PicturePtr pPicture;
GCPtr pGC;
int error;
xRectangle rect;
if (width > 32767 || height > 32767)
return 0;
if (!pPictFormat)
{
if (pDst->polyEdge == PolyEdgeSharp)
pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
else
pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
if (!pPictFormat)
return 0;
}
pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
pPictFormat->depth, 0);
if (!pPixmap)
return 0;
pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
if (!pGC)
{
(*pScreen->DestroyPixmap) (pPixmap);
return 0;
}
ValidateGC (&pPixmap->drawable, pGC);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
(*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
FreeScratchGC (pGC);
pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
0, 0, serverClient, &error);
(*pScreen->DestroyPixmap) (pPixmap);
return pPicture;
}
static xFixed
miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
{
@ -126,64 +77,3 @@ miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
box->x2 = x2;
}
}
void
miTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntrap,
xTrapezoid *traps)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
/*
* Check for solid alpha add
*/
if (op == PictOpAdd && miIsSolidAlpha (pSrc))
{
for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
}
else if (maskFormat)
{
PicturePtr pPicture;
BoxRec bounds;
INT16 xDst, yDst;
INT16 xRel, yRel;
xDst = traps[0].left.p1.x >> 16;
yDst = traps[0].left.p1.y >> 16;
miTrapezoidBounds (ntrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pPicture, traps,
-bounds.x1, -bounds.y1);
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst,
xRel, yRel, 0, 0, bounds.x1, bounds.y1,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
FreePicture (pPicture, 0);
}
else
{
if (pDst->polyEdge == PolyEdgeSharp)
maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
else
maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
for (; ntrap; ntrap--, traps++)
miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
}
}

View File

@ -67,65 +67,6 @@ miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
}
void
miTriangles (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int ntri,
xTriangle *tris)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
/*
* Check for solid alpha add
*/
if (op == PictOpAdd && miIsSolidAlpha (pSrc))
{
(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
}
else if (maskFormat)
{
BoxRec bounds;
PicturePtr pPicture;
INT16 xDst, yDst;
INT16 xRel, yRel;
xDst = tris[0].p1.x >> 16;
yDst = tris[0].p1.y >> 16;
miTriangleBounds (ntri, tris, &bounds);
if (bounds.x2 <= bounds.x1 || bounds.y2 <= bounds.y1)
return;
pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst,
xRel, yRel, 0, 0, bounds.x1, bounds.y1,
bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
FreePicture (pPicture, 0);
}
else
{
if (pDst->polyEdge == PolyEdgeSharp)
maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
else
maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
for (; ntri; ntri--, tris++)
miTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
}
}
void
miTriStrip (CARD8 op,
PicturePtr pSrc,