EXA: Improve ShmPutImage.

Share as much code with exaPutImage as possible, and fall back to fbShmPutImage
when that fails.
This commit is contained in:
Michel Dänzer 2007-08-24 14:03:14 +02:00
parent 6085522d91
commit 5d9e2c2821
3 changed files with 60 additions and 24 deletions

View File

@ -32,10 +32,6 @@
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#ifdef MITSHM
#include "shmint.h"
#endif
#include <stdlib.h> #include <stdlib.h>
#include "exa_priv.h" #include "exa_priv.h"
@ -696,7 +692,7 @@ exaDriverInit (ScreenPtr pScreen,
* Shared pixmaps are almost always a performance loss for us, but this * Shared pixmaps are almost always a performance loss for us, but this
* still allows for SHM PutImage. * still allows for SHM PutImage.
*/ */
ShmRegisterFuncs(pScreen, NULL); ShmRegisterFuncs(pScreen, &exaShmFuncs);
#endif #endif
/* /*
* Hookup offscreen pixmaps * Hookup offscreen pixmaps

View File

@ -138,9 +138,9 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
exaMarkSync(pScreen); exaMarkSync(pScreen);
} }
static void static Bool
exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *bits) int w, int h, int leftPad, int format, char *bits, int src_stride)
{ {
ExaScreenPriv (pDrawable->pScreen); ExaScreenPriv (pDrawable->pScreen);
PixmapPtr pPix; PixmapPtr pPix;
@ -149,7 +149,8 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
BoxPtr pbox; BoxPtr pbox;
int nbox; int nbox;
int xoff, yoff; 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_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
@ -168,19 +169,12 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
exaDoMigration (pixmaps, 1, TRUE); exaDoMigration (pixmaps, 1, TRUE);
if (pExaScr->info->UploadToScreen == NULL)
goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
goto fallback;
x += pDrawable->x; x += pDrawable->x;
y += pDrawable->y; y += pDrawable->y;
pClip = fbGetCompositeClip(pGC); pClip = fbGetCompositeClip(pGC);
src_stride = PixmapBytePad(w, pDrawable->depth);
for (nbox = REGION_NUM_RECTS(pClip), for (nbox = REGION_NUM_RECTS(pClip),
pbox = REGION_RECTS(pClip); pbox = REGION_RECTS(pClip);
nbox--; nbox--;
@ -205,8 +199,10 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
continue; continue;
src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, ok = (pPix && pExaScr->info->UploadToScreen) ?
x2 - x1, y2 - y1, src, src_stride); 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 /* If we fail to accelerate the upload, fall back to using unaccelerated
* fb calls. * fb calls.
*/ */
@ -216,8 +212,12 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int dstBpp; int dstBpp;
int dstXoff, dstYoff; int dstXoff, dstYoff;
if (!access_prepared) {
exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
access_prepared = TRUE;
}
fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp, fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
dstXoff, dstYoff); dstXoff, dstYoff);
@ -230,22 +230,55 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
(x2 - x1) * dstBpp, (x2 - x1) * dstBpp,
y2 - y1, y2 - y1,
GXcopy, FB_ALLONES, dstBpp); GXcopy, FB_ALLONES, dstBpp);
}
if (access_prepared)
exaFinishAccess(pDrawable, EXA_PREPARE_DEST); exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
} }
exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); return TRUE;
}
return;
migrate_and_fallback: migrate_and_fallback:
exaDoMigration (pixmaps, 1, FALSE); exaDoMigration (pixmaps, 1, FALSE);
fallback: 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 static Bool inline
exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)

View File

@ -35,6 +35,9 @@
#include <X11/X.h> #include <X11/X.h>
#define NEED_EVENTS #define NEED_EVENTS
#include <X11/Xproto.h> #include <X11/Xproto.h>
#ifdef MITSHM
#include "shmint.h"
#endif
#include "scrnintstr.h" #include "scrnintstr.h"
#include "pixmapstr.h" #include "pixmapstr.h"
#include "windowstr.h" #include "windowstr.h"
@ -306,6 +309,10 @@ exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
extern const GCOps exaOps; extern const GCOps exaOps;
#ifdef MITSHM
extern ShmFuncs exaShmFuncs;
#endif
#ifdef RENDER #ifdef RENDER
void void
ExaCheckComposite (CARD8 op, ExaCheckComposite (CARD8 op,