aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/exa
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/exa')
-rw-r--r--xorg-server/exa/exa.c11
-rw-r--r--xorg-server/exa/exa_accel.c6
-rw-r--r--xorg-server/exa/exa_migration_mixed.c33
-rw-r--r--xorg-server/exa/exa_unaccel.c4
4 files changed, 35 insertions, 19 deletions
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c
index 16f39f6f0..023288c12 100644
--- a/xorg-server/exa/exa.c
+++ b/xorg-server/exa/exa.c
@@ -323,17 +323,10 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- if (has_gpu_copy) {
- /* This can be NULL, but the driver prepareAccess call should
- * take care of that. */
+ if (has_gpu_copy && pExaPixmap->fb_ptr)
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- pPixmap->devKind = pExaPixmap->fb_pitch;
- } else {
- /* For mixed pixmaps this can be NULL, but that will be fixed
- * later in exaPrepareAccessReg_mixed(). */
+ else
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- }
/* Store so we can handle repeated / nested calls. */
pExaScr->access[index].pixmap = pPixmap;
diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c
index 1d88acbf0..0f6e5f78a 100644
--- a/xorg-server/exa/exa_accel.c
+++ b/xorg-server/exa/exa_accel.c
@@ -506,11 +506,9 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable,
exaMarkSync (pDstDrawable->pScreen);
/* UTS: mainly for SHM PutImage's secondary path.
*
- * Not taking this path for mixed pixmaps: It could only save one CPU
- * copy between cached memory and risks causing a more expensive
- * DownloadFromScreen later on.
+ * Only taking this path for directly accessible pixmaps.
*/
- } else if (!(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) {
+ } else if (!pDstExaPixmap->pDamage) {
int bpp = pSrcDrawable->bitsPerPixel;
int src_stride = exaGetPixmapPitch(pSrcPixmap);
CARD8 *src = NULL;
diff --git a/xorg-server/exa/exa_migration_mixed.c b/xorg-server/exa/exa_migration_mixed.c
index ee32b215d..b755b83bb 100644
--- a/xorg-server/exa/exa_migration_mixed.c
+++ b/xorg-server/exa/exa_migration_mixed.c
@@ -101,6 +101,15 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
ExaScreenPriv(pPixmap->drawable.pScreen);
+ /* This pitch is needed for proper acceleration. For some reason
+ * there are pixmaps without pDamage and a bad fb_pitch value.
+ * So setting devKind when only exaPixmapHasGpuCopy() is true
+ * causes corruption. Pixmaps without pDamage are not migrated
+ * and should have a valid devKind at all times, so that's why this
+ * isn't causing problems. Pixmaps have their gpu pitch set the
+ * first time in the MPH call from exaCreateDriverPixmap_mixed().
+ */
+ pPixmap->devKind = pExaPixmap->fb_pitch;
exaCopyDirtyToFb(pixmaps + i);
if (pExaScr->deferred_mixed_pixmap == pPixmap)
@@ -108,10 +117,6 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
}
pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- if (pExaPixmap->use_gpu_copy)
- pPixmap->devKind = pExaPixmap->fb_pitch;
- else
- pPixmap->devKind = pExaPixmap->sys_pitch;
}
}
@@ -136,8 +141,9 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
void
exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
{
+ ExaPixmapPriv(pPixmap);
+
if (!ExaDoPrepareAccess(pPixmap, index)) {
- ExaPixmapPriv(pPixmap);
Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
ExaMigrationRec pixmaps[1];
@@ -198,6 +204,22 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
pExaPixmap->use_gpu_copy = FALSE;
+ /* We have a gpu pixmap that can be accessed, we don't need the cpu copy
+ * anymore. Drivers that prefer DFS, should fail prepare access. */
+ } else if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
+ /* Copy back any deferred content if needed. */
+ if (pExaScr->deferred_mixed_pixmap &&
+ pExaScr->deferred_mixed_pixmap == pPixmap)
+ exaMoveInPixmap_mixed(pPixmap);
+
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+
+ free(pExaPixmap->sys_ptr);
+ pExaPixmap->sys_ptr = NULL;
}
}
@@ -222,6 +244,7 @@ void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
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/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c
index 9bc765a53..eee14da4a 100644
--- a/xorg-server/exa/exa_unaccel.c
+++ b/xorg-server/exa/exa_unaccel.c
@@ -414,7 +414,9 @@ ExaCheckComposite (CARD8 op,
PixmapPtr pDstPix;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst + pDst->pDrawable->x,
+ yDst + pDst->pDrawable->y,
width, height))
goto skip;