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:
parent
6c9d7ed61b
commit
2e0895a4ba
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
165
exa/exa_render.c
165
exa/exa_render.c
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue