mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-15 00:13:28 +00:00
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:
parent
f480dc797b
commit
2e38fedd29
9 changed files with 275 additions and 59 deletions
42
exa/exa.c
42
exa/exa.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue