diff options
author | Eric Anholt <anholt@freebsd.org> | 2006-04-18 19:14:07 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2006-04-18 19:14:07 +0000 |
commit | b17a4de83e7ab18bef29ae898195889638f1cc6a (patch) | |
tree | 6ae3d6465edfbe4c950ebfff9a8641894607ea7a /exa | |
parent | 771b366abe0bc060592b548612ec413291e14bf0 (diff) |
Add a new migration scheme, called "Smart" for lack of a better name. This
one behaves somewhat between Greedy and Always. It moves in if we can
accelerate, unless the destination is clean and shouldn't be kept in
framebuffer according to the score, in which case we migrate out (and
force-migrate anything where migration is free). This should help fix
lack of acceleration for drivers without UTS since removing
exaAsyncPixmapGCOps, and has removed one performance trap with Radeon
I'd noticed. It is the new default.
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa.c | 2 | ||||
-rw-r--r-- | exa/exa_migration.c | 61 | ||||
-rw-r--r-- | exa/exa_priv.h | 3 |
3 files changed, 63 insertions, 3 deletions
@@ -557,7 +557,7 @@ exaDriverInit (ScreenPtr pScreen, pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr; - pExaScr->migration = ExaMigrationGreedy; + pExaScr->migration = ExaMigrationSmart; exaDDXDriverInit(pScreen); diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 50700ed46..ef7cfd86e 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -58,6 +58,36 @@ exaPixmapIsPinned (PixmapPtr pPix) } /** + * Returns TRUE if the pixmap is dirty (has been modified in its current + * location compared to the other), or lacks a private for tracking + * dirtiness. + */ +static Bool +exaPixmapIsDirty (PixmapPtr pPix) +{ + ExaPixmapPriv (pPix); + + return pExaPixmap == NULL || pExaPixmap->dirty == TRUE; +} + +/** + * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score + * to be considered "should be in framebuffer". + * + * Only valid if using a migration scheme that tracks score. + */ +static Bool +exaPixmapShouldBeInFB (PixmapPtr pPix) +{ + ExaPixmapPriv (pPix); + + if (exaPixmapIsPinned (pPix)) + return TRUE; + + return pExaPixmap->score >= EXA_PIXMAP_SCORE_INIT; +} + +/** * If the pixmap is currently dirty, this copies at least the dirty area from * the framebuffer memory copy to the system memory copy. Both areas must be * allocated. @@ -403,7 +433,36 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) } } - if (pExaScr->migration == ExaMigrationGreedy) { + if (pExaScr->migration == ExaMigrationSmart) { + /* If we've got something as a destination that we shouldn't cause to + * become newly dirtied, take the unaccelerated route. + */ + for (i = 0; i < npixmaps; i++) { + if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) && + !exaPixmapIsDirty (pixmaps[i].pPix)) + { + can_accel = FALSE; + } + } + + /* If we aren't going to accelerate, then we migrate everybody toward + * system memory, and kick out if it's free. + */ + if (!can_accel) { + for (i = 0; i < npixmaps; i++) { + exaMigrateTowardSys (pixmaps[i].pPix); + if (!exaPixmapIsDirty (pixmaps[i].pPix)) + exaMoveOutPixmap (pixmaps[i].pPix); + } + return; + } + + /* Finally, the acceleration path. Move them all in. */ + for (i = 0; i < npixmaps; i++) { + exaMigrateTowardFb(pixmaps[i].pPix); + exaMoveInPixmap(pixmaps[i].pPix); + } + } else if (pExaScr->migration == ExaMigrationGreedy) { /* If we can't accelerate, either because the driver can't or because one of * the pixmaps is pinned in system memory, then we migrate everybody toward * system memory. diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 18550eec0..89f8b0c9d 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -83,7 +83,8 @@ do { \ */ enum ExaMigrationHeuristic { ExaMigrationGreedy, - ExaMigrationAlways + ExaMigrationAlways, + ExaMigrationSmart }; typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); |