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 */ diff --git a/randr/randrstr.h b/randr/randrstr.h index 99022c313..505821269 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -549,6 +549,9 @@ Bool RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations); +void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); + /* * Destroy a Crtc at shutdown */ diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index cfd4da9f7..c84ec6178 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -397,6 +397,32 @@ RRCrtcGammaNotify (RRCrtcPtr crtc) return TRUE; /* not much going on here */ } +/** + * Returns the width/height that the crtc scans out from the framebuffer + */ +void +RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) +{ + if (crtc->mode == NULL) { + *width = 0; + *height = 0; + return; + } + + switch (crtc->rotation & 0xf) { + case RR_Rotate_0: + case RR_Rotate_180: + *width = crtc->mode->mode.width; + *height = crtc->mode->mode.height; + break; + case RR_Rotate_90: + case RR_Rotate_270: + *width = crtc->mode->mode.height; + *height = crtc->mode->mode.width; + break; + } +} + /* * Set the size of the gamma table at server startup time */ @@ -434,6 +460,7 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) { crtc->rotations = rotations; + return TRUE; } /* diff --git a/randr/rrpointer.c b/randr/rrpointer.c index 2a5ae7d2f..802dcb2c4 100644 --- a/randr/rrpointer.c +++ b/randr/rrpointer.c @@ -22,32 +22,6 @@ #include "randrstr.h" -/** - * Returns the width/height that the crtc scans out from the framebuffer - */ -static void -RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) -{ - if (crtc->mode == NULL) { - *width = 0; - *height = 0; - return; - } - - switch (crtc->rotation & 0xf) { - case RR_Rotate_0: - case RR_Rotate_180: - *width = crtc->mode->mode.width; - *height = crtc->mode->mode.height; - break; - case RR_Rotate_90: - case RR_Rotate_270: - *width = crtc->mode->mode.height; - *height = crtc->mode->mode.width; - break; - } -} - /* * When the pointer moves, check to see if the specified position is outside * any of theavailable CRTCs and move it to a 'sensible' place if so, where diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index 8b951455c..1db27f14c 100644 --- a/randr/rrxinerama.c +++ b/randr/rrxinerama.c @@ -290,10 +290,12 @@ ProcRRXineramaQueryScreens(ClientPtr client) RRCrtcPtr crtc = pScrPriv->crtcs[i]; if (RRXineramaCrtcActive (crtc)) { + int width, height; + RRCrtcGetScanoutSize (crtc, &width, &height); scratch.x_org = crtc->x; scratch.y_org = crtc->y; - scratch.width = crtc->mode->mode.width; - scratch.height = crtc->mode->mode.height; + scratch.width = width; + scratch.height = height; if(client->swapped) { register int n; swaps(&scratch.x_org, n);