Darwin: Patch to avert (some) damage / rootless crashes, courtesy of Ken Thomases
(cherry picked from commit 148a87ff20aa5e7a6d839610aa14fa1a31505c4a)
This commit is contained in:
parent
f5f833b806
commit
74214a9f42
|
@ -66,7 +66,6 @@ typedef struct _RootlessWindowRec {
|
||||||
int bytesPerRow;
|
int bytesPerRow;
|
||||||
|
|
||||||
PixmapPtr pixmap;
|
PixmapPtr pixmap;
|
||||||
PixmapPtr oldPixmap;
|
|
||||||
|
|
||||||
#ifdef ROOTLESS_TRACK_DAMAGE
|
#ifdef ROOTLESS_TRACK_DAMAGE
|
||||||
RegionRec damage;
|
RegionRec damage;
|
||||||
|
|
|
@ -172,9 +172,25 @@ void RootlessStartDrawing(WindowPtr pWindow)
|
||||||
winRec->is_drawing = TRUE;
|
winRec->is_drawing = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
winRec->oldPixmap = pScreen->GetWindowPixmap(pWindow);
|
PixmapPtr curPixmap = pScreen->GetWindowPixmap(pWindow);
|
||||||
|
if (curPixmap == winRec->pixmap)
|
||||||
|
{
|
||||||
|
RL_DEBUG_MSG("Window %p already has winRec->pixmap %p; not pushing\n", pWindow, winRec->pixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PixmapPtr oldPixmap = pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr;
|
||||||
|
if (oldPixmap != NULL)
|
||||||
|
{
|
||||||
|
if (oldPixmap == curPixmap)
|
||||||
|
RL_DEBUG_MSG("Window %p's curPixmap %p is the same as its oldPixmap; strange\n", pWindow, curPixmap);
|
||||||
|
else
|
||||||
|
RL_DEBUG_MSG("Window %p's existing oldPixmap %p being lost!\n", pWindow, oldPixmap);
|
||||||
|
}
|
||||||
|
pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = curPixmap;
|
||||||
pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
|
pScreen->SetWindowPixmap(pWindow, winRec->pixmap);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -182,6 +198,29 @@ void RootlessStartDrawing(WindowPtr pWindow)
|
||||||
* Stop drawing to a window's backing buffer. If flush is true,
|
* Stop drawing to a window's backing buffer. If flush is true,
|
||||||
* damaged regions are flushed to the screen.
|
* damaged regions are flushed to the screen.
|
||||||
*/
|
*/
|
||||||
|
static int RestorePreDrawingPixmapVisitor(WindowPtr pWindow, pointer data)
|
||||||
|
{
|
||||||
|
RootlessWindowRec *winRec = (RootlessWindowRec*)data;
|
||||||
|
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||||
|
PixmapPtr exPixmap = pScreen->GetWindowPixmap(pWindow);
|
||||||
|
PixmapPtr oldPixmap = pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr;
|
||||||
|
if (oldPixmap == NULL)
|
||||||
|
{
|
||||||
|
if (exPixmap == winRec->pixmap)
|
||||||
|
RL_DEBUG_MSG("Window %p appears to be in drawing mode (ex-pixmap %p equals winRec->pixmap, which is being freed) but has no oldPixmap!\n", pWindow, exPixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (exPixmap != winRec->pixmap)
|
||||||
|
RL_DEBUG_MSG("Window %p appears to be in drawing mode (oldPixmap %p) but ex-pixmap %p not winRec->pixmap %p!\n", pWindow, oldPixmap, exPixmap, winRec->pixmap);
|
||||||
|
if (oldPixmap == winRec->pixmap)
|
||||||
|
RL_DEBUG_MSG("Window %p's oldPixmap %p is winRec->pixmap, which has just been freed!\n", pWindow, oldPixmap);
|
||||||
|
pScreen->SetWindowPixmap(pWindow, oldPixmap);
|
||||||
|
pWindow->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = NULL;
|
||||||
|
}
|
||||||
|
return WT_WALKCHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
|
void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||||
|
@ -198,7 +237,7 @@ void RootlessStopDrawing(WindowPtr pWindow, Bool flush)
|
||||||
SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
|
SCREENREC(pScreen)->imp->StopDrawing(winRec->wid, flush);
|
||||||
|
|
||||||
FreeScratchPixmapHeader(winRec->pixmap);
|
FreeScratchPixmapHeader(winRec->pixmap);
|
||||||
pScreen->SetWindowPixmap(pWindow, winRec->oldPixmap);
|
TraverseTree(top, RestorePreDrawingPixmapVisitor, (pointer)winRec);
|
||||||
winRec->pixmap = NULL;
|
winRec->pixmap = NULL;
|
||||||
|
|
||||||
winRec->is_drawing = FALSE;
|
winRec->is_drawing = FALSE;
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
extern int rootlessGCPrivateIndex;
|
extern int rootlessGCPrivateIndex;
|
||||||
extern int rootlessScreenPrivateIndex;
|
extern int rootlessScreenPrivateIndex;
|
||||||
extern int rootlessWindowPrivateIndex;
|
extern int rootlessWindowPrivateIndex;
|
||||||
|
extern int rootlessWindowOldPixmapPrivateIndex;
|
||||||
|
|
||||||
|
|
||||||
// RootlessGCRec: private per-gc data
|
// RootlessGCRec: private per-gc data
|
||||||
|
|
|
@ -65,6 +65,7 @@ extern Bool RootlessCreateGC(GCPtr pGC);
|
||||||
int rootlessGCPrivateIndex = -1;
|
int rootlessGCPrivateIndex = -1;
|
||||||
int rootlessScreenPrivateIndex = -1;
|
int rootlessScreenPrivateIndex = -1;
|
||||||
int rootlessWindowPrivateIndex = -1;
|
int rootlessWindowPrivateIndex = -1;
|
||||||
|
int rootlessWindowOldPixmapPrivateIndex = -1;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -618,6 +619,8 @@ RootlessAllocatePrivates(ScreenPtr pScreen)
|
||||||
if (rootlessGCPrivateIndex == -1) return FALSE;
|
if (rootlessGCPrivateIndex == -1) return FALSE;
|
||||||
rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
|
rootlessWindowPrivateIndex = AllocateWindowPrivateIndex();
|
||||||
if (rootlessWindowPrivateIndex == -1) return FALSE;
|
if (rootlessWindowPrivateIndex == -1) return FALSE;
|
||||||
|
rootlessWindowOldPixmapPrivateIndex = AllocateWindowPrivateIndex();
|
||||||
|
if (rootlessWindowOldPixmapPrivateIndex == -1) return FALSE;
|
||||||
rootlessGeneration = serverGeneration;
|
rootlessGeneration = serverGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,6 +630,8 @@ RootlessAllocatePrivates(ScreenPtr pScreen)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
|
if (!AllocateWindowPrivate(pScreen, rootlessWindowPrivateIndex, 0))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
if (!AllocateWindowPrivate(pScreen, rootlessWindowOldPixmapPrivateIndex, 0))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
s = xalloc(sizeof(RootlessScreenRec));
|
s = xalloc(sizeof(RootlessScreenRec));
|
||||||
if (! s) return FALSE;
|
if (! s) return FALSE;
|
||||||
|
|
|
@ -198,6 +198,7 @@ RootlessCreateWindow(WindowPtr pWin)
|
||||||
RegionRec saveRoot;
|
RegionRec saveRoot;
|
||||||
|
|
||||||
WINREC(pWin) = NULL;
|
WINREC(pWin) = NULL;
|
||||||
|
pWin->devPrivates[rootlessWindowOldPixmapPrivateIndex].ptr = NULL;
|
||||||
|
|
||||||
SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow);
|
SCREEN_UNWRAP(pWin->drawable.pScreen, CreateWindow);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue