diff --git a/ChangeLog b/ChangeLog index 1d2a0fa8a..2d0473920 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-04-25 Eric Anholt + + * exa/exa_migration.c: (exaAssertNotDirty), (exaDoMigration): + * exa/exa_priv.h: + * hw/kdrive/ephyr/ephyr_draw.c: (exaDDXDriverInit): + Add an option to verify at the point of migration that pixmaps which + aren't marked dirty are in fact not dirty. This will hopefully help + catch issues like the previous commit. Leave it on in fakexa. + 2006-04-25 Eric Anholt * exa/exa_accel.c: (exaPutImage): diff --git a/exa/exa_migration.c b/exa/exa_migration.c index ef7cfd86e..8077f6802 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -406,6 +406,36 @@ exaMigrateTowardSys (PixmapPtr pPixmap) exaMoveOutPixmap (pPixmap); } +/** + * If the pixmap has both a framebuffer and system memory copy, this function + * asserts that both of them are the same. + */ +static void +exaAssertNotDirty (PixmapPtr pPixmap) +{ + ExaPixmapPriv (pPixmap); + CARD8 *dst, *src; + int dst_pitch, src_pitch, data_row_bytes, y; + + if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL) + return; + + dst = pExaPixmap->sys_ptr; + dst_pitch = pExaPixmap->sys_pitch; + src = pExaPixmap->fb_ptr; + src_pitch = pExaPixmap->fb_pitch; + data_row_bytes = pPixmap->drawable.width * + pPixmap->drawable.bitsPerPixel / 8; + + exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + for (y = 0; y < pPixmap->drawable.height; y++) { + if (memcmp(dst, src, data_row_bytes) != 0) { + abort(); + } + } + exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); +} + /** * Performs migration of the pixmaps according to the operation information * provided in pixmaps and can_accel and the migration scheme chosen in the @@ -418,6 +448,19 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) ExaScreenPriv(pScreen); int i, j; + /* If this debugging flag is set, check each pixmap for whether it is marked + * as clean, and if so, actually check if that's the case. This should help + * catch issues with failing to mark a drawable as dirty. While it will + * catch them late (after the operation happened), it at least explains what + * went wrong, and instrumenting the code to find what operation happened + * to the pixmap last shouldn't be hard. + */ + if (pExaScr->checkDirtyCorrectness) { + for (i = 0; i < npixmaps; i++) { + if (!exaPixmapIsDirty (pixmaps[i].pPix)) + exaAssertNotDirty (pixmaps[i].pPix); + } + } /* If anything is pinned in system memory, we won't be able to * accelerate. */ diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 89f8b0c9d..42c2f2d26 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -108,6 +108,7 @@ typedef struct { Bool swappedOut; enum ExaMigrationHeuristic migration; Bool hideOffscreenPixmapData; + Bool checkDirtyCorrectness; } ExaScreenPrivRec, *ExaScreenPrivPtr; /* diff --git a/hw/kdrive/ephyr/ephyr_draw.c b/hw/kdrive/ephyr/ephyr_draw.c index 0d095352f..0c1a5d0d3 100644 --- a/hw/kdrive/ephyr/ephyr_draw.c +++ b/hw/kdrive/ephyr/ephyr_draw.c @@ -515,4 +515,5 @@ exaDDXDriverInit(ScreenPtr pScreen) pExaScr->migration = ExaMigrationSmart; pExaScr->hideOffscreenPixmapData = TRUE; + pExaScr->checkDirtyCorrectness = TRUE; }