diff options
Diffstat (limited to 'xorg-server/exa')
-rw-r--r-- | xorg-server/exa/exa.c | 30 | ||||
-rw-r--r-- | xorg-server/exa/exa_mixed.c | 42 | ||||
-rw-r--r-- | xorg-server/exa/exa_priv.h | 1 |
3 files changed, 59 insertions, 14 deletions
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c index 023288c12..b3c5bfffe 100644 --- a/xorg-server/exa/exa.c +++ b/xorg-server/exa/exa.c @@ -283,7 +283,7 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) } /** - * Returns TRUE if pixmap can be accessed offscreen. + * Returns TRUE if the pixmap GPU copy is being accessed. */ Bool ExaDoPrepareAccess(PixmapPtr pPixmap, int index) @@ -291,7 +291,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) ScreenPtr pScreen = pPixmap->drawable.pScreen; ExaScreenPriv (pScreen); ExaPixmapPriv(pPixmap); - Bool has_gpu_copy; + Bool has_gpu_copy, ret; int i; if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) @@ -304,7 +304,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { if (pExaScr->access[i].pixmap == pPixmap) { pExaScr->access[i].count++; - return TRUE; + return pExaScr->access[i].retval; } } @@ -323,29 +323,33 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); - if (has_gpu_copy && pExaPixmap->fb_ptr) + if (has_gpu_copy && pExaPixmap->fb_ptr) { pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; - else + ret = TRUE; + } else { pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; + ret = FALSE; + } /* Store so we can handle repeated / nested calls. */ pExaScr->access[index].pixmap = pPixmap; pExaScr->access[index].count = 1; if (!has_gpu_copy) - return FALSE; + goto out; exaWaitSync (pScreen); if (pExaScr->info->PrepareAccess == NULL) - return TRUE; + goto out; if (index >= EXA_PREPARE_AUX_DEST && !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) FatalError("Unsupported AUX indices used on a pinned pixmap.\n"); exaMoveOutPixmap (pPixmap); - return FALSE; + ret = FALSE; + goto out; } if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { @@ -353,11 +357,15 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) !(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) FatalError("Driver failed PrepareAccess on a pinned pixmap.\n"); exaMoveOutPixmap (pPixmap); - - return FALSE; + ret = FALSE; + goto out; } - return TRUE; + ret = TRUE; + +out: + pExaScr->access[index].retval = ret; + return ret; } /** diff --git a/xorg-server/exa/exa_mixed.c b/xorg-server/exa/exa_mixed.c index 764c7dd58..155ed47c5 100644 --- a/xorg-server/exa/exa_mixed.c +++ b/xorg-server/exa/exa_mixed.c @@ -135,17 +135,53 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; } - if (pExaPixmap->driverPriv) { - if (width > 0 && height > 0 && bitsPerPixel > 0) { + has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); + + if (width <= 0) + width = pPixmap->drawable.width; + + if (height <= 0) + height = pPixmap->drawable.height; + + if (bitsPerPixel <= 0) { + if (depth <= 0) + bitsPerPixel = pPixmap->drawable.bitsPerPixel; + else + bitsPerPixel = BitsPerPixel(depth); + } + + if (depth <= 0) + depth = pPixmap->drawable.depth; + + if (width != pPixmap->drawable.width || + height != pPixmap->drawable.height || + depth != pPixmap->drawable.depth || + bitsPerPixel != pPixmap->drawable.bitsPerPixel) { + if (pExaPixmap->driverPriv) { exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel); exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel); + REGION_EMPTY(pScreen, &pExaPixmap->validFB); } + + /* Need to re-create system copy if there's also a GPU copy */ + if (has_gpu_copy && pExaPixmap->sys_ptr) { + free(pExaPixmap->sys_ptr); + pExaPixmap->sys_ptr = NULL; + pExaPixmap->sys_pitch = devKind > 0 ? devKind : + PixmapBytePad(width, depth); + DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); + DamageDestroy(pExaPixmap->pDamage); + pExaPixmap->pDamage = NULL; + REGION_EMPTY(pScreen, &pExaPixmap->validSys); + + if (pExaScr->deferred_mixed_pixmap == pPixmap) + pExaScr->deferred_mixed_pixmap = NULL; + } } - has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); if (has_gpu_copy) { pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; pPixmap->devKind = pExaPixmap->fb_pitch; diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h index 69c0d241d..085235524 100644 --- a/xorg-server/exa/exa_priv.h +++ b/xorg-server/exa/exa_priv.h @@ -194,6 +194,7 @@ typedef struct { struct { PixmapPtr pixmap; int count; + Bool retval; } access[EXA_NUM_PREPARE_INDICES]; /* Holds information on fallbacks that cannot be relayed otherwise. */ |