Add an option to EXA for the DDX to request that EXA hide the pixmap's

devPrivate.ptr when pointing at offscreen memory, outside of
    exaPrepare/FinishAccess(). This was used with fakexa to find (by NULL
    dereference) many instances of un-Prepared CPU access to the
    framebuffer:
- GC tiles used in several ops when fillStyle == FillTiled were never
    Prepared.
- Migration could lead to un-Prepared access to mask data in render's
    Trapezoids and Triangles
- PutImage's UploadToScreen failure fallback failed to Prepare.
This commit is contained in:
Eric Anholt 2006-03-31 19:41:28 +00:00
commit 2e38fedd29
9 changed files with 275 additions and 59 deletions

View file

@ -58,9 +58,16 @@ unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
ExaScreenPriv (pPix->drawable.pScreen);
ExaPixmapPriv (pPix);
void *ptr;
return ((unsigned long)pPix->devPrivate.ptr -
(unsigned long)pExaScr->info->memoryBase);
/* Return the offscreen pointer if we've hidden the data. */
if (pPix->devPrivate.ptr == NULL)
ptr = pExaPixmap->fb_ptr;
else
ptr = pPix->devPrivate.ptr;
return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
}
/**
@ -232,6 +239,11 @@ exaPixmapIsOffscreen(PixmapPtr p)
ScreenPtr pScreen = p->drawable.pScreen;
ExaScreenPriv(pScreen);
/* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
*/
if (p->devPrivate.ptr == NULL)
return TRUE;
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
(CARD8 *) pExaScr->info->memoryBase) <
pExaScr->info->memorySize);
@ -301,6 +313,13 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
else
return;
/* Unhide pixmap pointer */
if (pPixmap->devPrivate.ptr == NULL) {
ExaPixmapPriv (pPixmap);
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
}
if (pExaScr->info->PrepareAccess == NULL)
return;
@ -324,14 +343,25 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
pPixmap = exaGetDrawablePixmap (pDrawable);
pExaPixmap = ExaGetPixmapPriv(pPixmap);
/* Rehide pixmap pointer if we're doing that. */
if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
{
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
}
if (pExaScr->info->FinishAccess == NULL)
return;
pPixmap = exaGetDrawablePixmap (pDrawable);
if (!exaPixmapIsOffscreen (pPixmap))
return;
@ -508,6 +538,12 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedComposite = ps->Composite;
ps->Composite = exaComposite;
pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid;
ps->RasterizeTrapezoid = exaRasterizeTrapezoid;
pExaScr->SavedAddTriangles = ps->AddTriangles;
ps->AddTriangles = exaAddTriangles;
pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs;
}