[PATCH] exa/mixed: avoid unnecessary dest system buffer copy in prepare_access_reg
Karl Tomlinson
karlt+ at karlt.net
Thu Aug 26 03:29:35 PDT 2010
A region is only provided to prepare_access_reg for destination pixmaps when
the operator will not read from the destination. A non-NULL region therefore
indicates that no pixels in the destination gpu buffer need to be copied to
the system buffer.
The provided region still serves a purpose, as it indicates the portion of
the system buffer that will be damaged.
---
exa/exa_migration_mixed.c | 42 ++++++++++++++++++++++++++++--------------
1 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index fb47151..605235e 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -196,6 +196,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
}
if (!success) {
+ BoxRec box;
+ RegionRec region_all;
ExaMigrationRec pixmaps[1];
/* Do we need to allocate our system buffer? */
@@ -207,15 +209,27 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
pExaPixmap->sys_pitch * pPixmap->drawable.height);
}
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPixmap->drawable.width;
+ box.y2 = pPixmap->drawable.height;
+ RegionInit(®ion_all, &box, 1);
+
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = pReg;
if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ /* A pReg for a destination indicates that the operator will not
+ * read from the destination, and so there is no need to copy any
+ * pixels. The valid regions will still be updated.
+ */
+ if (pReg)
+ pixmaps[0].pReg = ®ion_all;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
} else {
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
}
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = pReg;
if (!pExaPixmap->pDamage &&
(has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
@@ -232,27 +246,27 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
/* This is used by exa to optimize migration. */
DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
- if (has_gpu_copy) {
+ if (has_gpu_copy)
exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
pPixmap->drawable.height);
- /* We don't know which region of the destination will be damaged,
- * have to assume all of it
- */
- if (as_dst) {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pReg = NULL;
- }
+ /* When we don't know which region of the destination will be
+ * damaged, have to assume all of it
+ */
+ if (as_dst)
+ DamageRegionAppend(&pPixmap->drawable,
+ pReg ? pReg : ®ion_all);
+
+ if (has_gpu_copy)
exaCopyDirtyToSys(pixmaps);
- }
if (as_dst)
- exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
- pPixmap->drawable.height);
+ DamageRegionProcessPending(&pPixmap->drawable);
} else if (has_gpu_copy)
exaCopyDirtyToSys(pixmaps);
+ RegionUninit(®ion_all);
+
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
pExaPixmap->use_gpu_copy = FALSE;
--
1.7.1
--=-=-=--
More information about the xorg-devel
mailing list