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" LIBUDEV="libudev >= 143"
LIBSELINUX="libselinux >= 2.0.86" LIBSELINUX="libselinux >= 2.0.86"
LIBDBUS="dbus-1 >= 1.0" 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 Pixman is always required, but we separate it out so we can link
dnl specific modules against it dnl specific modules against it

View File

@ -1423,237 +1423,3 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype)
} }
return pRgn; 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->Glyphs = miGlyphs;
ps->CompositeRects = miCompositeRects; ps->CompositeRects = miCompositeRects;
ps->RasterizeTrapezoid = fbRasterizeTrapezoid; ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
ps->Trapezoids = fbTrapezoids;
ps->AddTraps = fbAddTraps; ps->AddTraps = fbAddTraps;
ps->AddTriangles = fbAddTriangles; ps->AddTriangles = fbAddTriangles;
ps->Triangles = fbTriangles;
return TRUE; return TRUE;
} }

View File

@ -65,4 +65,24 @@ fbAddTriangles (PicturePtr pPicture,
int ntri, int ntri,
xTriangle *tris); 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_ */ #endif /* _FBPICT_H_ */

View File

@ -65,32 +65,6 @@ fbRasterizeTrapezoid (PicturePtr pPicture,
free_pixman_pict (pPicture, image); 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 void
fbAddTriangles (PicturePtr pPicture, fbAddTriangles (PicturePtr pPicture,
INT16 x_off, INT16 x_off,
@ -98,62 +72,139 @@ fbAddTriangles (PicturePtr pPicture,
int ntri, int ntri,
xTriangle *tris) xTriangle *tris)
{ {
xPointFixed *top, *left, *right, *tmp; int image_xoff, image_yoff;
xTrapezoid trap; pixman_image_t *image =
image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff);
for (; ntri; ntri--, tris++) if (!image)
{ return;
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;
}
/* pixman_add_triangles (image, x_off, y_off, ntri, (pixman_triangle_t *)tris);
* Two cases:
*
* + +
* / \ / \
* / \ / \
* / + + \
* / -- -- \
* / -- -- \
* / --- --- \
* +-- --+
*/
trap.top = top->y; free_pixman_pict (pPicture, image);
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);
}
} }
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( extern _X_EXPORT void RegionPrint(
RegionPtr /*pReg*/); 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 #define INCLUDE_LEGACY_REGION_DEFINES
#ifdef 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->Composite = 0; /* requires DDX support */
ps->Glyphs = miGlyphs; ps->Glyphs = miGlyphs;
ps->CompositeRects = miCompositeRects; ps->CompositeRects = miCompositeRects;
ps->Trapezoids = miTrapezoids; ps->Trapezoids = 0;
ps->Triangles = miTriangles; ps->Triangles = 0;
ps->TriStrip = miTriStrip; ps->TriStrip = miTriStrip;
ps->TriFan = miTriFan; ps->TriFan = miTriFan;

View File

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

View File

@ -34,55 +34,6 @@
#include "picturestr.h" #include "picturestr.h"
#include "mipict.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 static xFixed
miLineFixedX (xLineFixed *l, xFixed y, Bool ceil) miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
{ {
@ -126,64 +77,3 @@ miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
box->x2 = x2; 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); 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 void
miTriStrip (CARD8 op, miTriStrip (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,