EXA: exaImageGlyphBlt improvements.
As we can't actually accelerate anything interesting here, just migrate out once and call fbSolidBoxClipped instead of taking a round trip via offscreen memory with exaSolidBoxClipped. Reuse pending damage region for extents and to prevent any actual migration of pixmap contents when we're overwriting the whole pending damage region. Remove superfluous manual damage tracking.
This commit is contained in:
parent
2e0895a4ba
commit
489bc7551f
174
exa/exa_accel.c
174
exa/exa_accel.c
|
@ -815,97 +815,6 @@ out:
|
||||||
REGION_DESTROY(pScreen, pReg);
|
REGION_DESTROY(pScreen, pReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
exaSolidBoxClipped (DrawablePtr pDrawable,
|
|
||||||
RegionPtr pClip,
|
|
||||||
FbBits pm,
|
|
||||||
FbBits fg,
|
|
||||||
int x1,
|
|
||||||
int y1,
|
|
||||||
int x2,
|
|
||||||
int y2)
|
|
||||||
{
|
|
||||||
ExaScreenPriv (pDrawable->pScreen);
|
|
||||||
PixmapPtr pPixmap;
|
|
||||||
BoxPtr pbox;
|
|
||||||
int nbox;
|
|
||||||
int xoff, yoff;
|
|
||||||
int partX1, partX2, partY1, partY2;
|
|
||||||
ExaMigrationRec pixmaps[1];
|
|
||||||
Bool fallback = FALSE;
|
|
||||||
|
|
||||||
pixmaps[0].as_dst = TRUE;
|
|
||||||
pixmaps[0].as_src = FALSE;
|
|
||||||
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
|
|
||||||
pixmaps[0].pReg = NULL;
|
|
||||||
|
|
||||||
if (pExaScr->swappedOut ||
|
|
||||||
pPixmap->drawable.width > pExaScr->info->maxX ||
|
|
||||||
pPixmap->drawable.height > pExaScr->info->maxY)
|
|
||||||
{
|
|
||||||
fallback = TRUE;
|
|
||||||
} else {
|
|
||||||
exaDoMigration (pixmaps, 1, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
|
|
||||||
|
|
||||||
if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
|
|
||||||
!(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
|
|
||||||
{
|
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
|
|
||||||
exaDrawableLocation(pDrawable)));
|
|
||||||
fallback = TRUE;
|
|
||||||
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
|
||||||
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
|
|
||||||
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
|
|
||||||
fbAnd (GXcopy, fg, pm),
|
|
||||||
fbXor (GXcopy, fg, pm));
|
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
|
||||||
}
|
|
||||||
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
|
|
||||||
nbox--;
|
|
||||||
pbox++)
|
|
||||||
{
|
|
||||||
partX1 = pbox->x1;
|
|
||||||
if (partX1 < x1)
|
|
||||||
partX1 = x1;
|
|
||||||
|
|
||||||
partX2 = pbox->x2;
|
|
||||||
if (partX2 > x2)
|
|
||||||
partX2 = x2;
|
|
||||||
|
|
||||||
if (partX2 <= partX1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
partY1 = pbox->y1;
|
|
||||||
if (partY1 < y1)
|
|
||||||
partY1 = y1;
|
|
||||||
|
|
||||||
partY2 = pbox->y2;
|
|
||||||
if (partY2 > y2)
|
|
||||||
partY2 = y2;
|
|
||||||
|
|
||||||
if (partY2 <= partY1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fallback) {
|
|
||||||
(*pExaScr->info->Solid) (pPixmap,
|
|
||||||
partX1 + xoff, partY1 + yoff,
|
|
||||||
partX2 + xoff, partY2 + yoff);
|
|
||||||
}
|
|
||||||
|
|
||||||
exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
|
|
||||||
partY2 + yoff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fallback)
|
|
||||||
return;
|
|
||||||
|
|
||||||
(*pExaScr->info->DoneSolid) (pPixmap);
|
|
||||||
exaMarkSync(pDrawable->pScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
exaImageGlyphBlt (DrawablePtr pDrawable,
|
exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
GCPtr pGC,
|
GCPtr pGC,
|
||||||
|
@ -922,7 +831,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
int gWidth, gHeight; /* width and height of glyph */
|
int gWidth, gHeight; /* width and height of glyph */
|
||||||
FbStride gStride; /* stride of glyph */
|
FbStride gStride; /* stride of glyph */
|
||||||
Bool opaque;
|
Bool opaque;
|
||||||
int n;
|
|
||||||
int gx, gy;
|
int gx, gy;
|
||||||
void (*glyph) (FbBits *,
|
void (*glyph) (FbBits *,
|
||||||
FbStride,
|
FbStride,
|
||||||
|
@ -936,37 +844,33 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
int dstBpp;
|
int dstBpp;
|
||||||
int dstXoff, dstYoff;
|
int dstXoff, dstYoff;
|
||||||
FbBits depthMask;
|
FbBits depthMask;
|
||||||
|
Bool fallback;
|
||||||
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
|
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
|
||||||
|
ExaPixmapPriv(pPixmap);
|
||||||
ExaMigrationRec pixmaps[1];
|
ExaMigrationRec pixmaps[1];
|
||||||
int xBack, widthBack, yBack, heightBack;
|
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
|
||||||
|
BoxRec extents = *REGION_EXTENTS(pScreen, pending_damage);
|
||||||
|
int xoff, yoff;
|
||||||
|
|
||||||
for (ppci = ppciInit, n = nglyph, widthBack = 0; n; n--)
|
if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2)
|
||||||
widthBack += (*ppci++)->metrics.characterWidth;
|
|
||||||
|
|
||||||
xBack = x;
|
|
||||||
if (widthBack < 0)
|
|
||||||
{
|
|
||||||
xBack += widthBack;
|
|
||||||
widthBack = -widthBack;
|
|
||||||
}
|
|
||||||
yBack = y - FONTASCENT(pGC->font);
|
|
||||||
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
|
|
||||||
|
|
||||||
if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
|
|
||||||
(xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pixmaps[0].as_dst = TRUE;
|
|
||||||
pixmaps[0].as_src = TRUE;
|
|
||||||
pixmaps[0].pPix = pPixmap;
|
|
||||||
pixmaps[0].pReg = NULL;
|
|
||||||
|
|
||||||
depthMask = FbFullMask(pDrawable->depth);
|
depthMask = FbFullMask(pDrawable->depth);
|
||||||
if ((pGC->planemask & depthMask) != depthMask)
|
fallback = (pGC->planemask & depthMask) != depthMask;
|
||||||
|
|
||||||
|
pixmaps[0].as_dst = TRUE;
|
||||||
|
pixmaps[0].as_src = FALSE;
|
||||||
|
pixmaps[0].pPix = pPixmap;
|
||||||
|
pixmaps[0].pReg = fallback ? NULL : pending_damage;
|
||||||
|
|
||||||
|
exaDoMigration(pixmaps, 1, FALSE);
|
||||||
|
|
||||||
|
if (fallback)
|
||||||
{
|
{
|
||||||
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
|
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
|
||||||
goto damage;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glyph = NULL;
|
glyph = NULL;
|
||||||
switch (pDrawable->bitsPerPixel) {
|
switch (pDrawable->bitsPerPixel) {
|
||||||
case 8: glyph = fbGlyph8; break;
|
case 8: glyph = fbGlyph8; break;
|
||||||
|
@ -977,8 +881,14 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
|
|
||||||
x += pDrawable->x;
|
x += pDrawable->x;
|
||||||
y += pDrawable->y;
|
y += pDrawable->y;
|
||||||
xBack += pDrawable->x;
|
|
||||||
yBack += pDrawable->y;
|
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
|
||||||
|
extents.x1 -= xoff;
|
||||||
|
extents.x2 -= xoff;
|
||||||
|
extents.y1 -= yoff;
|
||||||
|
extents.y2 -= yoff;
|
||||||
|
|
||||||
|
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
||||||
|
|
||||||
if (TERMINALFONT (pGC->font) && !glyph)
|
if (TERMINALFONT (pGC->font) && !glyph)
|
||||||
{
|
{
|
||||||
|
@ -986,19 +896,22 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exaSolidBoxClipped (pDrawable,
|
FbBits fg = fbReplicatePixel (pGC->bgPixel, pDrawable->bitsPerPixel);
|
||||||
fbGetCompositeClip(pGC),
|
|
||||||
pGC->planemask,
|
fbSolidBoxClipped (pDrawable,
|
||||||
pGC->bgPixel,
|
fbGetCompositeClip(pGC),
|
||||||
xBack,
|
extents.x1,
|
||||||
yBack,
|
extents.y1,
|
||||||
xBack + widthBack,
|
extents.x2,
|
||||||
yBack + heightBack);
|
extents.y2,
|
||||||
|
fbAnd (GXcopy, fg, pGC->planemask),
|
||||||
|
fbXor (GXcopy, fg, pGC->planemask));
|
||||||
|
|
||||||
opaque = FALSE;
|
opaque = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
|
||||||
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
|
|
||||||
exaPrepareAccessGC (pGC);
|
exaPrepareAccessGC (pGC);
|
||||||
|
|
||||||
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
|
||||||
|
@ -1011,9 +924,9 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
gx = x + pci->metrics.leftSideBearing;
|
gx = x + pci->metrics.leftSideBearing;
|
||||||
gy = y - pci->metrics.ascent;
|
gy = y - pci->metrics.ascent;
|
||||||
|
|
||||||
if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
|
if (!gWidth || !gHeight || (gx + gWidth) <= extents.x1 ||
|
||||||
(gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
|
(gy + gHeight) <= extents.y1 || gx >= extents.x2 ||
|
||||||
gy >= (yBack + heightBack))
|
gy >= extents.y2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
pglyph = FONTGLYPHBITS(pglyphBase, pci);
|
||||||
|
@ -1036,11 +949,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
|
||||||
}
|
}
|
||||||
exaFinishAccessGC (pGC);
|
exaFinishAccessGC (pGC);
|
||||||
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
|
||||||
|
|
||||||
damage:
|
|
||||||
exaGetDrawableDeltas(pDrawable, pPixmap, &dstXoff, &dstYoff);
|
|
||||||
exaPixmapDirty(pPixmap, xBack + dstXoff, yBack + dstYoff,
|
|
||||||
xBack + dstXoff + widthBack, yBack + dstYoff + heightBack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GCOps exaOps = {
|
const GCOps exaOps = {
|
||||||
|
|
Loading…
Reference in New Issue