summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-09-26 01:59:39 +0200
committerMichel Dänzer <daenzer@vmware.com>2009-09-26 01:59:39 +0200
commit1818cbd70fc1f2e1487b4c678e67e28f1265c0ef (patch)
treec19cc48b73ed6885079f48a321aa775068fae57e
parente23bffc41b007f1bc2b8f5cd4ac54213062c95cc (diff)
EXA: Extend mixed pixmaps scheme to allow driver PrepareAccess hook to fail.
If the PrepareAccess hook fails, use the DownloadFromScreen hook to retrieve driver pixmap contents to a system RAM copy, perform software rendering on that and copy the results back using the UploadToScreen hook. Use the classic migration logic to minimize transfers (which as a bonus allows slightly cleaning up some of the existing mixed pixmap code). This enables things that weren't possible before with driver-allocated pixmap storage: If some (or all) GPU pixmap storage can't be mapped directly by the CPU, this can be handled between the PrepareAccess and DownloadFrom/UploadToScreen hooks, e.g.: * Radeon KMS on big endian machines can fail PrepareAccess if the pixmap requires byte-swapping and swap bytes in DownloadFrom/UploadToScreen. * Environments where GPU and CPU don't have a shared address space at all. Here the driver PrepareAccess hook will always fail and leave all transfers between GPU / CPU storage to the Download/From/UploadToScreen hooks. Drivers which can handle all pixmaps in the PrepareAccess hook should notice little if any difference.
-rw-r--r--exa/exa.c78
-rw-r--r--exa/exa_migration_classic.c30
-rw-r--r--exa/exa_migration_mixed.c179
-rw-r--r--exa/exa_mixed.c87
-rw-r--r--exa/exa_priv.h22
-rw-r--r--exa/exa_unaccel.c52
6 files changed, 232 insertions, 216 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 483e3b4eb..e264d440c 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -288,7 +288,6 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
Bool
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
{
- ScreenPtr pScreen = pDrawable->pScreen;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
ExaPixmapPriv(pPixmap);
@@ -326,3 +325,3 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
- if (offscreen)
+ if (offscreen && pExaPixmap->fb_ptr)
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
@@ -335,16 +334,6 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
- if (!offscreen) {
- /* Do we need to allocate our system buffer? */
- if ((pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && (pExaScr->info->flags & EXA_MIXED_PIXMAPS)) {
- if (!pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap)) {
- pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch * pDrawable->height);
- if (!pExaPixmap->sys_ptr)
- FatalError("EXA: malloc failed for size %d bytes\n", pExaPixmap->sys_pitch * pDrawable->height);
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- }
- }
+ if (!offscreen)
return FALSE;
- }
- exaWaitSync (pDrawable->pScreen);
+ exaWaitSync (pScreen);
@@ -362,3 +351,4 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED &&
+ !(pExaScr->info->flags & EXA_MIXED_PIXMAPS))
FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
@@ -372,27 +362,2 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
-void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
-{
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- 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;
-
- exaDoMigration(pixmaps, 1, FALSE);
- }
-
- ExaDoPrepareAccess(pDrawable, index);
-}
-
/**
@@ -406,3 +371,9 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
{
- exaPrepareAccessReg(pDrawable, index, NULL);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaScreenPriv(pDrawable->pScreen);
+
+ if (pExaScr->prepare_access_reg)
+ pExaScr->prepare_access_reg(pPixmap, index, NULL);
+ else
+ (void)ExaDoPrepareAccess(pPixmap, index);
}
@@ -434,3 +405,2 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
return;
- index = i;
break;
@@ -444,3 +414,3 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
- pExaScr->access[index].pixmap = NULL;
+ pExaScr->access[i].pixmap = NULL;
@@ -449,9 +419,9 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
- if (pExaScr->info->FinishAccess == NULL)
- return;
+ if (pExaScr->finish_access)
+ pExaScr->finish_access(pPixmap, index);
- if (!exaPixmapIsOffscreen (pPixmap))
+ if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap))
return;
- if (index >= EXA_PREPARE_AUX_DEST &&
+ if (i >= EXA_PREPARE_AUX_DEST &&
!(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
@@ -462,3 +432,3 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
- (*pExaScr->info->FinishAccess) (pPixmap, index);
+ (*pExaScr->info->FinishAccess) (pPixmap, i);
}
@@ -539,3 +509,3 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
*/
- ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+ ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST);
@@ -1073,2 +1043,4 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_out_pixmap = NULL;
+ pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
+ pExaScr->finish_access = exaFinishAccess_mixed;
} else {
@@ -1081,2 +1053,4 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_out_pixmap = NULL;
+ pExaScr->prepare_access_reg = NULL;
+ pExaScr->finish_access = NULL;
}
@@ -1090,2 +1064,4 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
+ pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
+ pExaScr->finish_access = NULL;
}
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index d8e1e86da..0032f02f9 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -122,3 +122,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
/* Damaged bits are valid in current copy but invalid in other one */
- if (exaPixmapIsOffscreen(pPixmap)) {
+ if (pExaPixmap->offscreen) {
REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
@@ -227,3 +227,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
if (!access_prepared) {
- ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
+ ExaDoPrepareAccess(pPixmap, fallback_index);
access_prepared = TRUE;
@@ -265,3 +265,3 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
*/
-static void
+void
exaCopyDirtyToSys (ExaMigrationPtr migrate)
@@ -283,3 +283,3 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
*/
-static void
+void
exaCopyDirtyToFb (ExaMigrationPtr migrate)
@@ -547,3 +547,3 @@ exaAssertNotDirty (PixmapPtr pPixmap)
- if (!ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC))
+ if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
goto skip;
@@ -720 +720,21 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
}
+
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg)
+{
+ ExaMigrationRec pixmaps[1];
+
+ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ 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;
+
+ exaDoMigration(pixmaps, 1, FALSE);
+
+ (void)ExaDoPrepareAccess(pPixmap, index);
+}
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index d1ee9871b..f42c9c233 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -33,36 +33,2 @@
-static void
-exaUploadFallback(PixmapPtr pPixmap, CARD8 *src, int src_pitch)
-{
- ExaPixmapPriv(pPixmap);
- RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
- GCPtr pGC = GetScratchGC (pPixmap->drawable.depth,
- pPixmap->drawable.pScreen);
- int nbox, cpp = pPixmap->drawable.bitsPerPixel / 8;
- DamagePtr backup = pExaPixmap->pDamage;
- BoxPtr pbox;
- CARD8 *src2;
-
- /* We don't want damage optimisations. */
- pExaPixmap->pDamage = NULL;
- ValidateGC (&pPixmap->drawable, pGC);
-
- pbox = REGION_RECTS(damage);
- nbox = REGION_NUM_RECTS(damage);
-
- while (nbox--) {
- src2 = src + pbox->y1 * src_pitch + pbox->x1 * cpp;
-
- ExaCheckPutImage(&pPixmap->drawable, pGC,
- pPixmap->drawable.depth, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 0,
- ZPixmap, (char*) src2);
-
- pbox++;
- }
-
- FreeScratchGC (pGC);
- pExaPixmap->pDamage = backup;
-}
-
void
@@ -73,4 +39,2 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
ExaPixmapPriv(pPixmap);
- RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
- void *sys_buffer = pExaPixmap->sys_ptr;
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
@@ -78,6 +42,3 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
int usage_hint = pPixmap->usage_hint;
- int sys_pitch = pExaPixmap->sys_pitch;
- int paddedWidth = sys_pitch;
- int nbox;
- BoxPtr pbox;
+ int paddedWidth = pExaPixmap->sys_pitch;
@@ -107,46 +68,4 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
- pExaPixmap->offscreen = TRUE;
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->sys_pitch = pPixmap->devKind = 0;
-
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
(*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
paddedWidth, NULL);
-
- /* scratch pixmaps */
- if (!w || !h)
- goto finish;
-
- /* we do not malloc memory by default. */
- if (!sys_buffer)
- goto finish;
-
- if (!pExaScr->info->UploadToScreen)
- goto fallback;
-
- 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:
- exaUploadFallback(pPixmap, sys_buffer, sys_pitch);
-
-finish:
- free(sys_buffer);
-
- /* We no longer need this. */
- if (pExaPixmap->pDamage) {
- DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- }
}
@@ -177,4 +96,12 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
ExaPixmapPriv(pPixmap);
+
if (!pExaPixmap->driverPriv)
exaCreateDriverPixmap_mixed(pPixmap);
+
+ if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ exaCopyDirtyToFb(pixmaps + i);
+ }
+
+ pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
}
@@ -194 +121,89 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
}
+
+/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
+ * use the DownloadFromScreen hook to retrieve contents to a copy in system
+ * memory, perform software rendering on that and move back the results with the
+ * UploadToScreen hook (see exaFinishAccess_mixed).
+ */
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
+{
+ if (!ExaDoPrepareAccess(pPixmap, index)) {
+ ExaPixmapPriv(pPixmap);
+ Bool is_offscreen = exaPixmapIsOffscreen(pPixmap);
+ ExaMigrationRec pixmaps[1];
+
+ /* Do we need to allocate our system buffer? */
+ if (!pExaPixmap->sys_ptr) {
+ pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
+ pPixmap->drawable.height);
+ if (!pExaPixmap->sys_ptr)
+ FatalError("EXA: malloc failed for size %d bytes\n",
+ pExaPixmap->sys_pitch * pPixmap->drawable.height);
+ }
+
+ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ 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 && (is_offscreen || !exaPixmapIsPinned(pPixmap))) {
+ Bool as_dst = pixmaps[0].as_dst;
+
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+ TRUE, pPixmap->drawable.pScreen,
+ pPixmap);
+
+ 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);
+
+ if (is_offscreen) {
+ 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;
+ }
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ exaCopyDirtyToSys(pixmaps);
+ }
+
+ if (as_dst)
+ exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
+ pPixmap->drawable.height);
+ } else if (is_offscreen) {
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ exaCopyDirtyToSys(pixmaps);
+ }
+
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
+ pExaPixmap->offscreen = FALSE;
+ }
+}
+
+/* Move back results of software rendering on system memory copy of mixed driver
+ * pixmap (see exaPrepareAccessReg_mixed).
+ */
+void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
+{
+ ExaPixmapPriv(pPixmap);
+
+ if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) {
+ DamageRegionProcessPending(&pPixmap->drawable);
+ exaMoveInPixmap_mixed(pPixmap);
+ }
+}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 6aa73f2b6..167ffa9d5 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -34,4 +34,2 @@
/* This file holds the driver allocated pixmaps + better initial placement code.
- * A pinned pixmap implies one that is either driver based already or otherwise altered.
- * Proper care is taken to free the initially allocated buffer.
*/
@@ -48,5 +46,2 @@ ExaGetPixmapAddress(PixmapPtr p)
* exaCreatePixmap() creates a new pixmap.
- *
- * Pixmaps are always marked as pinned, unless the pixmap can still be transfered to a
- * driver pixmaps.
*/
@@ -87,3 +82,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
pExaPixmap->area = NULL;
- pExaPixmap->offscreen = FALSE;
pExaPixmap->fb_ptr = NULL;
@@ -95,5 +89,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- /* Avoid freeing sys_ptr. */
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
-
(*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
@@ -101,5 +92,2 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- /* We want to be able to transfer the pixmap to driver memory later on. */
- pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
/* A scratch pixmap will become a driver pixmap right away. */
@@ -107,20 +95,5 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
exaCreateDriverPixmap_mixed(pPixmap);
- } else {
- /* 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);
- }
+ pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap);
+ } else
+ pExaPixmap->offscreen = FALSE;
@@ -136,3 +109,3 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
ExaPixmapPrivPtr pExaPixmap;
- Bool ret;
+ Bool ret, is_offscreen;
@@ -144,9 +117,4 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- if (pExaPixmap) {
- if (!exaPixmapIsPinned(pPixmap)) {
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->sys_pitch = pPixmap->devKind = 0;
-
- /* We no longer need this. */
+ if (pPixData) {
+ if (pExaPixmap->driverPriv) {
if (pExaPixmap->pDamage) {
@@ -156,10 +124,12 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
}
- }
- if (pPixData)
- pExaPixmap->sys_ptr = pPixData;
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
+ }
- if (devKind > 0)
- pExaPixmap->sys_pitch = devKind;
+ pExaPixmap->offscreen = FALSE;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ }
+ if (pExaPixmap->driverPriv) {
if (width > 0 && height > 0 && bitsPerPixel > 0) {
@@ -171,5 +141,11 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
}
+ }
- /* Anything can happen, don't try to predict it all. */
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ is_offscreen = exaPixmapIsOffscreen(pPixmap);
+ if (is_offscreen) {
+ pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ } else {
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
}
@@ -184,6 +160,2 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
*/
- if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
- }
if (ret == TRUE)
@@ -198,2 +170,9 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
out:
+ if (is_offscreen) {
+ pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->fb_pitch = pPixmap->devKind;
+ } else {
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
+ }
/* Always NULL this, we don't want lingering pointers. */
@@ -217,6 +196,10 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap)
pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- else if (pExaPixmap->sys_ptr && !exaPixmapIsPinned(pPixmap))
- free(pExaPixmap->sys_ptr);
pExaPixmap->driverPriv = NULL;
- pExaPixmap->sys_ptr = NULL;
+
+ if (pExaPixmap->pDamage) {
+ if (pExaPixmap->sys_ptr)
+ free(pExaPixmap->sys_ptr);
+ pExaPixmap->sys_ptr = NULL;
+ pExaPixmap->pDamage = NULL;
+ }
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 869cf1772..1aec8e966 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -178,2 +178,4 @@ typedef struct {
void (*do_move_out_pixmap) (PixmapPtr pPixmap);
+ void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
+ void (*finish_access)(PixmapPtr pPixmap, int index);
@@ -513,6 +515,3 @@ ExaOffscreenFini (ScreenPtr pScreen);
Bool
-ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
-
-void
-exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
+ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
@@ -611,2 +610,8 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap);
+void
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+void
+exaFinishAccess_mixed(PixmapPtr pPixmap, int index);
+
/* exa_render.c */
@@ -667,2 +672,8 @@ exaGlyphs (CARD8 op,
void
+exaCopyDirtyToSys (ExaMigrationPtr migrate);
+
+void
+exaCopyDirtyToFb (ExaMigrationPtr migrate);
+
+void
exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
@@ -678,2 +689,5 @@ exaMoveInPixmap_classic (PixmapPtr pPixmap);
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
+
#endif /* EXAPRIV_H */
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index f4700adac..c8f017243 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -103,3 +103,5 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
{
- ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
+ ExaScreenPriv(pDrawable->pScreen);
@@ -107,3 +109,4 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
+ exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
pGC->alu, pGC->clientClipType))
@@ -111,4 +114,4 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
else
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
- DamagePendingRegion(pExaPixmap->pDamage) : NULL);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+ DamagePendingRegion(pExaPixmap->pDamage));
pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
@@ -325,5 +328,2 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
{
- BoxRec Box;
- RegionRec Reg;
- int xoff, yoff;
ScreenPtr pScreen = pDrawable->pScreen;
@@ -335,12 +335,20 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+ if (pExaScr->prepare_access_reg) {
+ int xoff, yoff;
+ BoxRec Box;
+ RegionRec Reg;
+
+ exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+ Box.x1 = pDrawable->y + x + xoff;
+ Box.y1 = pDrawable->y + y + yoff;
+ Box.x2 = Box.x1 + w;
+ Box.y2 = Box.y1 + h;
- Box.x1 = pDrawable->y + x + xoff;
- Box.y1 = pDrawable->y + y + yoff;
- Box.x2 = Box.x1 + w;
- Box.y2 = Box.y1 + h;
+ REGION_INIT(pScreen, &Reg, &Box, 1);
- REGION_INIT(pScreen, &Reg, &Box, 1);
+ pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &Reg);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
swap(pExaScr, pScreen, GetImage);
@@ -403,3 +411,5 @@ ExaCheckComposite (CARD8 op,
- if (!exaOpReadsDestination(op)) {
+ if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) {
+ PixmapPtr pDstPix;
+
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
@@ -409,6 +419,4 @@ ExaCheckComposite (CARD8 op,
- exaGetDrawableDeltas (pDst->pDrawable,
- exaGetDrawablePixmap(pDst->pDrawable),
- &xoff, &yoff);
-
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
@@ -416,6 +424,6 @@ ExaCheckComposite (CARD8 op,
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaPrepareAccessReg(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST,
- &region);
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST, &region);
- exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, &region);
+ pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, &region);
} else {