Reimplement ShmPutImage.

There's no reason to not just dispatch this straight into the GC.  As a
bonus, if you do so, damage wraps correctly, and thus swcursor works.
The side effect is it's no longer possible to override ShmPutImage with
ShmRegisterFuncs().

Also remove the (broken) damage tracking for same from EXA, since it didn't
work right, and is now superfluous.

(cherry picked from commit ee7c684f21)
This commit is contained in:
Adam Jackson 2008-08-27 16:05:47 -04:00
parent ef0780b738
commit 4652c51e92
5 changed files with 25 additions and 180 deletions

View File

@ -106,7 +106,6 @@ typedef struct _ShmDesc {
unsigned long size;
} ShmDescRec, *ShmDescPtr;
static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
static int ShmDetachSegment(
pointer /* value */,
@ -148,8 +147,8 @@ static int shmPixFormat[MAXSCREENS];
static ShmFuncsPtr shmFuncs[MAXSCREENS];
static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivate;
static ShmFuncs miFuncs = {NULL, miShmPutImage};
static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
static ShmFuncs miFuncs = {NULL, NULL};
static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
{ \
@ -522,70 +521,28 @@ ProcShmDetach(client)
return(client->noClientException);
}
/*
* If the given request doesn't exactly match PutImage's constraints,
* wrap the image in a scratch pixmap header and let CopyArea sort it out.
*/
static void
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
DrawablePtr dst;
GCPtr pGC;
int depth, w, h, sx, sy, sw, sh, dx, dy;
unsigned int format;
char *data;
doShmPutImage(DrawablePtr dst, 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)
{
PixmapPtr pmap;
GCPtr putGC;
putGC = GetScratchGC(depth, dst->pScreen);
if (!putGC)
PixmapPtr pPixmap;
pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
BitsPerPixel(depth),
PixmapBytePad(w, depth),
data);
if (!pPixmap)
return;
pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
CREATE_PIXMAP_USAGE_SCRATCH);
if (!pmap)
{
FreeScratchGC(putGC);
return;
}
ValidateGC((DrawablePtr)pmap, putGC);
(*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
(format == XYPixmap) ? XYPixmap : ZPixmap, data);
FreeScratchGC(putGC);
if (format == XYBitmap)
(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
dx, dy, 1L);
else
(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
dx, dy);
(*pmap->drawable.pScreen->DestroyPixmap)(pmap);
pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy);
FreeScratchPixmapHeader(pPixmap);
}
_X_EXPORT void
fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
DrawablePtr dst;
GCPtr pGC;
int depth, w, h, sx, sy, sw, sh, dx, dy;
unsigned int format;
char *data;
{
if ((format == ZPixmap) || (depth == 1))
{
PixmapPtr pPixmap;
pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
if (!pPixmap)
return;
if (format == XYBitmap)
(void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
sx, sy, sw, sh, dx, dy, 1L);
else
(void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
sx, sy, sw, sh, dx, dy);
FreeScratchPixmapHeader(pPixmap);
}
else
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
data);
}
#ifdef PANORAMIX
static int
ProcPanoramiXShmPutImage(register ClientPtr client)
@ -940,13 +897,12 @@ ProcShmPutImage(client)
shmdesc->addr + stuff->offset +
(stuff->srcY * length));
else
(*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
pDraw, pGC, stuff->depth, stuff->format,
stuff->totalWidth, stuff->totalHeight,
stuff->srcX, stuff->srcY,
stuff->srcWidth, stuff->srcHeight,
stuff->dstX, stuff->dstY,
shmdesc->addr + stuff->offset);
doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
stuff->totalWidth, stuff->totalHeight,
stuff->srcX, stuff->srcY,
stuff->srcWidth, stuff->srcHeight,
stuff->dstX, stuff->dstY,
shmdesc->addr + stuff->offset);
if (stuff->sendEvent)
{

View File

@ -36,9 +36,6 @@ ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs);
void
ShmSetPixmapFormat(ScreenPtr pScreen, int format);
void
fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
void
ShmRegisterFbFuncs(ScreenPtr pScreen);

View File

@ -924,13 +924,6 @@ exaDriverInit (ScreenPtr pScreen,
}
#endif
#ifdef MITSHM
/* Re-register with the MI funcs, which don't allow shared pixmaps.
* Shared pixmaps are almost always a performance loss for us, but this
* still allows for SHM PutImage.
*/
ShmRegisterFuncs(pScreen, &exaShmFuncs);
#endif
/*
* Hookup offscreen pixmaps
*/

View File

@ -245,104 +245,12 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
return TRUE;
}
#ifdef MITSHM
static Bool
exaDoShmPutImage(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, format, data +
sy * src_stride + sx * BitsPerPixel(depth) / 8,
src_stride))
return TRUE;
if (format == ZPixmap)
{
PixmapPtr pPixmap;
pPixmap = GetScratchPixmapHeader(pDrawable->pScreen, w, h, depth,
BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
if (!pPixmap)
return FALSE;
if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
pGC->alu))
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
else
ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy);
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
FreeScratchPixmapHeader(pPixmap);
return TRUE;
}
return FALSE;
}
/* The actual ShmPutImage isn't wrapped by the damage layer, so we need to
* inform any interested parties of the damage incurred to the drawable.
*
* We also need to set the pending damage to ensure correct migration in all
* cases.
*/
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)
{
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
ExaPixmapPriv(pPixmap);
BoxRec box = { .x1 = pDrawable->x + dx, .y1 = pDrawable->y + dy,
.x2 = pDrawable->x + dx + sw, .y2 = pDrawable->y + dy + sh };
RegionRec region;
int xoff, yoff;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
REGION_INIT(pScreen, &region, &box, 1);
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
REGION_UNION(pScreen, pending_damage, pending_damage, &region);
if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh,
dx, dy, data)) {
if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
pGC->alu))
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
else
ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
data);
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
}
REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
DamageDamageRegion(pDrawable, &region);
REGION_UNINIT(pScreen, &region);
}
ShmFuncs exaShmFuncs = { NULL, exaShmPutImage };
#endif
static void
exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *bits)
{
#ifdef MITSHM
if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, 0, 0, w, h, x, y,
bits))
#else
if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
PixmapBytePad(w, pDrawable->depth)))
#endif
ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
bits);
}

View File

@ -319,21 +319,12 @@ Bool
exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
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);
void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d);
extern const GCOps exaOps;
#ifdef MITSHM
extern ShmFuncs exaShmFuncs;
#endif
#ifdef RENDER
void
ExaCheckComposite (CARD8 op,