EXA: RENDER improvements.

Exclude bits that will be overwritten from migration.

Use exaGlyphs even when Composite can't be accelerated, to avoid PolyFillRect
roundtrip via offscreen memory.

Initialize mask pixmap in exaGlyphs in FB in addition to system if the driver
provides Composite hooks to avoid migration overhead.

Remove manual damage tracking where superfluous.
This commit is contained in:
Michel Dänzer 2007-08-30 13:48:03 +02:00
parent 1f457ff3db
commit a634c9b034
4 changed files with 80 additions and 87 deletions

View File

@ -285,15 +285,19 @@ static Bool
exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
int bitsPerPixel, int devKind, pointer pPixData) int bitsPerPixel, int devKind, pointer pPixData)
{ {
ExaScreenPriv(pPixmap->drawable.pScreen); ExaScreenPrivPtr pExaScr;
ExaPixmapPriv(pPixmap); ExaPixmapPrivPtr pExaPixmap;
if (!pPixmap) if (!pPixmap)
return FALSE; return FALSE;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
if (pExaPixmap) if (pExaPixmap)
pExaPixmap->sys_ptr = pPixData; pExaPixmap->sys_ptr = pPixData;
pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth, return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData); bitsPerPixel, devKind, pPixData);
} }

View File

@ -384,6 +384,9 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
void *closure); void *closure);
/* exa_render.c */ /* exa_render.c */
Bool
exaOpReadsDestination (CARD8 op);
void void
exaComposite(CARD8 op, exaComposite(CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,

View File

@ -111,7 +111,7 @@ exaPrintCompositeFallback(CARD8 op,
} }
#endif /* DEBUG_TRACE_FALL */ #endif /* DEBUG_TRACE_FALL */
static Bool Bool
exaOpReadsDestination (CARD8 op) exaOpReadsDestination (CARD8 op)
{ {
/* FALSE (does not read destination) is the list of ops in the protocol /* FALSE (does not read destination) is the list of ops in the protocol
@ -261,17 +261,21 @@ exaTryDriverSolidFill(PicturePtr pSrc,
width, height)) width, height))
return 1; return 1;
pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
pixel = exaGetPixmapFirstPixel (pSrcPix); pixel = exaGetPixmapFirstPixel (pSrcPix);
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable); pixmaps[0].pPix = pDstPix;
pixmaps[0].pReg = NULL; pixmaps[0].pReg = &region;
exaDoMigration(pixmaps, 1, TRUE); exaDoMigration(pixmaps, 1, TRUE);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y); if (!exaPixmapIsOffscreen(pDstPix)) {
if (!pDstPix) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0; return 0;
} }
@ -301,9 +305,7 @@ exaTryDriverSolidFill(PicturePtr pSrc,
while (nbox--) while (nbox--)
{ {
(*pExaScr->info->Solid) (pDstPix, (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++; pbox++;
} }
@ -367,22 +369,26 @@ exaTryDriverComposite(CARD8 op,
xSrc += pSrc->pDrawable->x; xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y; ySrc += pSrc->pDrawable->y;
if (pExaScr->info->CheckComposite &&
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
{
return -1;
}
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst, xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height)) width, height))
return 1; return 1;
if (pExaScr->info->CheckComposite && pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
{
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
return -1;
}
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op); pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable); pixmaps[0].pPix = pDstPix;
pixmaps[0].pReg = NULL; pixmaps[0].pReg = pixmaps[0].as_src ? NULL : &region;
pixmaps[1].as_dst = FALSE; pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE; pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable); pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
@ -401,9 +407,8 @@ exaTryDriverComposite(CARD8 op,
if (pMask) if (pMask)
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
&mask_off_y); &mask_off_y);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix) { if (!exaPixmapIsOffscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return 0; return 0;
} }
@ -433,21 +438,21 @@ exaTryDriverComposite(CARD8 op,
nbox = REGION_NUM_RECTS(&region); nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region); pbox = REGION_RECTS(&region);
xMask -= xDst; xMask = xMask + mask_off_x - xDst - dst_off_x;
yMask -= yDst; yMask = yMask + mask_off_y - yDst - dst_off_y;
xSrc -= xDst; xSrc = xSrc + src_off_x - xDst - dst_off_x;
ySrc -= yDst; ySrc = ySrc + src_off_y - yDst - dst_off_y;
while (nbox--) while (nbox--)
{ {
(*pExaScr->info->Composite) (pDstPix, (*pExaScr->info->Composite) (pDstPix,
pbox->x1 + xSrc + src_off_x, pbox->x1 + xSrc,
pbox->y1 + ySrc + src_off_y, pbox->y1 + ySrc,
pbox->x1 + xMask + mask_off_x, pbox->x1 + xMask,
pbox->y1 + yMask + mask_off_y, pbox->y1 + yMask,
pbox->x1 + dst_off_x, pbox->x1,
pbox->y1 + dst_off_y, pbox->y1,
pbox->x2 - pbox->x1, pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1); pbox->y2 - pbox->y1);
pbox++; pbox++;
@ -523,9 +528,6 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
CARD16 height) CARD16 height)
{ {
ExaScreenPriv (pDst->pDrawable->pScreen); ExaScreenPriv (pDst->pDrawable->pScreen);
DrawablePtr pDstDraw = pDst->pDrawable;
PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
int xoff, yoff;
assert(op == PictOpOver); assert(op == PictOpOver);
@ -544,12 +546,6 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height); xDst, yDst, width, height);
exaGetDrawableDeltas(pDstDraw, pDstPixmap, &xoff, &yoff);
xoff += pDstDraw->x;
yoff += pDstDraw->y;
exaPixmapDirty(pDstPixmap, xDst + xoff, yDst + yoff, xDst + xoff + width,
yDst + yoff + height);
/* Then, add in the source value times the destination alpha factors (1.0). /* Then, add in the source value times the destination alpha factors (1.0).
*/ */
exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
@ -576,31 +572,8 @@ exaComposite(CARD8 op,
int ret = -1; int ret = -1;
Bool saveSrcRepeat = pSrc->repeat; Bool saveSrcRepeat = pSrc->repeat;
Bool saveMaskRepeat = pMask ? pMask->repeat : 0; Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
ExaMigrationRec pixmaps[3];
int npixmaps = 1;
PixmapPtr pSrcPixmap = NULL; PixmapPtr pSrcPixmap = NULL;
RegionRec region;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
pixmaps[0].pReg = NULL;
if (pSrc->pDrawable) {
pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = pSrcPixmap;
pixmaps[npixmaps].pReg = NULL;
npixmaps++;
}
if (pMask && pMask->pDrawable) {
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
pixmaps[npixmaps].pReg = NULL;
npixmaps++;
}
/* We currently don't support acceleration of gradients, or other pictures /* We currently don't support acceleration of gradients, or other pictures
* with a NULL pDrawable. * with a NULL pDrawable.
@ -638,8 +611,6 @@ exaComposite(CARD8 op,
} }
else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform) else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
{ {
RegionRec region;
xDst += pDst->pDrawable->x; xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y; yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x; xSrc += pSrc->pDrawable->x;
@ -661,7 +632,6 @@ exaComposite(CARD8 op,
else if (pSrcPixmap && !pSrc->transform && else if (pSrcPixmap && !pSrc->transform &&
pSrc->repeatType == RepeatNormal) pSrc->repeatType == RepeatNormal)
{ {
RegionRec region;
DDXPointRec srcOrg; DDXPointRec srcOrg;
/* Let's see if the driver can do the repeat in one go */ /* Let's see if the driver can do the repeat in one go */
@ -1092,6 +1062,9 @@ exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
* 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
* the loop and upload each glyph into the pixmap before compositing. * the loop and upload each glyph into the pixmap before compositing.
*
* This is now used even when Composite can't be accelerated for better
* migration control.
*/ */
void void
exaGlyphs (CARD8 op, exaGlyphs (CARD8 op,
@ -1108,11 +1081,10 @@ exaGlyphs (CARD8 op,
PixmapPtr pPixmap = NULL; PixmapPtr pPixmap = NULL;
PicturePtr pPicture; PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL; PixmapPtr pMaskPixmap = NULL;
PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
PicturePtr pMask; PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0; int width = 0, height = 0;
int x, y, x1, y1, xoff, yoff; int x, y, x1, y1;
int xDst = list->xOff, yDst = list->yOff; int xDst = list->xOff, yDst = list->yOff;
int n; int n;
int error; int error;
@ -1140,16 +1112,6 @@ exaGlyphs (CARD8 op,
} }
} }
/* If the driver doesn't support accelerated composite, there's no point in
* going to this extra work. Assume that any driver that supports Composite
* will be able to support component alpha using the two-pass helper.
*/
if (!pExaScr->info->PrepareComposite)
{
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
return;
}
if (maskFormat) if (maskFormat)
{ {
GCPtr pGC; GCPtr pGC;
@ -1186,8 +1148,11 @@ exaGlyphs (CARD8 op,
rect.y = 0; rect.y = 0;
rect.width = width; rect.width = width;
rect.height = height; rect.height = height;
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect);
exaPixmapDirty(pMaskPixmap, 0, 0, width, height); if (pExaScr->info->PrepareComposite)
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
else
exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
FreeScratchGC (pGC); FreeScratchGC (pGC);
x = -extents.x1; x = -extents.x1;
y = -extents.y1; y = -extents.y1;
@ -1199,8 +1164,6 @@ exaGlyphs (CARD8 op,
y = 0; y = 0;
} }
exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
while (nlist--) while (nlist--)
{ {
GCPtr pGC = NULL; GCPtr pGC = NULL;
@ -1339,10 +1302,6 @@ exaGlyphs (CARD8 op,
xSrc + x1 - xDst, ySrc + y1 - yDst, xSrc + x1 - xDst, ySrc + y1 - yDst,
0, 0, x1, y1, glyph->info.width, 0, 0, x1, y1, glyph->info.width,
glyph->info.height); glyph->info.height);
x1 += pDst->pDrawable->x + xoff;
y1 += pDst->pDrawable->y + yoff;
exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
y1 + glyph->info.height);
} }
nextglyph: nextglyph:
x += glyph->info.xOff; x += glyph->info.xOff;

View File

@ -23,6 +23,10 @@
#include "exa_priv.h" #include "exa_priv.h"
#ifdef RENDER
#include "mipict.h"
#endif
/* /*
* These functions wrap the low-level fb rendering functions and * These functions wrap the low-level fb rendering functions and
* synchronize framebuffer/accelerated drawing by stalling until * synchronize framebuffer/accelerated drawing by stalling until
@ -319,9 +323,30 @@ ExaCheckComposite (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
RegionRec region;
int xoff, yoff;
REGION_NULL(pScreen, &region);
if (!exaOpReadsDestination(op)) {
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
return;
exaGetDrawableDeltas (pDst->pDrawable,
exaGetDrawablePixmap(pDst->pDrawable),
&xoff, &yoff);
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
} else
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
EXA_FALLBACK(("from picts %p/%p to pict %p\n", EXA_FALLBACK(("from picts %p/%p to pict %p\n",
pSrc, pMask, pDst)); pSrc, pMask, pDst));
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
if (pSrc->pDrawable != NULL) if (pSrc->pDrawable != NULL)
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC); exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask && pMask->pDrawable != NULL) if (pMask && pMask->pDrawable != NULL)
@ -343,6 +368,8 @@ ExaCheckComposite (CARD8 op,
if (pSrc->pDrawable != NULL) if (pSrc->pDrawable != NULL)
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
REGION_UNINIT(pScreen, &region);
} }
/** /**