summaryrefslogtreecommitdiff
path: root/exa/exa_accel.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2005-09-11 19:08:10 +0000
committerEric Anholt <anholt@freebsd.org>2005-09-11 19:08:10 +0000
commit1c003ccf5d68baaae6fafdc75eff964f2a62fc35 (patch)
tree309af5414b568d8382bca1e4eb8ac4a221fd86c9 /exa/exa_accel.c
parentca210830bd361e3d91b6bc741c495b61c424d1d2 (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.c105
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