From 1b5758bef0840c6614244e321790231b3c9477c9 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 9 Apr 2009 15:45:57 +0200 Subject: [PATCH] exa: implement UTS based upload through CopyArea - Some image viewers (eog, gqview) trigger the CopyArea path of Xext/shm.c - I'm not aware of any code path that wouldn't like UTS and trigger this code. - miDoCopy should handle src coordinate clipping. - Overlapping blits are obviously not an issue (both would have to be offscreen or not). --- exa/exa_accel.c | 72 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/exa/exa_accel.c b/exa/exa_accel.c index b1ab2d1d9..d284ff560 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -466,27 +466,59 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, goto fallback; } - if (!exaPixmapIsOffscreen(pSrcPixmap) || - !exaPixmapIsOffscreen(pDstPixmap) || - !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, - upsidedown ? -1 : 1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : FB_ALLONES)) { + if (exaPixmapIsOffscreen(pDstPixmap)) { + /* Normal blitting. */ + if (exaPixmapIsOffscreen(pSrcPixmap)) { + if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, + upsidedown ? -1 : 1, + pGC ? pGC->alu : GXcopy, + pGC ? pGC->planemask : FB_ALLONES)) { + goto fallback; + } + + while (nbox--) + { + (*pExaScr->info->Copy) (pDstPixmap, + pbox->x1 + dx + src_off_x, + pbox->y1 + dy + src_off_y, + pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, + pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); + pbox++; + } + + (*pExaScr->info->DoneCopy) (pDstPixmap); + exaMarkSync (pDstDrawable->pScreen); + /* UTS: mainly for SHM PutImage's secondary path. */ + } else { + int bpp = pSrcDrawable->bitsPerPixel; + int src_stride = exaGetPixmapPitch(pSrcPixmap); + CARD8 *src = NULL; + + if (!pExaScr->info->UploadToScreen) + goto fallback; + + if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) + goto fallback; + + if (pSrcDrawable->bitsPerPixel < 8) + goto fallback; + + if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) + goto fallback; + + while (nbox--) + { + src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); + if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, + pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, + (char *) src, src_stride)) + goto fallback; + + pbox++; + } + } + } else goto fallback; - } - - while (nbox--) - { - (*pExaScr->info->Copy) (pDstPixmap, - pbox->x1 + dx + src_off_x, - pbox->y1 + dy + src_off_y, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pbox++; - } - - (*pExaScr->info->DoneCopy) (pDstPixmap); - exaMarkSync (pDstDrawable->pScreen); goto out;