From b17a4de83e7ab18bef29ae898195889638f1cc6a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 18 Apr 2006 19:14:07 +0000 Subject: [PATCH] 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. --- ChangeLog | 17 +++++++++++++ exa/exa.c | 2 +- exa/exa_migration.c | 61 ++++++++++++++++++++++++++++++++++++++++++++- exa/exa_priv.h | 3 ++- 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index fbdd69c88..36147cbeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-04-18 Eric Anholt + + * exa/exa.c: (exaDriverInit): + * exa/exa_migration.c: (exaPixmapIsDirty), (exaPixmapShouldBeInFB), + (exaDoMigration): + * exa/exa_priv.h: + * hw/kdrive/ephyr/ephyr_draw.c: (exaDDXDriverInit): + * hw/xfree86/exa/examodule.c: (exaDDXDriverInit): + 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. + 2006-04-18 Eric Anholt * exa/exa_unaccel.c: (ExaCheckPolyGlyphBlt), diff --git a/exa/exa.c b/exa/exa.c index aa191a863..75d5c0d69 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -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 @@ -57,6 +57,36 @@ exaPixmapIsPinned (PixmapPtr pPix) return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED; } +/** + * 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 @@ -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);