Skip to content

Commit fc21a08

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. 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 f1798d3 commit fc21a08

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

xf86-video-dummy/src/dummy_driver.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,41 @@ Bool DUMMYAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
406406
"Failed to get the screen pixmap.\n");
407407
return FALSE;
408408
}
409-
if (cbLine > UINT32_MAX || cbLine * height > pScrn->videoRam * 1024)
410-
{
409+
if (cbLine > UINT32_MAX) {
411410
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
412-
"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",
413-
width, height, pScrn->videoRam);
411+
"Unable to set up a virtual screen size of %dx%d, cbLine "
412+
"overflow\n",
413+
width, height);
414414
return FALSE;
415415
}
416+
if (cbLine * height > pScrn->videoRam * 1024) {
417+
if (!dPtr->FBBasePriv) {
418+
/* If there is no backing grant entries, it's easy enough to extend
419+
*/
420+
pointer *newFBBase;
421+
size_t new_size = (cbLine * height + 1023) & ~1023;
422+
423+
newFBBase = realloc(dPtr->FBBase, new_size);
424+
if (!newFBBase) {
425+
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
426+
"Unable to set up a virtual screen size of %dx%d, "
427+
"cannot allocate memory (%zu bytes)\n",
428+
width, height, new_size);
429+
return FALSE;
430+
}
431+
memset((char*)newFBBase + pScrn->videoRam * 1024,
432+
0,
433+
new_size - pScrn->videoRam * 1024);
434+
dPtr->FBBase = newFBBase;
435+
pScrn->videoRam = new_size / 1024;
436+
} else {
437+
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
438+
"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",
439+
width, height, pScrn->videoRam);
440+
return FALSE;
441+
}
442+
}
443+
416444
pScreen->ModifyPixmapHeader(pPixmap, width, height,
417445
pScrn->depth, xf86GetBppFromDepth(pScrn, pScrn->depth), cbLine,
418446
dPtr->FBBase);

0 commit comments

Comments
 (0)