[PATCH 3/3] exa: Use damage to optimise away useless copies.
Maarten Maathuis
madman2003 at gmail.com
Sun Aug 2 07:47:50 PDT 2009
- This is most useful for cases where the first operation is a hardware rendered one.
---
exa/exa_migration_mixed.c | 50 ++++++++++++++++++++++++++++++++++++++------
exa/exa_mixed.c | 27 +++++++++++++++++++++++-
2 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index bed7141..88077a3 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -35,12 +35,28 @@ static void
exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch,
CARD8 *dst, int dst_pitch)
{
- int i;
+ ExaPixmapPriv(pPixmap);
+ RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
+ int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
+ int bytes, nbox;
+ BoxPtr pbox;
+
+ pbox = REGION_RECTS(damage);
+ nbox = REGION_NUM_RECTS(damage);
+
+ while (nbox--) {
+ bytes = (pbox->x2 - pbox->x1) * cpp;
+
+ src += pbox->y1 * src_pitch + pbox->x1 * cpp;
+ dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
+
+ for (i = pbox->y2 - pbox->y1; i; i--) {
+ memcpy (dst, src, bytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
- for (i = pPixmap->drawable.height; i; i--) {
- memcpy (dst, src, min(src_pitch, dst_pitch));
- src += src_pitch;
- dst += dst_pitch;
+ pbox++;
}
}
@@ -50,12 +66,15 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv(pScreen);
ExaPixmapPriv(pPixmap);
+ RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
void *sys_buffer = pExaPixmap->sys_ptr;
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel;
int usage_hint = pPixmap->usage_hint;
int sys_pitch = pExaPixmap->sys_pitch;
int paddedWidth = sys_pitch;
+ int nbox;
+ BoxPtr pbox;
/* Already done. */
if (pExaPixmap->driverPriv)
@@ -91,8 +110,18 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
if (!pExaScr->info->UploadToScreen)
goto fallback;
- if (pExaScr->info->UploadToScreen(pPixmap, 0, 0, w, h, sys_buffer, sys_pitch))
- goto finish;
+ pbox = REGION_RECTS(damage);
+ nbox = REGION_NUM_RECTS(damage);
+
+ while (nbox--) {
+ if (!pExaScr->info->UploadToScreen(pPixmap, pbox->x1, pbox->y1, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1, (char *) (sys_buffer) + pbox->y1 * sys_pitch + pbox->x1 * (bpp / 8), sys_pitch))
+ goto fallback;
+
+ pbox++;
+ }
+
+ goto finish;
fallback:
ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
@@ -105,6 +134,13 @@ finish:
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
+
+ /* We no longer need this. */
+ if (pExaPixmap->pDamage) {
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+ }
}
void
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 80af521..9090078 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -108,6 +108,23 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
/* We want to be able to copy the pixmap to driver memory later on. */
pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
+
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate (NULL, NULL,
+ DamageReportNone, TRUE,
+ pScreen, pPixmap);
+
+ if (pExaPixmap->pDamage == NULL) {
+ swap(pExaScr, pScreen, DestroyPixmap);
+ pScreen->DestroyPixmap (pPixmap);
+ swap(pExaScr, pScreen, DestroyPixmap);
+ return NULL;
+ }
+
+ DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
+ /* This ensures that pending damage reflects the current operation. */
+ /* This is used by exa to optimize migration. */
+ DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
}
return pPixmap;
@@ -130,8 +147,16 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
if (pExaPixmap) {
if (pPixData) {
- if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap))
+ if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap)) {
free(pExaPixmap->sys_ptr);
+
+ /* We no longer need this. */
+ if (pExaPixmap->pDamage) {
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+ }
+ }
pExaPixmap->sys_ptr = pPixData;
}
--
1.6.4
More information about the xorg-devel
mailing list