- A mapped pixmap can't be used for acceleration, any decent memory manager
will refuse this.
- Source pixmaps with preg are incomplete (in the gpu pixmap), so also put them
on the deferred pixmap list.

Signed-off-by: Maarten Maathuis <[email protected]>
---
 exa/exa_migration_mixed.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 6816e6c..93f7332 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -115,6 +115,17 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int 
npixmaps, Bool can_accel)
            if (pExaScr->deferred_mixed_pixmap == pPixmap &&
                !pixmaps[i].as_dst && !pixmaps[i].pReg)
                pExaScr->deferred_mixed_pixmap = NULL;
+
+           /* Sources that are transferred only partially, need to be brought
+            * up-to-date later, otherwise it may end up losing some data
+            * forever if the system ram pixmap is removed.
+            */
+           if (pixmaps[i].as_src && pixmaps[i].pReg) {
+               if (pExaScr->deferred_mixed_pixmap &&
+                       pExaScr->deferred_mixed_pixmap != pPixmap)
+                   exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+               pExaScr->deferred_mixed_pixmap = pPixmap;
+           }
        }
 
        pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
@@ -167,9 +178,12 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, 
RegionPtr pReg)
     ExaPixmapPriv(pPixmap);
 
     if (!ExaDoPrepareAccess(pPixmap, index)) {
-       Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+       Bool has_gpu_copy;
        ExaMigrationRec pixmaps[1];
 
+late_failure:
+       has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+
        /* Do we need to allocate our system buffer? */
        if (!pExaPixmap->sys_ptr) {
            pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
@@ -233,10 +247,21 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, 
RegionPtr pReg)
     } 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)
+           pExaScr->deferred_mixed_pixmap == pPixmap) {
+           /* You cannot do accelerated operations while a buffer is mapped. */
+           exaFinishAccess(&pPixmap->drawable, index);
+           /* Deferred pixmaps include destinations that were used for software
+            * rendering and sources that were migrated with a region (therefore
+            * incomplete from the gpu point of view).
+            */
            exaMoveInPixmap_mixed(pPixmap);
+           /* You cannot assume prepare access will succeed twice,
+            * however likely it may be.
+            */
+           if (!ExaDoPrepareAccess(pPixmap, index))
+               goto late_failure;
+       }
 
        DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
        DamageDestroy(pExaPixmap->pDamage);
-- 
1.6.6.1

_______________________________________________
xorg-devel mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to