EXA: Improvements for trapezoids and triangles.

Only migrate once in exaTrapezoids/Triangles instead of every time in
exaRasterizeTrapezoid/AddTriangles. Adapt manual damage tracking to new
infrastructure.

Also move definition of NeedsComponent() closer to where it's used.
This commit is contained in:
Michel Dänzer 2007-08-30 13:30:03 +02:00
parent 6c9d7ed61b
commit 2e0895a4ba
3 changed files with 136 additions and 56 deletions

View File

@ -766,11 +766,8 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedComposite = ps->Composite; pExaScr->SavedComposite = ps->Composite;
ps->Composite = exaComposite; ps->Composite = exaComposite;
pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid; pExaScr->SavedTriangles = ps->Triangles;
ps->RasterizeTrapezoid = exaRasterizeTrapezoid; ps->Triangles = exaTriangles;
pExaScr->SavedAddTriangles = ps->AddTriangles;
ps->AddTriangles = exaAddTriangles;
pExaScr->SavedGlyphs = ps->Glyphs; pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs; ps->Glyphs = exaGlyphs;

View File

@ -111,8 +111,7 @@ typedef struct {
ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader; ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
#ifdef RENDER #ifdef RENDER
CompositeProcPtr SavedComposite; CompositeProcPtr SavedComposite;
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid; TrianglesProcPtr SavedTriangles;
AddTrianglesProcPtr SavedAddTriangles;
GlyphsProcPtr SavedGlyphs; GlyphsProcPtr SavedGlyphs;
TrapezoidsProcPtr SavedTrapezoids; TrapezoidsProcPtr SavedTrapezoids;
#endif #endif
@ -405,12 +404,9 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
int ntrap, xTrapezoid *traps); int ntrap, xTrapezoid *traps);
void void
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap, exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
int x_off, int y_off); PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int ntri, xTriangle *tris);
void
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
xTriangle *tris);
void void
exaGlyphs (CARD8 op, exaGlyphs (CARD8 op,

View File

@ -760,7 +760,7 @@ done:
* of PolyFillRect to initialize the pixmap after creating it, to prevent * of PolyFillRect to initialize the pixmap after creating it, to prevent
* the pixmap from being migrated. * the pixmap from being migrated.
* *
* See the comments about exaTrapezoids. * See the comments about exaTrapezoids and exaTriangles.
*/ */
static PicturePtr static PicturePtr
exaCreateAlphaPicture (ScreenPtr pScreen, exaCreateAlphaPicture (ScreenPtr pScreen,
@ -832,36 +832,70 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
{ {
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen); PictureScreenPtr ps = GetPictureScreen(pScreen);
BoxRec bounds;
Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
if (maskFormat || direct) {
miTrapezoidBounds (ntrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
}
/* /*
* Check for solid alpha add * Check for solid alpha add
*/ */
if (op == PictOpAdd && miIsSolidAlpha (pSrc)) if (direct)
{ {
DrawablePtr pDraw = pDst->pDrawable;
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
ExaPixmapPriv (pixmap);
RegionRec migration;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
int xoff, yoff;
exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
xoff += pDraw->x;
yoff += pDraw->y;
bounds.x1 += xoff;
bounds.y1 += yoff;
bounds.x2 += xoff;
bounds.y2 += yoff;
REGION_INIT(pScreen, &migration, &bounds, 1);
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
REGION_UNINIT(pScreen, &migration);
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
for (; ntrap; ntrap--, traps++) for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0); (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
} }
else if (maskFormat) else if (maskFormat)
{ {
PicturePtr pPicture; PicturePtr pPicture;
BoxRec bounds;
INT16 xDst, yDst; INT16 xDst, yDst;
INT16 xRel, yRel; INT16 xRel, yRel;
xDst = traps[0].left.p1.x >> 16; xDst = traps[0].left.p1.x >> 16;
yDst = traps[0].left.p1.y >> 16; yDst = traps[0].left.p1.y >> 16;
miTrapezoidBounds (ntrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat, pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
bounds.x2 - bounds.x1, bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1); bounds.y2 - bounds.y1);
if (!pPicture) if (!pPicture)
return; return;
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
for (; ntrap; ntrap--, traps++) for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pPicture, traps, (*ps->RasterizeTrapezoid) (pPicture, traps,
-bounds.x1, -bounds.y1); -bounds.x1, -bounds.y1);
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
xRel = bounds.x1 + xSrc - xDst; xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst; yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst, CompositePicture (op, pSrc, pPicture, pDst,
@ -881,51 +915,102 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
} }
} }
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
/** /**
* exaRasterizeTrapezoid is just a wrapper around the software implementation. * exaTriangles is essentially a copy of miTriangles that uses
* exaCreateAlphaPicture instead of miCreateAlphaPicture.
* *
* The trapezoid specification is basically too hard to be done in hardware (at * The problem with miCreateAlphaPicture is that it calls PolyFillRect
* the very least, without programmability), so we just do the appropriate * to initialize the contents after creating the pixmap, which
* Prepare/FinishAccess for it before using fbtrap.c. * causes the pixmap to be moved in for acceleration. The subsequent
* call to AddTriangles won't be accelerated however, which forces the pixmap
* to be moved out again.
*
* exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
* to initialize the contents.
*/ */
void void
exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap, exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
int x_off, int y_off) PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
int ntri, xTriangle *tris)
{ {
DrawablePtr pDraw = pPicture->pDrawable; ScreenPtr pScreen = pDst->pDrawable->pScreen;
PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw); PictureScreenPtr ps = GetPictureScreen(pScreen);
int xoff, yoff; BoxRec bounds;
Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
exaPrepareAccess(pDraw, EXA_PREPARE_DEST); if (maskFormat || direct) {
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off); miTriangleBounds (ntri, tris, &bounds);
exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
}
/** if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
* exaAddTriangles does migration and syncing before dumping down to the return;
* software implementation. }
/*
* Check for solid alpha add
*/ */
void if (direct)
exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri, {
xTriangle *tris) DrawablePtr pDraw = pDst->pDrawable;
{ PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
DrawablePtr pDraw = pPicture->pDrawable; ExaPixmapPriv (pixmap);
PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw); RegionRec migration;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
int xoff, yoff; int xoff, yoff;
exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
xoff += pDraw->x;
yoff += pDraw->y;
bounds.x1 += xoff;
bounds.y1 += yoff;
bounds.x2 += xoff;
bounds.y2 += yoff;
REGION_INIT(pScreen, &migration, &bounds, 1);
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
REGION_UNINIT(pScreen, &migration);
exaPrepareAccess(pDraw, EXA_PREPARE_DEST); exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbAddTriangles(pPicture, x_off, y_off, ntri, tris); (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST); exaFinishAccess(pDraw, EXA_PREPARE_DEST);
}
else if (maskFormat)
{
PicturePtr pPicture;
INT16 xDst, yDst;
INT16 xRel, yRel;
xDst = tris[0].p1.x >> 16;
yDst = tris[0].p1.y >> 16;
pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
(*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
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++)
exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
}
} }
/** /**
@ -1001,6 +1086,8 @@ exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
return FALSE; return FALSE;
} }
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The /* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
* migrate these pixmaps. So, instead we create a pixmap at the beginning of * migrate these pixmaps. So, instead we create a pixmap at the beginning of