summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-03-15 01:20:08 +0000
committerEric Anholt <anholt@freebsd.org>2006-03-15 01:20:08 +0000
commitc1601717d536419693b3ef6e8a3d69b9f2fdc2b3 (patch)
tree2d989707731d8e3b6aa7f8be234296dca6e320e4
parenta90cff266cc81993ed804fb320c1dbfe5e0d4787 (diff)
Add a new migration scheme, "always", which will move pixmaps to their
desired location always (unless they don't fit in FB, in which case they all get moved out for software rendering). The default remains as before, but can be controlled by the MigrationHeuristic xorg.conf option (which is intentionally not documented, as it may be short-lived). This is part of the exa-damagetrack work, which appears stable in testing with fakexa, unlike the work as a whole.
-rw-r--r--ChangeLog15
-rw-r--r--exa/exa.c2
-rw-r--r--exa/exa_migration.c93
-rw-r--r--exa/exa_priv.h10
-rw-r--r--hw/xfree86/exa/examodule.c43
5 files changed, 131 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 89c7720ca..5a54f678f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2006-03-14 Eric Anholt <anholt@FreeBSD.org>
+ * exa/exa.c: (exaDriverInit):
+ * exa/exa_migration.c: (exaDoMigration):
+ * exa/exa_priv.h:
+ * hw/xfree86/exa/examodule.c: (exaXorgCloseScreen),
+ (exaDDXDriverInit):
+ Add a new migration scheme, "always", which will move pixmaps to their
+ desired location always (unless they don't fit in FB, in which case they
+ all get moved out for software rendering). The default remains as
+ before, but can be controlled by the MigrationHeuristic xorg.conf option
+ (which is intentionally not documented, as it may be short-lived). This
+ is part of the exa-damagetrack work, which appears stable in testing
+ with fakexa, unlike the work as a whole.
+
+2006-03-14 Eric Anholt <anholt@FreeBSD.org>
+
* exa/exa.c:
* exa/exa.h:
Add more doxygen documentation, including notes on WaitMarker() and
diff --git a/exa/exa.c b/exa/exa.c
index db76b8038..548f76ad9 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -456,6 +456,8 @@ exaDriverInit (ScreenPtr pScreen,
pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
+ pExaScr->migration = ExaMigrationGreedy;
+
exaDDXDriverInit(pScreen);
/*
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index d48abf066..ce4ce7455 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -247,6 +247,10 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
}
}
+/**
+ * For the "greedy" migration scheme, pushes the pixmap toward being located in
+ * framebuffer memory.
+ */
static void
exaMigrateTowardFb (PixmapPtr pPixmap)
{
@@ -285,6 +289,10 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
ExaOffscreenMarkUsed (pPixmap);
}
+/**
+ * For the "greedy" migration scheme, pushes the pixmap toward being located in
+ * system memory.
+ */
static void
exaMigrateTowardSys (PixmapPtr pPixmap)
{
@@ -314,13 +322,14 @@ exaMigrateTowardSys (PixmapPtr pPixmap)
/**
* Performs migration of the pixmaps according to the operation information
- * provided in pixmaps and can_accel. In the future, other migration schemes
- * may be added, which is facilitated by having this logic all in one place.
+ * provided in pixmaps and can_accel and the migration scheme chosen in the
+ * config file.
*/
void
exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
{
ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
+ ExaScreenPriv(pScreen);
int i, j;
/* If anything is pinned in system memory, we won't be able to
@@ -338,33 +347,63 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
}
}
- /* 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.
- *
- * We also migrate toward system if all pixmaps involved are currently in
- * system memory -- this can mitigate thrashing when there are significantly
- * more pixmaps active than would fit in memory.
- *
- * If not, then we migrate toward FB so that hopefully acceleration can
- * happen.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys (pixmaps[i].pPix);
- return;
- }
+ 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.
+ *
+ * We also migrate toward system if all pixmaps involved are currently in
+ * system memory -- this can mitigate thrashing when there are significantly
+ * more pixmaps active than would fit in memory.
+ *
+ * If not, then we migrate toward FB so that hopefully acceleration can
+ * happen.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys (pixmaps[i].pPix);
+ return;
+ }
- for (i = 0; i < npixmaps; i++) {
- if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
- /* Found one in FB, so move all to FB. */
- for (j = 0; j < npixmaps; j++)
- exaMigrateTowardFb(pixmaps[j].pPix);
+ for (i = 0; i < npixmaps; i++) {
+ if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
+ /* Found one in FB, so move all to FB. */
+ for (j = 0; j < npixmaps; j++)
+ exaMigrateTowardFb(pixmaps[j].pPix);
+ return;
+ }
+ }
+
+ /* Nobody's in FB, so move all away from FB. */
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys(pixmaps[i].pPix);
+ } else if (pExaScr->migration == ExaMigrationAlways) {
+ /* Always move the pixmaps out if we can't accelerate. If we can
+ * accelerate, try to move them all in. If that fails, then move them
+ * back out.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaMoveOutPixmap(pixmaps[i].pPix);
return;
}
- }
- /* Nobody's in FB, so move all away from FB. */
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys(pixmaps[i].pPix);
+ /* Now, try to move them all into FB */
+ for (i = 0; i < npixmaps; i++) {
+ exaMoveInPixmap(pixmaps[i].pPix);
+ ExaOffscreenMarkUsed (pixmaps[i].pPix);
+ }
+
+ /* If we couldn't fit everything in, then kick back out */
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) {
+ EXA_FALLBACK(("Pixmap %p (%dx%d) not in fb\n", pixmaps[i].pPix,
+ pixmaps[i].pPix->drawable.width,
+ pixmaps[i].pPix->drawable.height));
+ for (j = 0; j < npixmaps; j++)
+ exaMoveOutPixmap(pixmaps[j].pPix);
+ break;
+ }
+ }
+ }
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 036433266..f199cab88 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -77,6 +77,15 @@ do { \
#define EXA_MAX_FB FB_OVERLAY_MAX
#endif
+/**
+ * This is the list of migration heuristics supported by EXA. See
+ * exaDoMigration() for what their implementations do.
+ */
+enum ExaMigrationHeuristic {
+ ExaMigrationGreedy,
+ ExaMigrationAlways
+};
+
typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
typedef struct {
ExaDriverPtr info;
@@ -94,6 +103,7 @@ typedef struct {
GlyphsProcPtr SavedGlyphs;
#endif
Bool swappedOut;
+ enum ExaMigrationHeuristic migration;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c
index 8b48444f1..627bfd567 100644
--- a/hw/xfree86/exa/examodule.c
+++ b/hw/xfree86/exa/examodule.c
@@ -29,6 +29,8 @@
#include <xorg-config.h>
#endif
+#include <string.h>
+
#include "exa_priv.h"
#include "xf86str.h"
@@ -37,11 +39,21 @@
typedef struct _ExaXorgScreenPrivRec {
CloseScreenProcPtr SavedCloseScreen;
EnableDisableFBAccessProcPtr SavedEnableDisableFBAccess;
+ OptionInfoPtr options;
} ExaXorgScreenPrivRec, *ExaXorgScreenPrivPtr;
static int exaXorgServerGeneration;
static int exaXorgScreenPrivateIndex;
+typedef enum {
+ EXAOPT_MIGRATION_HEURISTIC,
+} EXAOpts;
+
+static const OptionInfoRec EXAOptions[] = {
+ { EXAOPT_MIGRATION_HEURISTIC, "MigrationHeuristic", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
static Bool
exaXorgCloseScreen (int i, ScreenPtr pScreen)
{
@@ -53,6 +65,7 @@ exaXorgCloseScreen (int i, ScreenPtr pScreen)
pScrn->EnableDisableFBAccess = pScreenPriv->SavedEnableDisableFBAccess;
+ xfree (pScreenPriv->options);
xfree (pScreenPriv);
return pScreen->CloseScreen (i, pScreen);
@@ -82,6 +95,7 @@ exaXorgEnableDisableFBAccess (int index, Bool enable)
void
exaDDXDriverInit(ScreenPtr pScreen)
{
+ ExaScreenPriv(pScreen);
/* Do NOT use XF86SCRNINFO macro here!! */
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
ExaXorgScreenPrivPtr pScreenPriv;
@@ -95,6 +109,30 @@ exaDDXDriverInit(ScreenPtr pScreen)
if (pScreenPriv == NULL)
return;
+ pScreenPriv->options = xnfalloc (sizeof(EXAOptions));
+ memcpy(pScreenPriv->options, EXAOptions, sizeof(EXAOptions));
+ xf86ProcessOptions (pScrn->scrnIndex, pScrn->options, pScreenPriv->options);
+
+ if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
+ pExaScr->info->offScreenBase < pExaScr->info->memorySize)
+ {
+ char *heuristicName;
+
+ heuristicName = xf86GetOptValString (pScreenPriv->options,
+ EXAOPT_MIGRATION_HEURISTIC);
+ if (heuristicName != NULL) {
+ if (strcmp(heuristicName, "greedy") == 0)
+ pExaScr->migration = ExaMigrationGreedy;
+ else if (strcmp(heuristicName, "always") == 0)
+ pExaScr->migration = ExaMigrationAlways;
+ else {
+ xf86DrvMsg (pScreen->myNum, X_WARNING,
+ "EXA: unknown migration heuristic %s\n",
+ heuristicName);
+ }
+ }
+ }
+
pScreen->devPrivates[exaXorgScreenPrivateIndex].ptr = pScreenPriv;
pScreenPriv->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
@@ -107,11 +145,6 @@ exaDDXDriverInit(ScreenPtr pScreen)
static MODULESETUPPROTO(exaSetup);
-static const OptionInfoRec EXAOptions[] = {
- { -1, NULL,
- OPTV_NONE, {0}, FALSE }
-};
-
/*ARGSUSED*/
static const OptionInfoRec *
EXAAvailableOptions(void *unused)