summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-09-26 02:04:48 +0200
committerMichel Dänzer <daenzer@vmware.com>2009-09-26 02:04:48 +0200
commit0369eeeb6bf8a808fa2df503fc8b8df81e6e07b8 (patch)
treeae4cce47678bbe8ebce5a043f99eff18abb866a8
parent1818cbd70fc1f2e1487b4c678e67e28f1265c0ef (diff)
EXA: Try to minimize UploadToScreen calls for mixed pixmaps.
If there are several software fallbacks affecting the system memory copy of the same pixmap, only copy the results back to the driver pixmap when it's used for acceleration again, or in the BlockHandler, whichever happens first.
-rw-r--r--exa/exa.c14
-rw-r--r--exa/exa_migration_mixed.c20
-rw-r--r--exa/exa_mixed.c3
-rw-r--r--exa/exa_priv.h1
4 files changed, 35 insertions, 3 deletions
diff --git a/exa/exa.c b/exa/exa.c
index e264d440c..46e91820b 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -774,10 +774,18 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
ScreenPtr pScreen = screenInfo.screens[screenNum];
ExaScreenPriv(pScreen);
+ /* Move any deferred results from a software fallback to the driver pixmap */
+ if (pExaScr->deferred_mixed_pixmap)
+ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+
unwrap(pExaScr, pScreen, BlockHandler);
(*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
+ /* The rest only applies to classic EXA */
+ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
+ return;
+
/* Try and keep the offscreen memory area tidy every now and then (at most
* once per second) when the server has been idle for at least 100ms.
*/
@@ -991,10 +999,12 @@ exaDriverInit (ScreenPtr pScreen,
* Replace various fb screen functions
*/
if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
+ (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) ||
+ (pExaScr->info->flags & EXA_MIXED_PIXMAPS)))
wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
+ if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
+ !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
- }
wrap(pExaScr, pScreen, CreateGC, exaCreateGC);
wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
wrap(pExaScr, pScreen, GetImage, exaGetImage);
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index f42c9c233..6065d7577 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -99,8 +99,13 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
exaCreateDriverPixmap_mixed(pPixmap);
if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
pPixmap->devKind = pExaPixmap->fb_pitch;
exaCopyDirtyToFb(pixmaps + i);
+
+ if (pExaScr->deferred_mixed_pixmap == pPixmap)
+ pExaScr->deferred_mixed_pixmap = NULL;
}
pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
@@ -197,6 +202,9 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
/* Move back results of software rendering on system memory copy of mixed driver
* pixmap (see exaPrepareAccessReg_mixed).
+ *
+ * Defer moving the destination back into the driver pixmap, to try and save
+ * overhead on multiple consequent software fallbacks.
*/
void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
{
@@ -204,6 +212,16 @@ void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
DamageRegionProcessPending(&pPixmap->drawable);
- exaMoveInPixmap_mixed(pPixmap);
+
+ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
+ if (pExaScr->deferred_mixed_pixmap &&
+ pExaScr->deferred_mixed_pixmap != pPixmap)
+ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+ pExaScr->deferred_mixed_pixmap = pPixmap;
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ } else
+ exaMoveInPixmap_mixed(pPixmap);
}
}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 167ffa9d5..bc393c772 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -192,6 +192,9 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
+ if (pExaScr->deferred_mixed_pixmap == pPixmap)
+ pExaScr->deferred_mixed_pixmap = NULL;
+
if (pExaPixmap->driverPriv)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
pExaPixmap->driverPriv = NULL;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 1aec8e966..5b056dab9 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -188,6 +188,7 @@ typedef struct {
unsigned numOffscreenAvailable;
CARD32 lastDefragment;
CARD32 nextDefragment;
+ PixmapPtr deferred_mixed_pixmap;
/* Reference counting for accessed pixmaps */
struct {