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.
This commit is contained in:
parent
771b366abe
commit
b17a4de83e
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
||||||
|
2006-04-18 Eric Anholt <anholt@FreeBSD.org>
|
||||||
|
|
||||||
|
* 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 <anholt@FreeBSD.org>
|
2006-04-18 Eric Anholt <anholt@FreeBSD.org>
|
||||||
|
|
||||||
* exa/exa_unaccel.c: (ExaCheckPolyGlyphBlt),
|
* exa/exa_unaccel.c: (ExaCheckPolyGlyphBlt),
|
||||||
|
|
|
@ -557,7 +557,7 @@ exaDriverInit (ScreenPtr pScreen,
|
||||||
|
|
||||||
pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
|
pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
|
||||||
|
|
||||||
pExaScr->migration = ExaMigrationGreedy;
|
pExaScr->migration = ExaMigrationSmart;
|
||||||
|
|
||||||
exaDDXDriverInit(pScreen);
|
exaDDXDriverInit(pScreen);
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,36 @@ exaPixmapIsPinned (PixmapPtr pPix)
|
||||||
return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
|
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
|
* 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
|
* 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
|
/* 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
|
* the pixmaps is pinned in system memory, then we migrate everybody toward
|
||||||
* system memory.
|
* system memory.
|
||||||
|
|
|
@ -83,7 +83,8 @@ do { \
|
||||||
*/
|
*/
|
||||||
enum ExaMigrationHeuristic {
|
enum ExaMigrationHeuristic {
|
||||||
ExaMigrationGreedy,
|
ExaMigrationGreedy,
|
||||||
ExaMigrationAlways
|
ExaMigrationAlways,
|
||||||
|
ExaMigrationSmart
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
|
typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
|
||||||
|
|
Loading…
Reference in New Issue