Pin header-only pixmaps in memory.

Off-screen reallocation could have used a stale pointer.
Separate framebuffer mapping computation from actual frame buffer mapping.
    Now map the frame buffer from vesaEnable so that VT switch shares the
    same mapping code. This makes sure any shadow framebuffer is allocated
    again.
This commit is contained in:
Keith Packard 2004-05-20 02:42:20 +00:00
parent cade317d31
commit 94648799c8
5 changed files with 85 additions and 63 deletions

View File

@ -51,8 +51,10 @@ int kaaPixmapPrivateIndex;
#define KAA_PIXMAP_SCORE_MOVE_IN 10
#define KAA_PIXMAP_SCORE_MAX 20
#define KAA_PIXMAP_SCORE_INIT 0
#define KAA_PIXMAP_SCORE_MOVE_OUT -10
#define KAA_PIXMAP_SCORE_MIN -20
#define KAA_PIXMAP_SCORE_PINNED 1000
#define MIN_OFFPIX_SIZE (4096)
@ -212,6 +214,9 @@ kaaPixmapUseScreen (PixmapPtr pPixmap)
{
KaaPixmapPriv (pPixmap);
if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED)
return;
if (pKaaPixmap->score < KAA_PIXMAP_SCORE_MAX)
{
pKaaPixmap->score++;
@ -226,6 +231,9 @@ kaaPixmapUseMemory (PixmapPtr pPixmap)
{
KaaPixmapPriv (pPixmap);
if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED)
return;
if (pKaaPixmap->score > KAA_PIXMAP_SCORE_MIN)
{
pKaaPixmap->score--;
@ -282,10 +290,15 @@ kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
if (!pPixmap)
return NULL;
pKaaPixmap = KaaGetPixmapPriv(pPixmap);
pKaaPixmap->score = 0;
if (!w || !h)
pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED;
else
pKaaPixmap->score = KAA_PIXMAP_SCORE_INIT;
pKaaPixmap->area = NULL;
if ((pPixmap->devKind * h) >= MIN_OFFPIX_SIZE)
if (pKaaPixmap->score != KAA_PIXMAP_SCORE_PINNED &&
(pPixmap->devKind * h) >= MIN_OFFPIX_SIZE)
kaaPixmapAllocArea (pPixmap);
return pPixmap;
}

View File

@ -882,7 +882,7 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
KdOffscreenSaveProc save,
pointer privData);
void
KdOffscreenArea *
KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area);
void

View File

@ -55,12 +55,12 @@ KdOffscreenValidate (ScreenPtr pScreen)
#define KdOffscreenValidate(s)
#endif
static void
static KdOffscreenArea *
KdOffscreenKickOut (ScreenPtr pScreen, KdOffscreenArea *area)
{
if (area->save)
(*area->save) (pScreen, area);
KdOffscreenFree (pScreen, area);
return KdOffscreenFree (pScreen, area);
}
KdOffscreenArea *
@ -161,14 +161,14 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
* Kick out first area if in use
*/
if (area->state != KdOffscreenAvail)
KdOffscreenKickOut (pScreen, area);
area = KdOffscreenKickOut (pScreen, area);
/*
* Now get the system to merge the other needed areas together
*/
while (area->size < real_size)
{
assert (area->next && area->next->state == KdOffscreenRemovable);
KdOffscreenKickOut (pScreen, area->next);
(void) KdOffscreenKickOut (pScreen, area->next);
}
}
@ -225,7 +225,7 @@ KdOffscreenSwapOut (ScreenPtr pScreen)
break;
}
assert (area->state != KdOffscreenAvail);
KdOffscreenKickOut (pScreen, area);
(void) KdOffscreenKickOut (pScreen, area);
KdOffscreenValidate (pScreen);
}
KdOffscreenValidate (pScreen);
@ -251,7 +251,7 @@ KdOffscreenMerge (KdOffscreenArea *area)
xfree (next);
}
void
KdOffscreenArea *
KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area)
{
KdScreenPriv(pScreen);
@ -281,9 +281,13 @@ KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area)
/* link with prev area if free */
if (prev && prev->state == KdOffscreenAvail)
KdOffscreenMerge (prev);
{
area = prev;
KdOffscreenMerge (area);
}
KdOffscreenValidate (pScreen);
return area;
}
Bool

View File

@ -47,6 +47,12 @@ Bool vesa_map_holes = TRUE;
#define vesaWidth(scr,vmib) ((vmib)->XResolution)
#define vesaHeight(scr,vmib) ((vmib)->YResolution)
static Bool
vesaComputeFramebufferMapping (KdScreenInfo *screen);
static Bool
vesaMapFramebuffer (KdScreenInfo *screen);
static Bool
vesaModeSupportable (VesaModePtr mode, Bool complain)
{
@ -507,7 +513,11 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
}
screen->rate = 72;
return vesaMapFramebuffer (screen);
if (!vesaComputeFramebufferMapping (screen))
return FALSE;
if (!vesaMapFramebuffer (screen))
return FALSE;
return TRUE;
}
Bool
@ -850,10 +860,9 @@ vesaSetShadow (ScreenPtr pScreen)
return KdShadowSet (pScreen, pscr->randr, update, window);
}
Bool
vesaMapFramebuffer (KdScreenInfo *screen)
static Bool
vesaComputeFramebufferMapping (KdScreenInfo *screen)
{
VesaCardPrivPtr priv = screen->card->driver;
VesaScreenPrivPtr pscr = screen->driver;
int depth, bpp, fbbpp;
Pixel allbits;
@ -956,7 +965,27 @@ vesaMapFramebuffer (KdScreenInfo *screen)
pscr->mapping = VESA_WINDOWED;
pscr->shadow = TRUE;
}
KdComputeMouseMatrix (&m, pscr->randr,
pscr->mode.XResolution, pscr->mode.YResolution);
KdSetMouseMatrix (&m);
screen->width = pscr->mode.XResolution;
screen->height = pscr->mode.YResolution;
screen->fb[0].depth = depth;
screen->fb[0].bitsPerPixel = bpp;
return TRUE;
}
static Bool
vesaMapFramebuffer (KdScreenInfo *screen)
{
VesaCardPrivPtr priv = screen->card->driver;
VesaScreenPrivPtr pscr = screen->driver;
if (pscr->mapped)
return TRUE;
switch (pscr->mapping) {
case VESA_MONO:
case VESA_LINEAR:
@ -981,17 +1010,8 @@ vesaMapFramebuffer (KdScreenInfo *screen)
break;
}
KdComputeMouseMatrix (&m, pscr->randr,
pscr->mode.XResolution, pscr->mode.YResolution);
KdSetMouseMatrix (&m);
screen->width = pscr->mode.XResolution;
screen->height = pscr->mode.YResolution;
screen->memory_base = pscr->fb;
screen->memory_size = pscr->fb_size;
screen->fb[0].depth = depth;
screen->fb[0].bitsPerPixel = bpp;
if (pscr->shadow)
{
@ -1008,16 +1028,21 @@ vesaMapFramebuffer (KdScreenInfo *screen)
screen->fb[0].bitsPerPixel);
screen->off_screen_base = screen->fb[0].byteStride * screen->height;
}
pscr->mapped = TRUE;
return TRUE;
}
void
static void
vesaUnmapFramebuffer (KdScreenInfo *screen)
{
VesaCardPrivPtr priv = screen->card->driver;
VesaScreenPrivPtr pscr = screen->driver;
if (!pscr->mapped)
return;
pscr->mapped = FALSE;
KdShadowFbFree (screen, 0);
if (pscr->fb)
{
@ -1201,6 +1226,9 @@ vesaRandRSetConfig (ScreenPtr pScreen,
vesaUnmapFramebuffer (screen);
if (!vesaComputeFramebufferMapping (screen))
goto bail3;
if (!vesaMapFramebuffer (screen))
goto bail3;
@ -1231,6 +1259,7 @@ vesaRandRSetConfig (ScreenPtr pScreen,
bail4:
vesaUnmapFramebuffer (screen);
*pscr = oldscr;
(void) vesaComputeFramebufferMapping (screen);
(void) vesaMapFramebuffer (screen);
bail3:
@ -1332,6 +1361,10 @@ vesaEnable(ScreenPtr pScreen)
int i;
CARD32 size;
char *p;
Bool was_mapped = pscr->mapped;
if (!vesaMapFramebuffer (screen))
return FALSE;
if (!vesaSetMode (pScreen, &pscr->mode))
return FALSE;
@ -1340,39 +1373,6 @@ vesaEnable(ScreenPtr pScreen)
case VESA_MONO:
VgaSetWritePlaneMask (priv->vi, 0x1);
case VESA_LINEAR:
/*
* Remap the frame buffer if necessary
*/
if (!pscr->fb)
{
if (pscr->mode.vbe)
pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
pscr->mode.mode,
&pscr->fb_size,
&pscr->fb_phys);
else
pscr->fb = VgaMapFramebuffer (priv->vi,
pscr->mode.mode,
&pscr->fb_size,
&pscr->fb_phys);
if (!pscr->fb)
return FALSE;
screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
screen->memory_base = pscr->fb;
/*
* Set frame buffer mapping
*/
if (!pscr->shadow)
{
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
pScreen->width,
pScreen->height,
screen->fb[0].depth,
screen->fb[0].bitsPerPixel,
screen->fb[0].byteStride,
screen->fb[0].frameBuffer);
}
}
if (vesa_restore_font)
memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
break;
@ -1405,6 +1405,16 @@ vesaEnable(ScreenPtr pScreen)
}
break;
}
if (!was_mapped)
{
(*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
pScreen->width,
pScreen->height,
screen->fb[0].depth,
screen->fb[0].bitsPerPixel,
screen->fb[0].byteStride,
screen->fb[0].frameBuffer);
}
return TRUE;
}

View File

@ -102,6 +102,7 @@ typedef struct _VesaScreenPriv {
int fb_size;
CARD32 fb_phys;
PixmapPtr pShadow;
Bool mapped;
} VesaScreenPrivRec, *VesaScreenPrivPtr;
extern int vesa_video_mode;
@ -223,12 +224,6 @@ vesaScreenInit(KdScreenInfo *screen);
PixmapPtr
vesaGetPixmap (ScreenPtr pScreen);
Bool
vesaMapFramebuffer (KdScreenInfo *screen);
void
vesaUnmapFramebuffer (KdScreenInfo *screen);
Bool
vesaInitScreen(ScreenPtr pScreen);