diff options
author | Eric Anholt <anholt@freebsd.org> | 2005-09-11 19:08:10 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2005-09-11 19:08:10 +0000 |
commit | 1c003ccf5d68baaae6fafdc75eff964f2a62fc35 (patch) | |
tree | 309af5414b568d8382bca1e4eb8ac4a221fd86c9 /exa/exa_accel.c | |
parent | ca210830bd361e3d91b6bc741c495b61c424d1d2 (diff) |
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
Diffstat (limited to 'exa/exa_accel.c')
-rw-r--r-- | exa/exa_accel.c | 105 |
1 files changed, 87 insertions, 18 deletions
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 |