From 5d9e2c282145897008d7d941e2a0a3fdc71f2373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Fri, 24 Aug 2007 14:03:14 +0200 Subject: [PATCH] EXA: Improve ShmPutImage. Share as much code with exaPutImage as possible, and fall back to fbShmPutImage when that fails. --- exa/exa.c | 6 +---- exa/exa_accel.c | 71 ++++++++++++++++++++++++++++++++++++------------- exa/exa_priv.h | 7 +++++ 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/exa/exa.c b/exa/exa.c index b2faf2f1c..d827fc66e 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -32,10 +32,6 @@ #include #endif -#ifdef MITSHM -#include "shmint.h" -#endif - #include #include "exa_priv.h" @@ -696,7 +692,7 @@ exaDriverInit (ScreenPtr pScreen, * Shared pixmaps are almost always a performance loss for us, but this * still allows for SHM PutImage. */ - ShmRegisterFuncs(pScreen, NULL); + ShmRegisterFuncs(pScreen, &exaShmFuncs); #endif /* * Hookup offscreen pixmaps diff --git a/exa/exa_accel.c b/exa/exa_accel.c index cc383cca4..3af5c6eb1 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -138,9 +138,9 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, exaMarkSync(pScreen); } -static void -exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - int w, int h, int leftPad, int format, char *bits) +static Bool +exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits, int src_stride) { ExaScreenPriv (pDrawable->pScreen); PixmapPtr pPix; @@ -149,7 +149,8 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, BoxPtr pbox; int nbox; int xoff, yoff; - int src_stride, bpp = pDrawable->bitsPerPixel; + int bpp = pDrawable->bitsPerPixel; + Bool access_prepared = FALSE; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = FALSE; @@ -168,19 +169,12 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, exaDoMigration (pixmaps, 1, TRUE); - if (pExaScr->info->UploadToScreen == NULL) - goto fallback; - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - if (pPix == NULL) - goto fallback; - x += pDrawable->x; y += pDrawable->y; pClip = fbGetCompositeClip(pGC); - src_stride = PixmapBytePad(w, pDrawable->depth); for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); nbox--; @@ -205,8 +199,10 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, continue; src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); - ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, - x2 - x1, y2 - y1, src, src_stride); + ok = (pPix && pExaScr->info->UploadToScreen) ? + pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, + x2 - x1, y2 - y1, src, src_stride) : + FALSE; /* If we fail to accelerate the upload, fall back to using unaccelerated * fb calls. */ @@ -216,7 +212,11 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int dstBpp; int dstXoff, dstYoff; - exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); + if (!access_prepared) { + exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); + + access_prepared = TRUE; + } fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, dstXoff, dstYoff); @@ -230,22 +230,55 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, (x2 - x1) * dstBpp, y2 - y1, GXcopy, FB_ALLONES, dstBpp); - - exaFinishAccess(pDrawable, EXA_PREPARE_DEST); } - exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); + if (access_prepared) + exaFinishAccess(pDrawable, EXA_PREPARE_DEST); + + exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); } - return; + return TRUE; migrate_and_fallback: exaDoMigration (pixmaps, 1, FALSE); fallback: - ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); + return FALSE; } +static void +exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ + if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits, + PixmapBytePad(w, pDrawable->depth))) + ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, + bits); +} + +#ifdef MITSHM + +static void +exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format, + int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, + char *data) +{ + int src_stride = PixmapBytePad(w, depth); + + if (exaDoPutImage(pDrawable, pGC, depth, dx, dy, sw, sh, 0, format, data + + sy * src_stride + sx * BitsPerPixel(depth) / 8, + src_stride)) + return; + + fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, + data); +} + +ShmFuncs exaShmFuncs = { NULL, exaShmPutImage }; + +#endif + static Bool inline exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) diff --git a/exa/exa_priv.h b/exa/exa_priv.h index bab8aa23b..9bed5c871 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -35,6 +35,9 @@ #include #define NEED_EVENTS #include +#ifdef MITSHM +#include "shmint.h" +#endif #include "scrnintstr.h" #include "pixmapstr.h" #include "windowstr.h" @@ -306,6 +309,10 @@ exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth, extern const GCOps exaOps; +#ifdef MITSHM +extern ShmFuncs exaShmFuncs; +#endif + #ifdef RENDER void ExaCheckComposite (CARD8 op,