From 1c003ccf5d68baaae6fafdc75eff964f2a62fc35 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 11 Sep 2005 19:08:10 +0000 Subject: [PATCH] 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 --- exa/exa.c | 105 +++++++++++++++++++++++----- exa/exa.h | 21 ++++++ exa/exa_accel.c | 105 +++++++++++++++++++++++----- exa/exa_migration.c | 105 +++++++++++++++++++++++----- exa/exa_priv.h | 7 ++ exa/exa_render.c | 9 +-- exa/exa_unaccel.c | 122 ++++++++++++++++++++------------- hw/xfree86/exa/exa.c | 105 +++++++++++++++++++++++----- hw/xfree86/exa/exa.h | 21 ++++++ hw/xfree86/exa/exaPriv.h | 7 ++ hw/xfree86/exa/exa_accel.c | 105 +++++++++++++++++++++++----- hw/xfree86/exa/exa_migration.c | 105 +++++++++++++++++++++++----- hw/xfree86/exa/exa_priv.h | 7 ++ hw/xfree86/exa/exa_render.c | 9 +-- hw/xfree86/exa/exa_unaccel.c | 122 ++++++++++++++++++++------------- hw/xfree86/exa/exaasync.c | 122 ++++++++++++++++++++------------- hw/xfree86/exa/exapict.c | 9 +-- 17 files changed, 813 insertions(+), 273 deletions(-) diff --git a/exa/exa.c b/exa/exa.c index 29a94b31d..92ff394e2 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -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 diff --git a/exa/exa.h b/exa/exa.h index 2cf9fe44a..5e850a3cf 100644 --- a/exa/exa.h +++ b/exa/exa.h @@ -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) \ diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 29a94b31d..92ff394e2 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -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 diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 29a94b31d..92ff394e2 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -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 diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 3d0904375..a53f370a3 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -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); diff --git a/exa/exa_render.c b/exa/exa_render.c index 5bfb07c4b..537f159e0 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -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, ®ion); return -1; } + exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC); + exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->format); diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index c0927751b..93502c800 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -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); } /* diff --git a/hw/xfree86/exa/exa.c b/hw/xfree86/exa/exa.c index 29a94b31d..92ff394e2 100644 --- a/hw/xfree86/exa/exa.c +++ b/hw/xfree86/exa/exa.c @@ -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 diff --git a/hw/xfree86/exa/exa.h b/hw/xfree86/exa/exa.h index 2cf9fe44a..5e850a3cf 100644 --- a/hw/xfree86/exa/exa.h +++ b/hw/xfree86/exa/exa.h @@ -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) \ diff --git a/hw/xfree86/exa/exaPriv.h b/hw/xfree86/exa/exaPriv.h index 3d0904375..a53f370a3 100644 --- a/hw/xfree86/exa/exaPriv.h +++ b/hw/xfree86/exa/exaPriv.h @@ -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); diff --git a/hw/xfree86/exa/exa_accel.c b/hw/xfree86/exa/exa_accel.c index 29a94b31d..92ff394e2 100644 --- a/hw/xfree86/exa/exa_accel.c +++ b/hw/xfree86/exa/exa_accel.c @@ -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 diff --git a/hw/xfree86/exa/exa_migration.c b/hw/xfree86/exa/exa_migration.c index 29a94b31d..92ff394e2 100644 --- a/hw/xfree86/exa/exa_migration.c +++ b/hw/xfree86/exa/exa_migration.c @@ -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 diff --git a/hw/xfree86/exa/exa_priv.h b/hw/xfree86/exa/exa_priv.h index 3d0904375..a53f370a3 100644 --- a/hw/xfree86/exa/exa_priv.h +++ b/hw/xfree86/exa/exa_priv.h @@ -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); diff --git a/hw/xfree86/exa/exa_render.c b/hw/xfree86/exa/exa_render.c index 5bfb07c4b..537f159e0 100644 --- a/hw/xfree86/exa/exa_render.c +++ b/hw/xfree86/exa/exa_render.c @@ -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, ®ion); return -1; } + exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC); + exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->format); diff --git a/hw/xfree86/exa/exa_unaccel.c b/hw/xfree86/exa/exa_unaccel.c index c0927751b..93502c800 100644 --- a/hw/xfree86/exa/exa_unaccel.c +++ b/hw/xfree86/exa/exa_unaccel.c @@ -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); } /* diff --git a/hw/xfree86/exa/exaasync.c b/hw/xfree86/exa/exaasync.c index c0927751b..93502c800 100644 --- a/hw/xfree86/exa/exaasync.c +++ b/hw/xfree86/exa/exaasync.c @@ -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); } /* diff --git a/hw/xfree86/exa/exapict.c b/hw/xfree86/exa/exapict.c index 5bfb07c4b..537f159e0 100644 --- a/hw/xfree86/exa/exapict.c +++ b/hw/xfree86/exa/exapict.c @@ -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, ®ion); return -1; } + exaFinishAccess(&pSrcPix->drawable, EXA_PREPARE_SRC); + exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->format);