Add a pair of hooks, PrepareAccess() and FinishAccess(), which get called

around CPU access to the framebuffer. This allows the hardware to set
    up swappers to deal with endianness, or to tell EXA to move the pixmap
    out to framebuffer if insufficient swappers are available (note: must
    not fail on front buffer!).
Submitted by: benh
This commit is contained in:
Eric Anholt 2005-09-11 19:08:10 +00:00
parent ca210830bd
commit 1c003ccf5d
17 changed files with 813 additions and 273 deletions

105
exa/exa.c
View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -175,6 +175,24 @@ typedef struct _ExaAccelInfo {
*/
int (*MarkSync) (ScreenPtr pScreen);
void (*WaitMarker) (ScreenPtr pScreen, int marker);
/* These are wrapping all fb or composite operations that will cause
* a direct access to the framebuffer. You can use them to update
* endian swappers, force migration to RAM, or whatever else you find
* useful at this point. EXA can stack up to 3 calls to Prepare/Finish
* access, though they will have a different index. If your hardware
* doesn't have enough separate configurable swapper, you can return
* FALSE from PrepareAccess() to force EXA to migrate the pixmap to RAM.
* Note that DownloadFromScreen and UploadToScreen can both be called
* between PrepareAccess() and FinishAccess(). If they need to use a
* swapper, they should save & restore its setting.
*/
Bool (*PrepareAccess)(PixmapPtr pPix, int index);
void (*FinishAccess)(PixmapPtr pPix, int index);
#define EXA_PREPARE_DEST 0
#define EXA_PREPARE_SRC 1
#define EXA_PREPARE_MASK 2
} ExaAccelInfoRec, *ExaAccelInfoPtr;
typedef struct _ExaDriver {
@ -224,6 +242,9 @@ exaGetPixmapOffset(PixmapPtr pPix);
unsigned long
exaGetPixmapPitch(PixmapPtr pPix);
unsigned long
exaGetPixmapSize(PixmapPtr pPix);
#define exaInitCard(exa, sync, memory_base, off_screen_base, memory_size, \
offscreen_byte_align, offscreen_pitch, flags, \
max_x, max_y) \

View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -103,6 +103,7 @@ typedef struct {
int devKind;
DevUnion devPrivate;
Bool dirty;
unsigned int size;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
@ -246,6 +247,12 @@ exaPixmapUseScreen (PixmapPtr pPixmap);
void
exaPixmapUseMemory (PixmapPtr pPixmap);
void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
exaFinishAccess(DrawablePtr pDrawable, int index);
void
exaDrawableDirty(DrawablePtr pDrawable);

View File

@ -262,13 +262,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
else
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
/* If source is offscreen, we need to sync the accelerator
* before accessing it. We'd prefer for it to be in memory.
*/
if (exaPixmapIsOffscreen(pSrcPix)) {
exaWaitSync(pDst->pDrawable->pScreen);
}
exaPrepareAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
pSrc->format))
@ -276,6 +271,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
pDst->format);

View File

@ -33,18 +33,18 @@ void
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
DDXPointPtr ppt, int *pwidth, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -52,18 +52,24 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
RegionPtr
@ -71,19 +77,25 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty,
unsigned long bitPlane)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
void
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -92,10 +104,11 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
}
@ -104,10 +117,11 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
int nsegInit, xSegment *pSegInit)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
}
@ -116,8 +130,10 @@ ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
int nrects, xRectangle *prect)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyRectangle (pDrawable, pGC, nrects, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolyRectangle (pDrawable, pGC, nrects, prect);
}
@ -128,12 +144,12 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
else
miPolyArc (pDrawable, pGC, narcs, pArcs);
miPolyArc (pDrawable, pGC, narcs, pArcs);
}
#if 0
@ -141,9 +157,9 @@ void
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count, DDXPointPtr pPts)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
#endif
@ -151,18 +167,18 @@ void
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillRect (pDrawable, pGC, nrect, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -170,9 +186,9 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -180,9 +196,9 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -190,9 +206,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -201,8 +217,9 @@ ExaCheckGetImage (DrawablePtr pDrawable,
unsigned int format, unsigned long planeMask,
char *d)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -213,8 +230,9 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
int nspans,
char *pdstStart)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -224,9 +242,9 @@ ExaCheckSaveAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty (&pPixmap->drawable);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
@ -236,17 +254,17 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
{
exaWaitSync (pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
fbPaintWindow (pWin, pRegion, what);
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
}
void
@ -263,8 +281,10 @@ ExaCheckComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
exaWaitSync (pDst->pDrawable->pScreen);
exaDrawableDirty (pDst->pDrawable);
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask)
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
fbComposite (op,
pSrc,
pMask,
@ -277,6 +297,10 @@ ExaCheckComposite (CARD8 op,
yDst,
width,
height);
if (pMask)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
}
/*

View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -175,6 +175,24 @@ typedef struct _ExaAccelInfo {
*/
int (*MarkSync) (ScreenPtr pScreen);
void (*WaitMarker) (ScreenPtr pScreen, int marker);
/* These are wrapping all fb or composite operations that will cause
* a direct access to the framebuffer. You can use them to update
* endian swappers, force migration to RAM, or whatever else you find
* useful at this point. EXA can stack up to 3 calls to Prepare/Finish
* access, though they will have a different index. If your hardware
* doesn't have enough separate configurable swapper, you can return
* FALSE from PrepareAccess() to force EXA to migrate the pixmap to RAM.
* Note that DownloadFromScreen and UploadToScreen can both be called
* between PrepareAccess() and FinishAccess(). If they need to use a
* swapper, they should save & restore its setting.
*/
Bool (*PrepareAccess)(PixmapPtr pPix, int index);
void (*FinishAccess)(PixmapPtr pPix, int index);
#define EXA_PREPARE_DEST 0
#define EXA_PREPARE_SRC 1
#define EXA_PREPARE_MASK 2
} ExaAccelInfoRec, *ExaAccelInfoPtr;
typedef struct _ExaDriver {
@ -224,6 +242,9 @@ exaGetPixmapOffset(PixmapPtr pPix);
unsigned long
exaGetPixmapPitch(PixmapPtr pPix);
unsigned long
exaGetPixmapSize(PixmapPtr pPix);
#define exaInitCard(exa, sync, memory_base, off_screen_base, memory_size, \
offscreen_byte_align, offscreen_pitch, flags, \
max_x, max_y) \

View File

@ -103,6 +103,7 @@ typedef struct {
int devKind;
DevUnion devPrivate;
Bool dirty;
unsigned int size;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
@ -246,6 +247,12 @@ exaPixmapUseScreen (PixmapPtr pPixmap);
void
exaPixmapUseMemory (PixmapPtr pPixmap);
void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
exaFinishAccess(DrawablePtr pDrawable, int index);
void
exaDrawableDirty(DrawablePtr pDrawable);

View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -78,6 +78,21 @@ exaGetPixmapPitch(PixmapPtr pPix)
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
{
ExaPixmapPrivPtr pExaPixmap;
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
return pExaPixmap->size;
return 0;
}
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -185,6 +200,7 @@ exaPixmapAllocArea (PixmapPtr pPixmap)
pitch = (w * bpp / 8) + (pExaScr->info->card.pixmapPitchAlign - 1);
pitch -= pitch % pExaScr->info->card.pixmapPitchAlign;
pExaPixmap->size = pitch * h;
pExaPixmap->devKind = pPixmap->devKind;
pExaPixmap->devPrivate = pPixmap->devPrivate;
pExaPixmap->area = exaOffscreenAlloc (pScreen, pitch * h,
@ -439,6 +455,7 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
{
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
@ -446,6 +463,57 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
return exaPixmapIsOffscreen (pPixmap);
}
void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (index == EXA_PREPARE_DEST)
exaDrawableDirty (pDrawable);
if (exaPixmapIsOffscreen (pPixmap))
exaWaitSync (pDrawable->pScreen);
else
return;
if (pExaScr->info->accel.PrepareAccess == NULL)
return;
if (!(*pExaScr->info->accel.PrepareAccess) (pPixmap, index)) {
ExaPixmapPriv (pPixmap);
assert (pExaPixmap->score != EXA_PIXMAP_SCORE_PINNED);
exaMoveOutPixmap (pPixmap);
}
}
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
PixmapPtr pPixmap;
STRACE;
if (pExaScr->info->accel.FinishAccess == NULL)
return;
if (pDrawable->type == DRAWABLE_WINDOW)
pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable);
else
pPixmap = (PixmapPtr) pDrawable;
if (!exaPixmapIsOffscreen (pPixmap))
return;
(*pExaScr->info->accel.FinishAccess) (pPixmap, index);
}
#if 0
static void
exaFillTiled(int dst_x,
@ -620,10 +688,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
exaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
if (pDstDrawable->type == DRAWABLE_PIXMAP)
exaPixmapUseMemory ((PixmapPtr) pDstDrawable);
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
goto fallback;
}
/* If either drawable is already in framebuffer, try to get both of them
@ -664,15 +729,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
}
(*pExaScr->info->accel.DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
exaDrawableDirty (pDstDrawable);
return;
}
else
{
exaWaitSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
}
exaDrawableDirty (pDstDrawable);
fallback:
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
RegionPtr
@ -822,12 +890,12 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
!(*pExaScr->info->accel.PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
fbXor (GXcopy, fg, pm));
exaDrawableDirty (pDrawable);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
@ -949,8 +1017,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
opaque = FALSE;
}
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
ppci = ppciInit;
while (nglyph--)
@ -996,6 +1063,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
x += pci->metrics.characterWidth;
}
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
static const GCOps exaOps = {
@ -1121,14 +1189,15 @@ exaFillRegionSolid (DrawablePtr pDrawable,
}
(*pExaScr->info->accel.DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
}
else
{
exaWaitSync (pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
exaDrawableDirty (pDrawable);
}
static void

View File

@ -103,6 +103,7 @@ typedef struct {
int devKind;
DevUnion devPrivate;
Bool dirty;
unsigned int size;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
@ -246,6 +247,12 @@ exaPixmapUseScreen (PixmapPtr pPixmap);
void
exaPixmapUseMemory (PixmapPtr pPixmap);
void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
exaFinishAccess(DrawablePtr pDrawable, int index);
void
exaDrawableDirty(DrawablePtr pDrawable);

View File

@ -262,13 +262,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
else
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
/* If source is offscreen, we need to sync the accelerator
* before accessing it. We'd prefer for it to be in memory.
*/
if (exaPixmapIsOffscreen(pSrcPix)) {
exaWaitSync(pDst->pDrawable->pScreen);
}
exaPrepareAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
pSrc->format))
@ -276,6 +271,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
pDst->format);

View File

@ -33,18 +33,18 @@ void
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
DDXPointPtr ppt, int *pwidth, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -52,18 +52,24 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
RegionPtr
@ -71,19 +77,25 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty,
unsigned long bitPlane)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
void
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -92,10 +104,11 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
}
@ -104,10 +117,11 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
int nsegInit, xSegment *pSegInit)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
}
@ -116,8 +130,10 @@ ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
int nrects, xRectangle *prect)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyRectangle (pDrawable, pGC, nrects, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolyRectangle (pDrawable, pGC, nrects, prect);
}
@ -128,12 +144,12 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
else
miPolyArc (pDrawable, pGC, narcs, pArcs);
miPolyArc (pDrawable, pGC, narcs, pArcs);
}
#if 0
@ -141,9 +157,9 @@ void
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count, DDXPointPtr pPts)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
#endif
@ -151,18 +167,18 @@ void
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillRect (pDrawable, pGC, nrect, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -170,9 +186,9 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -180,9 +196,9 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -190,9 +206,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -201,8 +217,9 @@ ExaCheckGetImage (DrawablePtr pDrawable,
unsigned int format, unsigned long planeMask,
char *d)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -213,8 +230,9 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
int nspans,
char *pdstStart)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -224,9 +242,9 @@ ExaCheckSaveAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty (&pPixmap->drawable);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
@ -236,17 +254,17 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
{
exaWaitSync (pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
fbPaintWindow (pWin, pRegion, what);
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
}
void
@ -263,8 +281,10 @@ ExaCheckComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
exaWaitSync (pDst->pDrawable->pScreen);
exaDrawableDirty (pDst->pDrawable);
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask)
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
fbComposite (op,
pSrc,
pMask,
@ -277,6 +297,10 @@ ExaCheckComposite (CARD8 op,
yDst,
width,
height);
if (pMask)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
}
/*

View File

@ -33,18 +33,18 @@ void
ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
DDXPointPtr ppt, int *pwidth, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbSetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -52,18 +52,24 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
RegionPtr
@ -71,19 +77,25 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty,
unsigned long bitPlane)
{
exaWaitSync (pSrc->pScreen);
exaDrawableDirty (pDst);
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
RegionPtr ret;
exaPrepareAccess (pDst, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
ret = fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
return ret;
}
void
ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
DDXPointPtr pptInit)
{
exaWaitSync (pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyPoint (pDrawable, pGC, mode, npt, pptInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -92,10 +104,11 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolyLine (pDrawable, pGC, mode, npt, ppt);
}
@ -104,10 +117,11 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
int nsegInit, xSegment *pSegInit)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
exaDrawableDirty (pDrawable);
fbPolySegment (pDrawable, pGC, nsegInit, pSegInit);
}
@ -116,8 +130,10 @@ ExaCheckPolyRectangle (DrawablePtr pDrawable, GCPtr pGC,
int nrects, xRectangle *prect)
{
if (pGC->lineWidth == 0) {
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyRectangle (pDrawable, pGC, nrects, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
fbPolyRectangle (pDrawable, pGC, nrects, prect);
}
@ -128,12 +144,12 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
{
if (pGC->lineWidth == 0)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return;
}
else
miPolyArc (pDrawable, pGC, narcs, pArcs);
miPolyArc (pDrawable, pGC, narcs, pArcs);
}
#if 0
@ -141,9 +157,9 @@ void
ExaCheckFillPolygon (DrawablePtr pDrawable, GCPtr pGC,
int shape, int mode, int count, DDXPointPtr pPts)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillPolygon (pDrawable, pGC, mode, count, pPts);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
#endif
@ -151,18 +167,18 @@ void
ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
int nrect, xRectangle *prect)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillRect (pDrawable, pGC, nrect, prect);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
ExaCheckPolyFillArc (DrawablePtr pDrawable, GCPtr pGC,
int narcs, xArc *pArcs)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyFillArc (pDrawable, pGC, narcs, pArcs);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -170,9 +186,9 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -180,9 +196,9 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
int x, int y, unsigned int nglyph,
CharInfoPtr *ppci, pointer pglyphBase)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -190,9 +206,9 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
DrawablePtr pDrawable,
int w, int h, int x, int y)
{
exaWaitSync(pDrawable->pScreen);
exaDrawableDirty (pDrawable);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
@ -201,8 +217,9 @@ ExaCheckGetImage (DrawablePtr pDrawable,
unsigned int format, unsigned long planeMask,
char *d)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -213,8 +230,9 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
int nspans,
char *pdstStart)
{
exaWaitSync(pDrawable->pScreen);
exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
}
void
@ -224,9 +242,9 @@ ExaCheckSaveAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty (&pPixmap->drawable);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbSaveAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
@ -236,17 +254,17 @@ ExaCheckRestoreAreas (PixmapPtr pPixmap,
int yorg,
WindowPtr pWin)
{
exaWaitSync(pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
fbRestoreAreas (pPixmap, prgnSave, xorg, yorg, pWin);
exaFinishAccess ((DrawablePtr)pPixmap, EXA_PREPARE_DEST);
}
void
ExaCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what)
{
exaWaitSync (pWin->drawable.pScreen);
exaDrawableDirty ((DrawablePtr)pWin);
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
fbPaintWindow (pWin, pRegion, what);
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
}
void
@ -263,8 +281,10 @@ ExaCheckComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
exaWaitSync (pDst->pDrawable->pScreen);
exaDrawableDirty (pDst->pDrawable);
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask)
exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
fbComposite (op,
pSrc,
pMask,
@ -277,6 +297,10 @@ ExaCheckComposite (CARD8 op,
yDst,
width,
height);
if (pMask)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
}
/*

View File

@ -262,13 +262,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
else
pSrcPix = (PixmapPtr) (pSrc->pDrawable);
/* If source is offscreen, we need to sync the accelerator
* before accessing it. We'd prefer for it to be in memory.
*/
if (exaPixmapIsOffscreen(pSrcPix)) {
exaWaitSync(pDst->pDrawable->pScreen);
}
exaPrepareAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
pSrc->format))
@ -276,6 +271,8 @@ exaTryDriverSolidFill(PicturePtr pSrc,
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
return -1;
}
exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC);
exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
pDst->format);