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