EXA: Hide pixmap pointer outside of exaPrepare/FinishAccess whenever possible.
We finally want to catch all cases where the pixmap pointer is dereferenced outside of exaPrepare/FinishAccess. Also fix a couple of such cases exposed by this change.
This commit is contained in:
parent
962eddd7a2
commit
6c9d7ed61b
99
exa/exa.c
99
exa/exa.c
|
@ -44,6 +44,17 @@ static int exaGeneration;
|
|||
int exaScreenPrivateIndex;
|
||||
int exaPixmapPrivateIndex;
|
||||
|
||||
static _X_INLINE void*
|
||||
ExaGetPixmapAddress(PixmapPtr p)
|
||||
{
|
||||
ExaPixmapPriv(p);
|
||||
|
||||
if (pExaPixmap->offscreen && pExaPixmap->fb_ptr)
|
||||
return pExaPixmap->fb_ptr;
|
||||
else
|
||||
return pExaPixmap->sys_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
|
||||
* the beginning of the given pixmap.
|
||||
|
@ -58,16 +69,9 @@ unsigned long
|
|||
exaGetPixmapOffset(PixmapPtr pPix)
|
||||
{
|
||||
ExaScreenPriv (pPix->drawable.pScreen);
|
||||
ExaPixmapPriv (pPix);
|
||||
void *ptr;
|
||||
|
||||
/* 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);
|
||||
return ((unsigned long)ExaGetPixmapAddress(pPix) -
|
||||
(unsigned long)pExaScr->info->memoryBase);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,6 +245,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
|||
pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
|
||||
pExaPixmap->sys_pitch = pPixmap->devKind;
|
||||
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
pExaPixmap->offscreen = FALSE;
|
||||
|
||||
pExaPixmap->fb_ptr = NULL;
|
||||
if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
|
||||
pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
|
||||
|
@ -274,6 +281,23 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
|||
return pPixmap;
|
||||
}
|
||||
|
||||
static Bool
|
||||
exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
|
||||
int bitsPerPixel, int devKind, pointer pPixData)
|
||||
{
|
||||
ExaScreenPriv(pPixmap->drawable.pScreen);
|
||||
ExaPixmapPriv(pPixmap);
|
||||
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
|
||||
if (pExaPixmap)
|
||||
pExaPixmap->sys_ptr = pPixData;
|
||||
|
||||
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
|
||||
bitsPerPixel, devKind, pPixData);
|
||||
}
|
||||
|
||||
/**
|
||||
* exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
|
||||
* memory, meaning that acceleration could probably be done to it, and that it
|
||||
|
@ -291,18 +315,25 @@ exaPixmapIsOffscreen(PixmapPtr p)
|
|||
{
|
||||
ScreenPtr pScreen = p->drawable.pScreen;
|
||||
ExaScreenPriv(pScreen);
|
||||
ExaPixmapPriv(p);
|
||||
void *save_ptr;
|
||||
Bool ret;
|
||||
|
||||
/* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
|
||||
*/
|
||||
if (p->devPrivate.ptr == NULL)
|
||||
return TRUE;
|
||||
save_ptr = p->devPrivate.ptr;
|
||||
|
||||
if (!save_ptr && pExaPixmap)
|
||||
p->devPrivate.ptr = ExaGetPixmapAddress(p);
|
||||
|
||||
if (pExaScr->info->PixmapIsOffscreen)
|
||||
return pExaScr->info->PixmapIsOffscreen(p);
|
||||
ret = pExaScr->info->PixmapIsOffscreen(p);
|
||||
else
|
||||
ret = ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
||||
(CARD8 *) pExaScr->info->memoryBase) <
|
||||
pExaScr->info->memorySize);
|
||||
|
||||
return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
||||
(CARD8 *) pExaScr->info->memoryBase) <
|
||||
pExaScr->info->memorySize);
|
||||
p->devPrivate.ptr = save_ptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -336,22 +367,19 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
|
|||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
ExaScreenPriv (pScreen);
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
if (exaPixmapIsOffscreen (pPixmap))
|
||||
exaWaitSync (pDrawable->pScreen);
|
||||
else
|
||||
return;
|
||||
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
|
||||
|
||||
/* Unhide pixmap pointer */
|
||||
if (pPixmap->devPrivate.ptr == NULL) {
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
|
||||
}
|
||||
|
||||
if (!offscreen)
|
||||
return;
|
||||
|
||||
exaWaitSync (pDrawable->pScreen);
|
||||
|
||||
if (pExaScr->info->PrepareAccess == NULL)
|
||||
return;
|
||||
|
||||
|
@ -400,18 +428,13 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
|
|||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
ExaScreenPriv (pScreen);
|
||||
PixmapPtr pPixmap;
|
||||
ExaPixmapPrivPtr pExaPixmap;
|
||||
|
||||
pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
|
||||
pExaPixmap = ExaGetPixmapPriv(pPixmap);
|
||||
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
|
||||
ExaPixmapPriv (pPixmap);
|
||||
|
||||
/* Rehide pixmap pointer if we're doing that. */
|
||||
if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
|
||||
pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
|
||||
if (pExaPixmap)
|
||||
{
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
}
|
||||
|
||||
if (pExaScr->info->FinishAccess == NULL)
|
||||
|
@ -783,6 +806,8 @@ exaDriverInit (ScreenPtr pScreen,
|
|||
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
|
||||
pScreen->DestroyPixmap = exaDestroyPixmap;
|
||||
|
||||
pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
|
||||
pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
|
||||
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
|
||||
pScreen->myNum,
|
||||
pExaScr->info->memorySize - pExaScr->info->offScreenBase);
|
||||
|
|
|
@ -213,8 +213,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
|||
int dstXoff, dstYoff;
|
||||
|
||||
if (!access_prepared) {
|
||||
exaPrepareAccessReg(pDrawable, EXA_PREPARE_DEST,
|
||||
pixmaps[0].pReg);
|
||||
ExaDoPrepareAccess(pDrawable, EXA_PREPARE_DEST);
|
||||
|
||||
access_prepared = TRUE;
|
||||
}
|
||||
|
@ -233,14 +232,14 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
|
|||
GXcopy, FB_ALLONES, dstBpp);
|
||||
}
|
||||
|
||||
if (access_prepared)
|
||||
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
||||
else
|
||||
exaMarkSync(pDrawable->pScreen);
|
||||
|
||||
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
|
||||
}
|
||||
|
||||
if (access_prepared)
|
||||
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
||||
else
|
||||
exaMarkSync(pDrawable->pScreen);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fallback:
|
||||
|
@ -271,8 +270,10 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
|
|||
src_stride))
|
||||
return;
|
||||
|
||||
exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
|
||||
fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
|
||||
data);
|
||||
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
|
||||
}
|
||||
|
||||
ShmFuncs exaShmFuncs = { NULL, exaShmPutImage };
|
||||
|
|
|
@ -323,10 +323,8 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
|
|||
pPixmap->drawable.height,
|
||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||
|
||||
if (pExaScr->hideOffscreenPixmapData)
|
||||
pPixmap->devPrivate.ptr = NULL;
|
||||
else
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
|
||||
pExaPixmap->offscreen = TRUE;
|
||||
|
||||
pPixmap->devKind = pExaPixmap->fb_pitch;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
@ -365,7 +363,8 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate)
|
|||
pPixmap->drawable.height,
|
||||
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
|
||||
|
||||
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
|
||||
pExaPixmap->offscreen = FALSE;
|
||||
|
||||
pPixmap->devKind = pExaPixmap->sys_pitch;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ typedef struct {
|
|||
CopyWindowProcPtr SavedCopyWindow;
|
||||
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
|
||||
BitmapToRegionProcPtr SavedBitmapToRegion;
|
||||
ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
|
||||
#ifdef RENDER
|
||||
CompositeProcPtr SavedComposite;
|
||||
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
|
||||
|
@ -118,7 +119,6 @@ typedef struct {
|
|||
|
||||
Bool swappedOut;
|
||||
enum ExaMigrationHeuristic migration;
|
||||
Bool hideOffscreenPixmapData;
|
||||
Bool checkDirtyCorrectness;
|
||||
unsigned disableFbCount;
|
||||
} ExaScreenPrivRec, *ExaScreenPrivPtr;
|
||||
|
@ -160,6 +160,7 @@ extern int exaPixmapPrivateIndex;
|
|||
typedef struct {
|
||||
ExaOffscreenArea *area;
|
||||
int score; /**< score for the move-in vs move-out heuristic */
|
||||
Bool offscreen;
|
||||
|
||||
CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
|
||||
int sys_pitch; /**< pitch of pixmap in system memory */
|
||||
|
|
Loading…
Reference in New Issue