summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2007-01-24 13:34:29 -0800
committerEric Anholt <eric@anholt.net>2007-01-24 13:34:58 -0800
commit7a12952fd437b105ea0d013d680f9c3a775a183c (patch)
treecffd02d6f5f51bad6532509c6038ce117f252ef3 /exa
parentb6b855932109b4bc3454f07bef8cb079d79ca369 (diff)
Bug #7639: Only swap out pixmaps (rather than everything) on VT switch in EXA.
This is a new behavior for version 2.1 of EXA, and only takes effect if the driver has requested that. Otherwise, the previous behavior remains the same.
Diffstat (limited to 'exa')
-rw-r--r--exa/exa.h6
-rw-r--r--exa/exa_migration.c2
-rw-r--r--exa/exa_offscreen.c70
-rw-r--r--exa/exa_priv.h3
4 files changed, 67 insertions, 14 deletions
diff --git a/exa/exa.h b/exa/exa.h
index b043c122c..bf723f723 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -39,7 +39,7 @@
#include "fb.h"
#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 0
+#define EXA_VERSION_MINOR 1
#define EXA_VERSION_RELEASE 0
typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -73,8 +73,8 @@ struct _ExaOffscreenArea {
typedef struct _ExaDriver {
/**
* exa_major and exa_minor should be set by the driver to the version of
- * EXA which the driver was compiled for (or configures itself at runtime to
- * support). This allows EXA to extend the structure for new features
+ * EXA which the driver was compiled for (or configures itself at runtime
+ * to support). This allows EXA to extend the structure for new features
* without breaking ABI for drivers compiled against older versions.
*/
int exa_major, exa_minor;
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index d24a1bf98..eedc5fd03 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -249,7 +249,7 @@ exaCopyDirtyToFb (PixmapPtr pPixmap)
* Called when the memory manager decides it's time to kick the pixmap out of
* framebuffer entirely.
*/
-static void
+void
exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
{
PixmapPtr pPixmap = area->privData;
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index fd3599e8c..7708dd739 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -81,15 +81,14 @@ ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area)
* @param save callback for when the area is evicted from memory
* @param privdata private data for the save callback.
*
- * Allocates offscreen memory from the device associated with pScreen. size and
- * align deteremine where and how large the allocated area is, and locked will
- * mark whether it should be held in card memory. privdata may be any pointer
- * for the save callback when the area is removed.
+ * Allocates offscreen memory from the device associated with pScreen. size
+ * and align deteremine where and how large the allocated area is, and locked
+ * will mark whether it should be held in card memory. privdata may be any
+ * pointer for the save callback when the area is removed.
*
- * Note that locked areas do get evicted on VT switch, because during that time
- * all offscreen memory becomes inaccessible. This may change in the future,
- * but drivers should be aware of this and provide a callback to mark that their
- * locked allocation was evicted, and then restore it if necessary on EnterVT.
+ * Note that locked areas do get evicted on VT switch unless the driver
+ * requested version 2.1 or newer behavior. In that case, the save callback is
+ * still called.
*/
ExaOffscreenArea *
exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
@@ -256,6 +255,9 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
return area;
}
+/**
+ * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
+ */
void
ExaOffscreenSwapOut (ScreenPtr pScreen)
{
@@ -283,12 +285,56 @@ ExaOffscreenSwapOut (ScreenPtr pScreen)
ExaOffscreenFini (pScreen);
}
+/** Ejects all pixmaps managed by EXA. */
+static void
+ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
+{
+ ExaScreenPriv (pScreen);
+
+ ExaOffscreenValidate (pScreen);
+ /* loop until a single free area spans the space */
+ for (;;)
+ {
+ ExaOffscreenArea *area;
+
+ for (area = pExaScr->info->offScreenAreas; area != NULL;
+ area = area->next)
+ {
+ if (area->state == ExaOffscreenRemovable &&
+ area->save == exaPixmapSave)
+ {
+ (void) ExaOffscreenKickOut (pScreen, area);
+ ExaOffscreenValidate (pScreen);
+ break;
+ }
+ }
+ if (area == NULL)
+ break;
+ }
+ ExaOffscreenValidate (pScreen);
+}
+
void
ExaOffscreenSwapIn (ScreenPtr pScreen)
{
exaOffscreenInit (pScreen);
}
+/**
+ * Prepares EXA for disabling of FB access, or restoring it.
+ *
+ * In version 2.1, the disabling results in pixmaps being ejected, while other
+ * allocations remain. With this plus the prevention of migration while
+ * swappedOut is set, EXA by itself should not cause any access of the
+ * framebuffer to occur while swapped out. Any remaining issues are the
+ * responsibility of the driver.
+ *
+ * Prior to version 2.1, all allocations, including locked ones, are ejected
+ * when access is disabled, and the allocator is torn down while swappedOut
+ * is set. This is more drastic, and caused implementation difficulties for
+ * many drivers that could otherwise handle the lack of FB access while
+ * swapped out.
+ */
void
exaEnableDisableFBAccess (int index, Bool enable)
{
@@ -296,10 +342,14 @@ exaEnableDisableFBAccess (int index, Bool enable)
ExaScreenPriv (pScreen);
if (!enable) {
- ExaOffscreenSwapOut (pScreen);
+ if (pExaScr->info->exa_minor < 1)
+ ExaOffscreenSwapOut (pScreen);
+ else
+ ExaOffscreenEjectPixmaps (pScreen);
pExaScr->swappedOut = TRUE;
} else {
- ExaOffscreenSwapIn (pScreen);
+ if (pExaScr->info->exa_minor < 1)
+ ExaOffscreenSwapIn (pScreen);
pExaScr->swappedOut = FALSE;
}
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 403d4b6a4..984cb669b 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -412,4 +412,7 @@ exaGlyphs (CARD8 op,
void
exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+void
+exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area);
+
#endif /* EXAPRIV_H */