Skip to content

Commit a6fb44b

Browse files
committed
Increase screen pixmap size beyond initial video RAM if needed
If FBBase is not backed by grant tables, it's now possible to reallocate it. This is especially useful when new external display is connected and the overall resolution is increased. Note the realloc() call may change FBBase address. In practice, FBBase is given to fbScreenInit, and it does save it at some point (fbScreenInit->fbFinishScreenInit->miScreenInit->miScreenDevPrivateInit), but then it's used only to attach it to the screen pixmap, which is updated via ModifyPixmapHeader() call few lines below anyway. Another place where it's used is DUMMY_OpenFramebuffer() and DUMMYDGAInit(). Avoid issues there by enabling DGA extension only if FBBase is backed by grant tables, so it won't be moved. DGA extension seems to be useless in purely virtual case anyway, as the framebuffer isn't displayed anywhere. This change adjusts also pScrn->videoRam. But fortunately X server seems to use it only at startup, and only to validate initial modes list. Fixes QubesOS/qubes-issues#7448
1 parent 9654fd0 commit a6fb44b

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

xf86-video-dummy/src/dummy_driver.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,13 +410,41 @@ Bool DUMMYAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
410410
"Failed to get the screen pixmap.\n");
411411
return FALSE;
412412
}
413-
if (cbLine > UINT32_MAX || cbLine * height > pScrn->videoRam * 1024)
414-
{
413+
if (cbLine > UINT32_MAX) {
415414
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
416-
"Unable to set up a virtual screen size of %dx%d with %d Kb of video memory available. Please increase the video memory size.\n",
417-
width, height, pScrn->videoRam);
415+
"Unable to set up a virtual screen size of %dx%d, cbLine "
416+
"overflow\n",
417+
width, height);
418418
return FALSE;
419419
}
420+
if (cbLine * height > pScrn->videoRam * 1024) {
421+
if (!dPtr->FBBasePriv) {
422+
/* If there is no backing grant entries, it's easy enough to extend
423+
*/
424+
pointer *newFBBase;
425+
size_t new_size = (cbLine * height + 1023) & ~1023;
426+
427+
newFBBase = realloc(dPtr->FBBase, new_size);
428+
if (!newFBBase) {
429+
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
430+
"Unable to set up a virtual screen size of %dx%d, "
431+
"cannot allocate memory (%lu bytes)\n",
432+
width, height, new_size);
433+
return FALSE;
434+
}
435+
memset((char*)newFBBase + pScrn->videoRam * 1024,
436+
0,
437+
new_size - pScrn->videoRam * 1024);
438+
dPtr->FBBase = newFBBase;
439+
pScrn->videoRam = new_size / 1024;
440+
} else {
441+
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
442+
"Unable to set up a virtual screen size of %dx%d with %d Kb of video memory available. Please increase the video memory size.\n",
443+
width, height, pScrn->videoRam);
444+
return FALSE;
445+
}
446+
}
447+
420448
pScreen->ModifyPixmapHeader(pPixmap, width, height,
421449
pScrn->depth, xf86GetBppFromDepth(pScrn, pScrn->depth), cbLine,
422450
dPtr->FBBase);
@@ -1127,7 +1155,8 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
11271155
pScreen->CreateScreenResources = qubes_create_screen_resources;
11281156

11291157
#ifdef USE_DGA
1130-
DUMMYDGAInit(pScreen);
1158+
if (dPtr->FBBasePriv)
1159+
DUMMYDGAInit(pScreen);
11311160
#endif
11321161

11331162
/* initialize XRANDR */

0 commit comments

Comments
 (0)