xfree86: Call ScreenInit for protocol screens before GPU screens

During startup, the xfree86 DDX's InitOutput() calls PreInit for
protocol screens first, and then GPU screens. On teardown, dix_main()
calls CloseScreen in the reverse order: GPU screens first starting with
the last one and then working backwards, and then protocol screens also
in reverse order.

InitOutput() calls ScreenInit in the wrong order: for GPU screens first and then
for protocol screens. This causes a problem for drivers that have global state
that is tied to the first screen that calls ScreenInit.

Fix this by simply re-ordering the for loops to call PreInit for
protocol screens first and then for GPU screens second.
This commit is contained in:
Aaron Plattner 2019-11-06 10:45:43 -08:00
parent 562c7888be
commit e5e9a8ca91
1 changed files with 25 additions and 25 deletions

View File

@ -620,31 +620,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0))
FatalError("Cannot register DDX private keys");
for (i = 0; i < xf86NumGPUScreens; i++) {
ScrnInfoPtr pScrn = xf86GPUScreens[i];
xf86VGAarbiterLock(pScrn);
/*
* Almost everything uses these defaults, and many of those that
* don't, will wrap them.
*/
pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
pScrn->SetDGAMode = xf86SetDGAMode;
#endif
scr_index = AddGPUScreen(xf86ScreenInit, argc, argv);
xf86VGAarbiterUnlock(pScrn);
if (scr_index == i) {
dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
pScrn->pScreen = screenInfo.gpuscreens[scr_index];
/* The driver should set this, but make sure it is set anyway */
pScrn->vtSema = TRUE;
} else {
FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
}
}
for (i = 0; i < xf86NumScreens; i++) {
xf86VGAarbiterLock(xf86Screens[i]);
/*
@ -690,6 +665,31 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
xf86EnsureRANDR(xf86Screens[i]->pScreen);
}
for (i = 0; i < xf86NumGPUScreens; i++) {
ScrnInfoPtr pScrn = xf86GPUScreens[i];
xf86VGAarbiterLock(pScrn);
/*
* Almost everything uses these defaults, and many of those that
* don't, will wrap them.
*/
pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
pScrn->SetDGAMode = xf86SetDGAMode;
#endif
scr_index = AddGPUScreen(xf86ScreenInit, argc, argv);
xf86VGAarbiterUnlock(pScrn);
if (scr_index == i) {
dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates,
xf86ScreenKey, xf86GPUScreens[i]);
pScrn->pScreen = screenInfo.gpuscreens[scr_index];
/* The driver should set this, but make sure it is set anyway */
pScrn->vtSema = TRUE;
} else {
FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index);
}
}
for (i = 0; i < xf86NumGPUScreens; i++)
AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen);