aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/exa
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
committermarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
commit0f834b91a4768673833ab4917e87d86c237bb1a6 (patch)
tree363489504ed4b2d360259b8de4c9e392918e5d02 /xorg-server/exa
parentfc72edebf875378459368c5383d9023730cbca54 (diff)
downloadvcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.gz
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.bz2
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.zip
libX11 xserver fontconfig mesa pixman xkbcomp xkeyboard-config git update
23 Mar 2012
Diffstat (limited to 'xorg-server/exa')
-rw-r--r--xorg-server/exa/exa.c627
-rw-r--r--xorg-server/exa/exa.h1659
-rw-r--r--xorg-server/exa/exa_accel.c1634
-rw-r--r--xorg-server/exa/exa_classic.c164
-rw-r--r--xorg-server/exa/exa_driver.c114
-rw-r--r--xorg-server/exa/exa_glyphs.c1702
-rw-r--r--xorg-server/exa/exa_migration_classic.c702
-rw-r--r--xorg-server/exa/exa_migration_mixed.c275
-rw-r--r--xorg-server/exa/exa_mixed.c221
-rw-r--r--xorg-server/exa/exa_offscreen.c1374
-rw-r--r--xorg-server/exa/exa_priv.h495
-rw-r--r--xorg-server/exa/exa_render.c1463
-rw-r--r--xorg-server/exa/exa_unaccel.c706
13 files changed, 5522 insertions, 5614 deletions
diff --git a/xorg-server/exa/exa.c b/xorg-server/exa/exa.c
index 4ce983bc3..754c8305a 100644
--- a/xorg-server/exa/exa.c
+++ b/xorg-server/exa/exa.c
@@ -58,10 +58,10 @@ static ShmFuncs exaShmFuncs = { NULL, NULL };
unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
- ExaScreenPriv (pPix->drawable.pScreen);
- ExaPixmapPriv (pPix);
+ ExaScreenPriv(pPix->drawable.pScreen);
+ ExaPixmapPriv(pPix);
- return (CARD8 *)pExaPixmap->fb_ptr - pExaScr->info->memoryBase;
+ return (CARD8 *) pExaPixmap->fb_ptr - pExaScr->info->memoryBase;
}
void *
@@ -95,7 +95,7 @@ exaGetPixmapSize(PixmapPtr pPix)
pExaPixmap = ExaGetPixmapPriv(pPix);
if (pExaPixmap != NULL)
- return pExaPixmap->fb_size;
+ return pExaPixmap->fb_size;
return 0;
}
@@ -113,10 +113,10 @@ exaGetPixmapSize(PixmapPtr pPix)
PixmapPtr
exaGetDrawablePixmap(DrawablePtr pDrawable)
{
- if (pDrawable->type == DRAWABLE_WINDOW)
- return pDrawable->pScreen->GetWindowPixmap ((WindowPtr) pDrawable);
- else
- return (PixmapPtr) pDrawable;
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable);
+ else
+ return (PixmapPtr) pDrawable;
}
/**
@@ -125,14 +125,13 @@ exaGetDrawablePixmap(DrawablePtr pDrawable)
* windows.
*/
void
-exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
- int *xp, int *yp)
+exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap, int *xp, int *yp)
{
#ifdef COMPOSITE
if (pDrawable->type == DRAWABLE_WINDOW) {
- *xp = -pPixmap->screen_x;
- *yp = -pPixmap->screen_y;
- return;
+ *xp = -pPixmap->screen_x;
+ *yp = -pPixmap->screen_y;
+ return;
}
#endif
@@ -145,7 +144,7 @@ exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
* optimizations in pixmap migration when no changes have occurred.
*/
void
-exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
+exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2)
{
BoxRec box;
RegionRec region;
@@ -156,7 +155,7 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
box.y2 = min(y2, pPix->drawable.height);
if (box.x1 >= box.x2 || box.y1 >= box.y2)
- return;
+ return;
RegionInit(&region, &box, 1);
DamageDamageRegion(&pPix->drawable, &region);
@@ -169,9 +168,9 @@ exaLog2(int val)
int bits;
if (val <= 0)
- return 0;
+ return 0;
for (bits = 0; val != 0; bits++)
- val >>= 1;
+ val >>= 1;
return bits - 1;
}
@@ -218,12 +217,12 @@ exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
* some X Server internal component (the score says it's pinned).
*/
Bool
-exaPixmapIsPinned (PixmapPtr pPix)
+exaPixmapIsPinned(PixmapPtr pPix)
{
- ExaPixmapPriv (pPix);
+ ExaPixmapPriv(pPix);
if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE);
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE);
return pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
}
@@ -243,22 +242,23 @@ exaPixmapIsPinned (PixmapPtr pPix)
Bool
exaPixmapHasGpuCopy(PixmapPtr pPixmap)
{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return FALSE;
+ return FALSE;
- return (*pExaScr->pixmap_has_gpu_copy)(pPixmap);
+ return (*pExaScr->pixmap_has_gpu_copy) (pPixmap);
}
/**
* exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapHasGpuCopy().
*/
Bool
-exaDrawableIsOffscreen (DrawablePtr pDrawable)
+exaDrawableIsOffscreen(DrawablePtr pDrawable)
{
- return exaPixmapHasGpuCopy (exaGetDrawablePixmap (pDrawable));
+ return exaPixmapHasGpuCopy(exaGetDrawablePixmap(pDrawable));
}
/**
@@ -266,16 +266,16 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable)
* coordinates to make them address the same bits in the backing drawable.
*/
PixmapPtr
-exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
+exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp)
{
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
- exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp);
+ exaGetDrawableDeltas(pDrawable, pPixmap, xp, yp);
- if (exaPixmapHasGpuCopy (pPixmap))
- return pPixmap;
+ if (exaPixmapHasGpuCopy(pPixmap))
+ return pPixmap;
else
- return NULL;
+ return NULL;
}
/**
@@ -285,46 +285,47 @@ Bool
ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ExaScreenPriv (pScreen);
+
+ ExaScreenPriv(pScreen);
ExaPixmapPriv(pPixmap);
Bool has_gpu_copy, ret;
int i;
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return FALSE;
+ return FALSE;
if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE);
+ EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE);
/* Handle repeated / nested calls. */
for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- pExaScr->access[i].count++;
- return pExaScr->access[i].retval;
- }
+ if (pExaScr->access[i].pixmap == pPixmap) {
+ pExaScr->access[i].count++;
+ return pExaScr->access[i].retval;
+ }
}
/* If slot for this index is taken, find an empty slot */
if (pExaScr->access[index].pixmap) {
- for (index = EXA_NUM_PREPARE_INDICES - 1; index >= 0; index--)
- if (!pExaScr->access[index].pixmap)
- break;
+ for (index = EXA_NUM_PREPARE_INDICES - 1; index >= 0; index--)
+ if (!pExaScr->access[index].pixmap)
+ break;
}
/* Access to this pixmap hasn't been prepared yet, so data pointer should be NULL. */
if (pPixmap->devPrivate.ptr != NULL) {
- EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n",
- pPixmap->devPrivate.ptr));
+ EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n", pPixmap->devPrivate.ptr));
}
has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
if (has_gpu_copy && pExaPixmap->fb_ptr) {
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- ret = TRUE;
- } else {
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- ret = FALSE;
+ pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ ret = TRUE;
+ }
+ else {
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ ret = FALSE;
}
/* Store so we can handle repeated / nested calls. */
@@ -332,34 +333,34 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index)
pExaScr->access[index].count = 1;
if (!has_gpu_copy)
- goto out;
+ goto out;
- exaWaitSync (pScreen);
+ exaWaitSync(pScreen);
if (pExaScr->info->PrepareAccess == NULL)
- goto out;
+ goto out;
if (index >= EXA_PREPARE_AUX_DEST &&
- !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
- FatalError("Unsupported AUX indices used on a pinned pixmap.\n");
- exaMoveOutPixmap (pPixmap);
- ret = FALSE;
- goto out;
+ !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
+ FatalError("Unsupported AUX indices used on a pinned pixmap.\n");
+ exaMoveOutPixmap(pPixmap);
+ ret = FALSE;
+ goto out;
}
if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
- if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED &&
- !(pExaScr->info->flags & EXA_MIXED_PIXMAPS))
- FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
- exaMoveOutPixmap (pPixmap);
- ret = FALSE;
- goto out;
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED &&
+ !(pExaScr->info->flags & EXA_MIXED_PIXMAPS))
+ FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
+ exaMoveOutPixmap(pPixmap);
+ ret = FALSE;
+ goto out;
}
ret = TRUE;
-out:
+ out:
pExaScr->access[index].retval = ret;
return ret;
}
@@ -374,12 +375,13 @@ void
exaPrepareAccess(DrawablePtr pDrawable, int index)
{
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
ExaScreenPriv(pDrawable->pScreen);
if (pExaScr->prepare_access_reg)
- pExaScr->prepare_access_reg(pPixmap, index, NULL);
+ pExaScr->prepare_access_reg(pPixmap, index, NULL);
else
- (void)ExaDoPrepareAccess(pPixmap, index);
+ (void) ExaDoPrepareAccess(pPixmap, index);
}
/**
@@ -390,31 +392,32 @@ exaPrepareAccess(DrawablePtr pDrawable, int index)
void
exaFinishAccess(DrawablePtr pDrawable, int index)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- ExaScreenPriv (pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
- ExaPixmapPriv (pPixmap);
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ ExaScreenPriv(pScreen);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ ExaPixmapPriv(pPixmap);
int i;
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
+ return;
if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),);
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),);
/* Handle repeated / nested calls. */
for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- if (--pExaScr->access[i].count > 0)
- return;
- break;
- }
+ if (pExaScr->access[i].pixmap == pPixmap) {
+ if (--pExaScr->access[i].count > 0)
+ return;
+ break;
+ }
}
/* Catch unbalanced Prepare/FinishAccess calls. */
if (i == EXA_NUM_PREPARE_INDICES)
- EXA_FatalErrorDebugWithRet(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n",
- pPixmap),);
+ EXA_FatalErrorDebugWithRet(("EXA bug: FinishAccess called without PrepareAccess for pixmap 0x%p.\n", pPixmap),);
pExaScr->access[i].pixmap = NULL;
@@ -423,19 +426,18 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
/* Only call FinishAccess if PrepareAccess was called and succeeded. */
if (!pExaScr->info->FinishAccess || !pExaScr->access[i].retval)
- return;
+ return;
if (i >= EXA_PREPARE_AUX_DEST &&
- !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
- ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
- "unsupported index EXA_PREPARE_AUX*\n");
- return;
+ !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) {
+ ErrorF("EXA bug: Trying to call driver FinishAccess hook with "
+ "unsupported index EXA_PREPARE_AUX*\n");
+ return;
}
(*pExaScr->info->FinishAccess) (pPixmap, i);
}
-
/**
* Helper for things common to all schemes when a pixmap is destroyed
*/
@@ -449,51 +451,42 @@ exaDestroyPixmap(PixmapPtr pPixmap)
* software fallback)
*/
for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) {
- if (pExaScr->access[i].pixmap == pPixmap) {
- exaFinishAccess(&pPixmap->drawable, i);
- pExaScr->access[i].pixmap = NULL;
- break;
- }
+ if (pExaScr->access[i].pixmap == pPixmap) {
+ exaFinishAccess(&pPixmap->drawable, i);
+ pExaScr->access[i].pixmap = NULL;
+ break;
+ }
}
}
-
/**
* Here begins EXA's GC code.
* Do not ever access the fb/mi layer directly.
*/
static void
-exaValidateGC(GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDrawable);
+ exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
static void
-exaDestroyGC(GCPtr pGC);
+ exaDestroyGC(GCPtr pGC);
static void
-exaChangeGC (GCPtr pGC,
- unsigned long mask);
+ exaChangeGC(GCPtr pGC, unsigned long mask);
static void
-exaCopyGC (GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst);
+ exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
static void
-exaChangeClip (GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects);
+ exaChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
static void
-exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+ exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
static void
-exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+ exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
static void
-exaDestroyClip(GCPtr pGC);
+ exaDestroyClip(GCPtr pGC);
const GCFuncs exaGCFuncs = {
exaValidateGC,
@@ -506,15 +499,14 @@ const GCFuncs exaGCFuncs = {
};
static void
-exaValidateGC(GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDrawable)
+exaValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
/* fbValidateGC will do direct access to pixmaps if the tiling has changed.
* Do a few smart things so fbValidateGC can do it's work.
*/
ScreenPtr pScreen = pDrawable->pScreen;
+
ExaScreenPriv(pScreen);
ExaGCPriv(pGC);
PixmapPtr pTile = NULL;
@@ -522,41 +514,45 @@ exaValidateGC(GCPtr pGC,
/* Either of these conditions is enough to trigger access to a tile pixmap. */
/* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */
- if (pGC->fillStyle == FillTiled || ((changes & GCTile) && !pGC->tileIsPixel)) {
- pTile = pGC->tile.pixmap;
-
- /* Sometimes tile pixmaps are swapped, you need access to:
- * - The current tile if it depth matches.
- * - Or the rotated tile if that one matches depth and !(changes & GCTile).
- * - Or the current tile pixmap and a newly created one.
- */
- if (pTile && pTile->drawable.depth != pDrawable->depth && !(changes & GCTile)) {
- PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
- if (pRotatedTile && pRotatedTile->drawable.depth == pDrawable->depth)
- pTile = pRotatedTile;
- else
- finish_current_tile = TRUE; /* CreatePixmap will be called. */
- }
+ if (pGC->fillStyle == FillTiled ||
+ ((changes & GCTile) && !pGC->tileIsPixel)) {
+ pTile = pGC->tile.pixmap;
+
+ /* Sometimes tile pixmaps are swapped, you need access to:
+ * - The current tile if it depth matches.
+ * - Or the rotated tile if that one matches depth and !(changes & GCTile).
+ * - Or the current tile pixmap and a newly created one.
+ */
+ if (pTile && pTile->drawable.depth != pDrawable->depth &&
+ !(changes & GCTile)) {
+ PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
+
+ if (pRotatedTile &&
+ pRotatedTile->drawable.depth == pDrawable->depth)
+ pTile = pRotatedTile;
+ else
+ finish_current_tile = TRUE; /* CreatePixmap will be called. */
+ }
}
if (pGC->stipple)
exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
if (pTile)
- exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
+ exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
/* Calls to Create/DestroyPixmap have to be identified as special. */
pExaScr->fallback_counter++;
swap(pExaGC, pGC, funcs);
- (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
swap(pExaGC, pGC, funcs);
pExaScr->fallback_counter--;
if (pTile)
- exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
if (finish_current_tile && pGC->tile.pixmap)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST);
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST);
if (pGC->stipple)
- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
}
/* Is exaPrepareAccessGC() needed? */
@@ -565,13 +561,12 @@ exaDestroyGC(GCPtr pGC)
{
ExaGCPriv(pGC);
swap(pExaGC, pGC, funcs);
- (*pGC->funcs->DestroyGC)(pGC);
+ (*pGC->funcs->DestroyGC) (pGC);
swap(pExaGC, pGC, funcs);
}
static void
-exaChangeGC (GCPtr pGC,
- unsigned long mask)
+exaChangeGC(GCPtr pGC, unsigned long mask)
{
ExaGCPriv(pGC);
swap(pExaGC, pGC, funcs);
@@ -580,9 +575,7 @@ exaChangeGC (GCPtr pGC,
}
static void
-exaCopyGC (GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst)
+exaCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
{
ExaGCPriv(pGCDst);
swap(pExaGC, pGCDst, funcs);
@@ -591,10 +584,7 @@ exaCopyGC (GCPtr pGCSrc,
}
static void
-exaChangeClip (GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects)
+exaChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
{
ExaGCPriv(pGC);
swap(pExaGC, pGC, funcs);
@@ -607,7 +597,7 @@ exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
{
ExaGCPriv(pGCDst);
swap(pExaGC, pGCDst, funcs);
- (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
+ (*pGCDst->funcs->CopyClip) (pGCDst, pGCSrc);
swap(pExaGC, pGCDst, funcs);
}
@@ -616,7 +606,7 @@ exaDestroyClip(GCPtr pGC)
{
ExaGCPriv(pGC);
swap(pExaGC, pGC, funcs);
- (*pGC->funcs->DestroyClip)(pGC);
+ (*pGC->funcs->DestroyClip) (pGC);
swap(pExaGC, pGC, funcs);
}
@@ -625,17 +615,18 @@ exaDestroyClip(GCPtr pGC)
* exaValidateGC() will get called.
*/
static int
-exaCreateGC (GCPtr pGC)
+exaCreateGC(GCPtr pGC)
{
ScreenPtr pScreen = pGC->pScreen;
+
ExaScreenPriv(pScreen);
ExaGCPriv(pGC);
Bool ret;
swap(pExaScr, pScreen, CreateGC);
if ((ret = (*pScreen->CreateGC) (pGC))) {
- wrap(pExaGC, pGC, funcs, (GCFuncs *) &exaGCFuncs);
- wrap(pExaGC, pGC, ops, (GCOps *) &exaOps);
+ wrap(pExaGC, pGC, funcs, (GCFuncs *) & exaGCFuncs);
+ wrap(pExaGC, pGC, ops, (GCOps *) & exaOps);
}
swap(pExaScr, pScreen, CreateGC);
@@ -647,13 +638,14 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
{
Bool ret;
ScreenPtr pScreen = pWin->drawable.pScreen;
+
ExaScreenPriv(pScreen);
- if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+ if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
+ exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+ exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
pExaScr->fallback_counter++;
swap(pExaScr, pScreen, ChangeWindowAttributes);
@@ -661,10 +653,10 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
swap(pExaScr, pScreen, ChangeWindowAttributes);
pExaScr->fallback_counter--;
- if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+ if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
+ exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+ exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
return ret;
}
@@ -674,11 +666,12 @@ exaBitmapToRegion(PixmapPtr pPix)
{
RegionPtr ret;
ScreenPtr pScreen = pPix->drawable.pScreen;
+
ExaScreenPriv(pScreen);
exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC);
swap(pExaScr, pScreen, BitmapToRegion);
- ret = (*pScreen->BitmapToRegion)(pPix);
+ ret = (*pScreen->BitmapToRegion) (pPix);
swap(pExaScr, pScreen, BitmapToRegion);
exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC);
@@ -715,14 +708,15 @@ exaCreateScreenResources(ScreenPtr pScreen)
static void
ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
- pointer pReadmask)
+ pointer pReadmask)
{
ScreenPtr pScreen = screenInfo.screens[screenNum];
+
ExaScreenPriv(pScreen);
/* Move any deferred results from a software fallback to the driver pixmap */
if (pExaScr->deferred_mixed_pixmap)
- exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
unwrap(pExaScr, pScreen, BlockHandler);
(*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
@@ -730,25 +724,26 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
/* The rest only applies to classic EXA */
if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
- return;
+ return;
/* Try and keep the offscreen memory area tidy every now and then (at most
* once per second) when the server has been idle for at least 100ms.
*/
if (pExaScr->numOffscreenAvailable > 1) {
- CARD32 now = GetTimeInMillis();
+ CARD32 now = GetTimeInMillis();
- pExaScr->nextDefragment = now +
- max(100, (INT32)(pExaScr->lastDefragment + 1000 - now));
- AdjustWaitForDelay(pTimeout, pExaScr->nextDefragment - now);
+ pExaScr->nextDefragment = now +
+ max(100, (INT32) (pExaScr->lastDefragment + 1000 - now));
+ AdjustWaitForDelay(pTimeout, pExaScr->nextDefragment - now);
}
}
static void
ExaWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
- pointer pReadmask)
+ pointer pReadmask)
{
ScreenPtr pScreen = screenInfo.screens[screenNum];
+
ExaScreenPriv(pScreen);
unwrap(pExaScr, pScreen, WakeupHandler);
@@ -756,12 +751,12 @@ ExaWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
if (result == 0 && pExaScr->numOffscreenAvailable > 1) {
- CARD32 now = GetTimeInMillis();
+ CARD32 now = GetTimeInMillis();
- if ((int)(now - pExaScr->nextDefragment) > 0) {
- ExaOffscreenDefragment(pScreen);
- pExaScr->lastDefragment = now;
- }
+ if ((int) (now - pExaScr->nextDefragment) > 0) {
+ ExaOffscreenDefragment(pScreen);
+ pExaScr->lastDefragment = now;
+ }
}
}
@@ -773,32 +768,32 @@ static Bool
exaCloseScreen(int i, ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
if (ps->Glyphs == exaGlyphs)
- exaGlyphsFini(pScreen);
+ exaGlyphsFini(pScreen);
if (pScreen->BlockHandler == ExaBlockHandler)
- unwrap(pExaScr, pScreen, BlockHandler);
+ unwrap(pExaScr, pScreen, BlockHandler);
if (pScreen->WakeupHandler == ExaWakeupHandler)
- unwrap(pExaScr, pScreen, WakeupHandler);
+ unwrap(pExaScr, pScreen, WakeupHandler);
unwrap(pExaScr, pScreen, CreateGC);
unwrap(pExaScr, pScreen, CloseScreen);
unwrap(pExaScr, pScreen, GetImage);
unwrap(pExaScr, pScreen, GetSpans);
if (pExaScr->SavedCreatePixmap)
- unwrap(pExaScr, pScreen, CreatePixmap);
+ unwrap(pExaScr, pScreen, CreatePixmap);
if (pExaScr->SavedDestroyPixmap)
- unwrap(pExaScr, pScreen, DestroyPixmap);
+ unwrap(pExaScr, pScreen, DestroyPixmap);
if (pExaScr->SavedModifyPixmapHeader)
- unwrap(pExaScr, pScreen, ModifyPixmapHeader);
+ unwrap(pExaScr, pScreen, ModifyPixmapHeader);
unwrap(pExaScr, pScreen, CopyWindow);
unwrap(pExaScr, pScreen, ChangeWindowAttributes);
unwrap(pExaScr, pScreen, BitmapToRegion);
unwrap(pExaScr, pScreen, CreateScreenResources);
unwrap(pExaScr, ps, Composite);
if (pExaScr->SavedGlyphs)
- unwrap(pExaScr, ps, Glyphs);
+ unwrap(pExaScr, ps, Glyphs);
unwrap(pExaScr, ps, Trapezoids);
unwrap(pExaScr, ps, Triangles);
unwrap(pExaScr, ps, AddTraps);
@@ -835,62 +830,60 @@ exaDriverAlloc(void)
* @return TRUE if EXA was successfully initialized.
*/
Bool
-exaDriverInit (ScreenPtr pScreen,
- ExaDriverPtr pScreenInfo)
+exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
{
ExaScreenPrivPtr pExaScr;
PictureScreenPtr ps;
if (!pScreenInfo)
- return FALSE;
+ return FALSE;
if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
- pScreenInfo->exa_minor > EXA_VERSION_MINOR)
- {
- LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements "
- "(%d.%d) are incompatible with EXA version (%d.%d)\n",
- pScreen->myNum,
- pScreenInfo->exa_major, pScreenInfo->exa_minor,
- EXA_VERSION_MAJOR, EXA_VERSION_MINOR);
- return FALSE;
+ pScreenInfo->exa_minor > EXA_VERSION_MINOR) {
+ LogMessage(X_ERROR, "EXA(%d): driver's EXA version requirements "
+ "(%d.%d) are incompatible with EXA version (%d.%d)\n",
+ pScreen->myNum,
+ pScreenInfo->exa_major, pScreenInfo->exa_minor,
+ EXA_VERSION_MAJOR, EXA_VERSION_MINOR);
+ return FALSE;
}
if (!pScreenInfo->CreatePixmap && !pScreenInfo->CreatePixmap2) {
- if (!pScreenInfo->memoryBase) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase "
- "must be non-zero\n", pScreen->myNum);
- return FALSE;
- }
-
- if (!pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
- "non-zero\n", pScreen->myNum);
- return FALSE;
- }
-
- if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
- "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
- return FALSE;
- }
+ if (!pScreenInfo->memoryBase) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase "
+ "must be non-zero\n", pScreen->myNum);
+ return FALSE;
+ }
+
+ if (!pScreenInfo->memorySize) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be "
+ "non-zero\n", pScreen->myNum);
+ return FALSE;
+ }
+
+ if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
+ "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
+ return FALSE;
+ }
}
if (!pScreenInfo->PrepareSolid) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be "
+ "non-NULL\n", pScreen->myNum);
+ return FALSE;
}
if (!pScreenInfo->PrepareCopy) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be "
+ "non-NULL\n", pScreen->myNum);
+ return FALSE;
}
if (!pScreenInfo->WaitMarker) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be "
- "non-NULL\n", pScreen->myNum);
- return FALSE;
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be "
+ "non-NULL\n", pScreen->myNum);
+ return FALSE;
}
/* If the driver doesn't set any max pitch values, we'll just assume
@@ -902,8 +895,7 @@ exaDriverInit (ScreenPtr pScreen,
* whether a pixmap is rejected because of its pitch or
* because of its width.
*/
- if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
- {
+ if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes) {
pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
}
@@ -911,15 +903,15 @@ exaDriverInit (ScreenPtr pScreen,
if (!dixRegisterPrivateKey(&exaScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) {
LogMessage(X_WARNING, "EXA(%d): Failed to register screen private\n",
- pScreen->myNum);
- return FALSE;
+ pScreen->myNum);
+ return FALSE;
}
- pExaScr = calloc (sizeof (ExaScreenPrivRec), 1);
+ pExaScr = calloc(sizeof(ExaScreenPrivRec), 1);
if (!pExaScr) {
LogMessage(X_WARNING, "EXA(%d): Failed to allocate screen private\n",
- pScreen->myNum);
- return FALSE;
+ pScreen->myNum);
+ return FALSE;
}
pExaScr->info = pScreenInfo;
@@ -930,23 +922,23 @@ exaDriverInit (ScreenPtr pScreen,
exaDDXDriverInit(pScreen);
- if (!dixRegisterPrivateKey(&exaGCPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
- LogMessage(X_WARNING,
- "EXA(%d): Failed to allocate GC private\n",
- pScreen->myNum);
- return FALSE;
+ if (!dixRegisterPrivateKey
+ (&exaGCPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
+ LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n",
+ pScreen->myNum);
+ return FALSE;
}
/*
* Replace various fb screen functions
*/
if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) ||
- (pExaScr->info->flags & EXA_MIXED_PIXMAPS)))
- wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
+ (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) ||
+ (pExaScr->info->flags & EXA_MIXED_PIXMAPS)))
+ wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
- wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
+ !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
+ wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
wrap(pExaScr, pScreen, CreateGC, exaCreateGC);
wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
wrap(pExaScr, pScreen, GetImage, exaGetImage);
@@ -957,15 +949,16 @@ exaDriverInit (ScreenPtr pScreen,
wrap(pExaScr, pScreen, CreateScreenResources, exaCreateScreenResources);
if (ps) {
- wrap(pExaScr, ps, Composite, exaComposite);
- if (pScreenInfo->PrepareComposite) {
- wrap(pExaScr, ps, Glyphs, exaGlyphs);
- } else {
- wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs);
- }
- wrap(pExaScr, ps, Trapezoids, exaTrapezoids);
- wrap(pExaScr, ps, Triangles, exaTriangles);
- wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps);
+ wrap(pExaScr, ps, Composite, exaComposite);
+ if (pScreenInfo->PrepareComposite) {
+ wrap(pExaScr, ps, Glyphs, exaGlyphs);
+ }
+ else {
+ wrap(pExaScr, ps, Glyphs, ExaCheckGlyphs);
+ }
+ wrap(pExaScr, ps, Trapezoids, exaTrapezoids);
+ wrap(pExaScr, ps, Triangles, exaTriangles);
+ wrap(pExaScr, ps, AddTraps, ExaCheckAddTraps);
}
#ifdef MITSHM
@@ -977,86 +970,95 @@ exaDriverInit (ScreenPtr pScreen,
/*
* Hookup offscreen pixmaps
*/
- if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
- {
- if (!dixRegisterPrivateKey(&exaPixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof(ExaPixmapPrivRec))) {
+ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
+ if (!dixRegisterPrivateKey
+ (&exaPixmapPrivateKeyRec, PRIVATE_PIXMAP,
+ sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
- "EXA(%d): Failed to allocate pixmap private\n",
- pScreen->myNum);
- return FALSE;
+ "EXA(%d): Failed to allocate pixmap private\n",
+ pScreen->myNum);
+ return FALSE;
+ }
+ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) {
+ if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) {
+ wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed);
+ wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed);
+ wrap(pExaScr, pScreen, ModifyPixmapHeader,
+ exaModifyPixmapHeader_mixed);
+ pExaScr->do_migration = exaDoMigration_mixed;
+ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed;
+ pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
+ pExaScr->do_move_out_pixmap = NULL;
+ pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
+ }
+ else {
+ wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
+ wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
+ wrap(pExaScr, pScreen, ModifyPixmapHeader,
+ exaModifyPixmapHeader_driver);
+ pExaScr->do_migration = NULL;
+ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver;
+ pExaScr->do_move_in_pixmap = NULL;
+ pExaScr->do_move_out_pixmap = NULL;
+ pExaScr->prepare_access_reg = NULL;
+ }
+ }
+ else {
+ wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
+ wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic);
+ wrap(pExaScr, pScreen, ModifyPixmapHeader,
+ exaModifyPixmapHeader_classic);
+ pExaScr->do_migration = exaDoMigration_classic;
+ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic;
+ pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
+ pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
+ pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
+ }
+ if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
+ LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
+ pScreen->myNum,
+ pExaScr->info->memorySize -
+ pExaScr->info->offScreenBase);
+ }
+ else {
+ LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
+ pScreen->myNum);
+
}
- if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) {
- if (pExaScr->info->flags & EXA_MIXED_PIXMAPS) {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_mixed);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed);
- wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_mixed);
- pExaScr->do_migration = exaDoMigration_mixed;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed;
- pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
- pExaScr->do_move_out_pixmap = NULL;
- pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
- } else {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
- wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_driver);
- pExaScr->do_migration = NULL;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver;
- pExaScr->do_move_in_pixmap = NULL;
- pExaScr->do_move_out_pixmap = NULL;
- pExaScr->prepare_access_reg = NULL;
- }
- } else {
- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic);
- wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_classic);
- pExaScr->do_migration = exaDoMigration_classic;
- pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic;
- pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
- pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
- pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
- }
- if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
- pScreen->myNum,
- pExaScr->info->memorySize - pExaScr->info->offScreenBase);
- } else {
- LogMessage(X_INFO, "EXA(%d): Driver allocated offscreen pixmaps\n",
- pScreen->myNum);
-
- }
}
else
LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
- pExaScr->info->memorySize));
- if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
- if (!exaOffscreenInit (pScreen)) {
- LogMessage(X_WARNING, "EXA(%d): Offscreen pixmap setup failed\n",
- pScreen->myNum);
- return FALSE;
- }
- }
+ DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
+ pExaScr->info->memorySize));
+ if (pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
+ if (!exaOffscreenInit(pScreen)) {
+ LogMessage(X_WARNING,
+ "EXA(%d): Offscreen pixmap setup failed\n",
+ pScreen->myNum);
+ return FALSE;
+ }
+ }
}
if (ps->Glyphs == exaGlyphs)
- exaGlyphsInit(pScreen);
+ exaGlyphsInit(pScreen);
LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"
- " operations:\n", pScreen->myNum);
+ " operations:\n", pScreen->myNum);
assert(pScreenInfo->PrepareSolid != NULL);
LogMessage(X_INFO, " Solid\n");
assert(pScreenInfo->PrepareCopy != NULL);
LogMessage(X_INFO, " Copy\n");
if (pScreenInfo->PrepareComposite != NULL) {
- LogMessage(X_INFO, " Composite (RENDER acceleration)\n");
+ LogMessage(X_INFO, " Composite (RENDER acceleration)\n");
}
if (pScreenInfo->UploadToScreen != NULL) {
- LogMessage(X_INFO, " UploadToScreen\n");
+ LogMessage(X_INFO, " UploadToScreen\n");
}
if (pScreenInfo->DownloadFromScreen != NULL) {
- LogMessage(X_INFO, " DownloadFromScreen\n");
+ LogMessage(X_INFO, " DownloadFromScreen\n");
}
return TRUE;
@@ -1068,9 +1070,9 @@ exaDriverInit (ScreenPtr pScreen,
* @param pScreen screen being torn down.
*/
void
-exaDriverFini (ScreenPtr pScreen)
+exaDriverFini(ScreenPtr pScreen)
{
- /*right now does nothing*/
+ /*right now does nothing */
}
/**
@@ -1084,13 +1086,14 @@ exaDriverFini (ScreenPtr pScreen)
* driver MarkSync() callback, the return value of which may be used to do partial
* synchronization with the hardware in the future.
*/
-void exaMarkSync(ScreenPtr pScreen)
+void
+exaMarkSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
pExaScr->info->needsSync = TRUE;
if (pExaScr->info->MarkSync != NULL) {
- pExaScr->info->lastMarker = (*pExaScr->info->MarkSync)(pScreen);
+ pExaScr->info->lastMarker = (*pExaScr->info->MarkSync) (pScreen);
}
}
@@ -1103,12 +1106,13 @@ void exaMarkSync(ScreenPtr pScreen)
* It should always be called before relying on the framebuffer contents
* reflecting previous drawing, from a CPU perspective.
*/
-void exaWaitSync(ScreenPtr pScreen)
+void
+exaWaitSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
if (pExaScr->info->needsSync && !pExaScr->swappedOut) {
- (*pExaScr->info->WaitMarker)(pScreen, pExaScr->info->lastMarker);
+ (*pExaScr->info->WaitMarker) (pScreen, pExaScr->info->lastMarker);
pExaScr->info->needsSync = FALSE;
}
}
@@ -1119,40 +1123,43 @@ void exaWaitSync(ScreenPtr pScreen)
* config file.
*/
void
-exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
+exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
{
ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
+
ExaScreenPriv(pScreen);
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
+ return;
if (pExaScr->do_migration)
- (*pExaScr->do_migration)(pixmaps, npixmaps, can_accel);
+ (*pExaScr->do_migration) (pixmaps, npixmaps, can_accel);
}
void
-exaMoveInPixmap (PixmapPtr pPixmap)
+exaMoveInPixmap(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
+ return;
if (pExaScr->do_move_in_pixmap)
- (*pExaScr->do_move_in_pixmap)(pPixmap);
+ (*pExaScr->do_move_in_pixmap) (pPixmap);
}
void
-exaMoveOutPixmap (PixmapPtr pPixmap)
+exaMoveOutPixmap(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
- return;
+ return;
if (pExaScr->do_move_out_pixmap)
- (*pExaScr->do_move_out_pixmap)(pPixmap);
+ (*pExaScr->do_move_out_pixmap) (pPixmap);
}
diff --git a/xorg-server/exa/exa.h b/xorg-server/exa/exa.h
index 3109607d8..75340021e 100644
--- a/xorg-server/exa/exa.h
+++ b/xorg-server/exa/exa.h
@@ -1,843 +1,816 @@
-/*
- *
- * Copyright (C) 2000 Keith Packard
- * 2004 Eric Anholt
- * 2005 Zack Rusin
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of copyright holders not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Copyright holders make no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/** @file
- * This is the header containing the public API of EXA for exa drivers.
- */
-
-#ifndef EXA_H
-#define EXA_H
-
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "gcstruct.h"
-#include "picturestr.h"
-#include "fb.h"
-
-#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 5
-#define EXA_VERSION_RELEASE 0
-
-typedef struct _ExaOffscreenArea ExaOffscreenArea;
-
-typedef void (*ExaOffscreenSaveProc) (ScreenPtr pScreen, ExaOffscreenArea *area);
-
-typedef enum _ExaOffscreenState {
- ExaOffscreenAvail,
- ExaOffscreenRemovable,
- ExaOffscreenLocked
-} ExaOffscreenState;
-
-struct _ExaOffscreenArea {
- int base_offset; /* allocation base */
- int offset; /* aligned offset */
- int size; /* total allocation size */
- unsigned last_use;
- pointer privData;
-
- ExaOffscreenSaveProc save;
-
- ExaOffscreenState state;
-
- ExaOffscreenArea *next;
-
- unsigned eviction_cost;
-
- ExaOffscreenArea *prev; /* Double-linked list for defragmentation */
- int align; /* required alignment */
-};
-
-/**
- * The ExaDriver structure is allocated through exaDriverAlloc(), and then
- * fllled in by drivers.
- */
-typedef struct _ExaDriver {
- /**
- * exa_major and exa_minor should be set by the driver to the version of
- * EXA which the driver was compiled for (or configures itself at runtime
- * to support). This allows EXA to extend the structure for new features
- * without breaking ABI for drivers compiled against older versions.
- */
- int exa_major, exa_minor;
-
- /**
- * memoryBase is the address of the beginning of framebuffer memory.
- * The visible screen should be within memoryBase to memoryBase +
- * memorySize.
- */
- CARD8 *memoryBase;
-
- /**
- * offScreenBase is the offset from memoryBase of the beginning of the area
- * to be managed by EXA's linear offscreen memory manager.
- *
- * In XFree86 DDX drivers, this is probably:
- * (pScrn->displayWidth * cpp * pScrn->virtualY)
- */
- unsigned long offScreenBase;
-
- /**
- * memorySize is the length (in bytes) of framebuffer memory beginning
- * from memoryBase.
- *
- * The offscreen memory manager will manage the area beginning at
- * (memoryBase + offScreenBase), with a length of (memorySize -
- * offScreenBase)
- *
- * In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024)
- */
- unsigned long memorySize;
-
- /**
- * pixmapOffsetAlign is the byte alignment necessary for pixmap offsets
- * within framebuffer.
- *
- * Hardware typically has a required alignment of offsets, which may or may
- * not be a power of two. EXA will ensure that pixmaps managed by the
- * offscreen memory manager meet this alignment requirement.
- */
- int pixmapOffsetAlign;
-
- /**
- * pixmapPitchAlign is the byte alignment necessary for pixmap pitches
- * within the framebuffer.
- *
- * Hardware typically has a required alignment of pitches for acceleration.
- * For 3D hardware, Composite acceleration often requires that source and
- * mask pixmaps (textures) have a power-of-two pitch, which can be demanded
- * using EXA_OFFSCREEN_ALIGN_POT. These pitch requirements only apply to
- * pixmaps managed by the offscreen memory manager. Thus, it is up to the
- * driver to ensure that the visible screen has an appropriate pitch for
- * acceleration.
- */
- int pixmapPitchAlign;
-
- /**
- * The flags field is bitfield of boolean values controlling EXA's behavior.
- *
- * The flags in clude EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and
- * EXA_TWO_BITBLT_DIRECTIONS.
- */
- int flags;
-
- /** @{ */
- /**
- * maxX controls the X coordinate limitation for rendering from the card.
- * The driver should never receive a request for rendering beyond maxX
- * in the X direction from the origin of a pixmap.
- */
- int maxX;
-
- /**
- * maxY controls the Y coordinate limitation for rendering from the card.
- * The driver should never receive a request for rendering beyond maxY
- * in the Y direction from the origin of a pixmap.
- */
- int maxY;
- /** @} */
-
- /* private */
- ExaOffscreenArea *offScreenAreas;
- Bool needsSync;
- int lastMarker;
-
- /** @name Solid
- * @{
- */
- /**
- * PrepareSolid() sets up the driver for doing a solid fill.
- * @param pPixmap Destination pixmap
- * @param alu raster operation
- * @param planemask write mask for the fill
- * @param fg "foreground" color for the fill
- *
- * This call should set up the driver for doing a series of solid fills
- * through the Solid() call. The alu raster op is one of the GX*
- * graphics functions listed in X.h, and typically maps to a similar
- * single-byte "ROP" setting in all hardware. The planemask controls
- * which bits of the destination should be affected, and will only represent
- * the bits up to the depth of pPixmap. The fg is the pixel value of the
- * foreground color referred to in ROP descriptions.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareSolid() call is required of all drivers, but it may fail for any
- * reason. Failure results in a fallback to software rendering.
- */
- Bool (*PrepareSolid) (PixmapPtr pPixmap,
- int alu,
- Pixel planemask,
- Pixel fg);
-
- /**
- * Solid() performs a solid fill set up in the last PrepareSolid() call.
- *
- * @param pPixmap destination pixmap
- * @param x1 left coordinate
- * @param y1 top coordinate
- * @param x2 right coordinate
- * @param y2 bottom coordinate
- *
- * Performs the fill set up by the last PrepareSolid() call, covering the
- * area from (x1,y1) to (x2,y2) in pPixmap. Note that the coordinates are
- * in the coordinate space of the destination pixmap, so the driver will
- * need to set up the hardware's offset and pitch for the destination
- * coordinates according to the pixmap's offset and pitch within
- * framebuffer. This likely means using exaGetPixmapOffset() and
- * exaGetPixmapPitch().
- *
- * This call is required if PrepareSolid() ever succeeds.
- */
- void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
-
- /**
- * DoneSolid() finishes a set of solid fills.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneSolid() call is called at the end of a series of consecutive
- * Solid() calls following a successful PrepareSolid(). This allows drivers
- * to finish up emitting drawing commands that were buffered, or clean up
- * state from PrepareSolid().
- *
- * This call is required if PrepareSolid() ever succeeds.
- */
- void (*DoneSolid) (PixmapPtr pPixmap);
- /** @} */
-
- /** @name Copy
- * @{
- */
- /**
- * PrepareCopy() sets up the driver for doing a copy within video
- * memory.
- *
- * @param pSrcPixmap source pixmap
- * @param pDstPixmap destination pixmap
- * @param dx X copy direction
- * @param dy Y copy direction
- * @param alu raster operation
- * @param planemask write mask for the fill
- *
- * This call should set up the driver for doing a series of copies from the
- * the pSrcPixmap to the pDstPixmap. The dx flag will be positive if the
- * hardware should do the copy from the left to the right, and dy will be
- * positive if the copy should be done from the top to the bottom. This
- * is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap.
- * If your hardware can only support blits that are (left to right, top to
- * bottom) or (right to left, bottom to top), then you should set
- * #EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to
- * ones that meet those requirements. The alu raster op is one of the GX*
- * graphics functions listed in X.h, and typically maps to a similar
- * single-byte "ROP" setting in all hardware. The planemask controls which
- * bits of the destination should be affected, and will only represent the
- * bits up to the depth of pPixmap.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareCopy() call is required of all drivers, but it may fail for any
- * reason. Failure results in a fallback to software rendering.
- */
- Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
- PixmapPtr pDstPixmap,
- int dx,
- int dy,
- int alu,
- Pixel planemask);
-
- /**
- * Copy() performs a copy set up in the last PrepareCopy call.
- *
- * @param pDstPixmap destination pixmap
- * @param srcX source X coordinate
- * @param srcY source Y coordinate
- * @param dstX destination X coordinate
- * @param dstY destination Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied.
- *
- * Performs the copy set up by the last PrepareCopy() call, copying the
- * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source
- * pixmap to the same-sized rectangle at (dstX, dstY) in the destination
- * pixmap. Those rectangles may overlap in memory, if
- * pSrcPixmap == pDstPixmap. Note that this call does not receive the
- * pSrcPixmap as an argument -- if it's needed in this function, it should
- * be stored in the driver private during PrepareCopy(). As with Solid(),
- * the coordinates are in the coordinate space of each pixmap, so the driver
- * will need to set up source and destination pitches and offsets from those
- * pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch().
- *
- * This call is required if PrepareCopy ever succeeds.
- */
- void (*Copy) (PixmapPtr pDstPixmap,
- int srcX,
- int srcY,
- int dstX,
- int dstY,
- int width,
- int height);
-
- /**
- * DoneCopy() finishes a set of copies.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneCopy() call is called at the end of a series of consecutive
- * Copy() calls following a successful PrepareCopy(). This allows drivers
- * to finish up emitting drawing commands that were buffered, or clean up
- * state from PrepareCopy().
- *
- * This call is required if PrepareCopy() ever succeeds.
- */
- void (*DoneCopy) (PixmapPtr pDstPixmap);
- /** @} */
-
- /** @name Composite
- * @{
- */
- /**
- * CheckComposite() checks to see if a composite operation could be
- * accelerated.
- *
- * @param op Render operation
- * @param pSrcPicture source Picture
- * @param pMaskPicture mask picture
- * @param pDstPicture destination Picture
- *
- * The CheckComposite() call checks if the driver could handle acceleration
- * of op with the given source, mask, and destination pictures. This allows
- * drivers to check source and destination formats, supported operations,
- * transformations, and component alpha state, and send operations it can't
- * support to software rendering early on. This avoids costly pixmap
- * migration to the wrong places when the driver can't accelerate
- * operations. Note that because migration hasn't happened, the driver
- * can't know during CheckComposite() what the offsets and pitches of the
- * pixmaps are going to be.
- *
- * See PrepareComposite() for more details on likely issues that drivers
- * will have in accelerating Composite operations.
- *
- * The CheckComposite() call is recommended if PrepareComposite() is
- * implemented, but is not required.
- */
- Bool (*CheckComposite) (int op,
- PicturePtr pSrcPicture,
- PicturePtr pMaskPicture,
- PicturePtr pDstPicture);
-
- /**
- * PrepareComposite() sets up the driver for doing a Composite operation
- * described in the Render extension protocol spec.
- *
- * @param op Render operation
- * @param pSrcPicture source Picture
- * @param pMaskPicture mask picture
- * @param pDstPicture destination Picture
- * @param pSrc source pixmap
- * @param pMask mask pixmap
- * @param pDst destination pixmap
- *
- * This call should set up the driver for doing a series of Composite
- * operations, as described in the Render protocol spec, with the given
- * pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and
- * pDst are the pixmaps containing the pixel data, and should be used for
- * setting the offset and pitch used for the coordinate spaces for each of
- * the Pictures.
- *
- * Notes on interpreting Picture structures:
- * - The Picture structures will always have a valid pDrawable.
- * - The Picture structures will never have alphaMap set.
- * - The mask Picture (and therefore pMask) may be NULL, in which case the
- * operation is simply src OP dst instead of src IN mask OP dst, and
- * mask coordinates should be ignored.
- * - pMarkPicture may have componentAlpha set, which greatly changes
- * the behavior of the Composite operation. componentAlpha has no effect
- * when set on pSrcPicture or pDstPicture.
- * - The source and mask Pictures may have a transformation set
- * (Picture->transform != NULL), which means that the source coordinates
- * should be transformed by that transformation, resulting in scaling,
- * rotation, etc. The PictureTransformPoint() call can transform
- * coordinates for you. Transforms have no effect on Pictures when used
- * as a destination.
- * - The source and mask pictures may have a filter set. PictFilterNearest
- * and PictFilterBilinear are defined in the Render protocol, but others
- * may be encountered, and must be handled correctly (usually by
- * PrepareComposite failing, and falling back to software). Filters have
- * no effect on Pictures when used as a destination.
- * - The source and mask Pictures may have repeating set, which must be
- * respected. Many chipsets will be unable to support repeating on
- * pixmaps that have a width or height that is not a power of two.
- *
- * If your hardware can't support source pictures (textures) with
- * non-power-of-two pitches, you should set #EXA_OFFSCREEN_ALIGN_POT.
- *
- * Note that many drivers will need to store some of the data in the driver
- * private record, for sending to the hardware with each drawing command.
- *
- * The PrepareComposite() call is not required. However, it is highly
- * recommended for performance of antialiased font rendering and performance
- * of cairo applications. Failure results in a fallback to software
- * rendering.
- */
- Bool (*PrepareComposite) (int op,
- PicturePtr pSrcPicture,
- PicturePtr pMaskPicture,
- PicturePtr pDstPicture,
- PixmapPtr pSrc,
- PixmapPtr pMask,
- PixmapPtr pDst);
-
- /**
- * Composite() performs a Composite operation set up in the last
- * PrepareComposite() call.
- *
- * @param pDstPixmap destination pixmap
- * @param srcX source X coordinate
- * @param srcY source Y coordinate
- * @param maskX source X coordinate
- * @param maskY source Y coordinate
- * @param dstX destination X coordinate
- * @param dstY destination Y coordinate
- * @param width destination rectangle width
- * @param height destination rectangle height
- *
- * Performs the Composite operation set up by the last PrepareComposite()
- * call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height)
- * in the destination Pixmap. Note that if a transformation was set on
- * the source or mask Pictures, the source rectangles may not be the same
- * size as the destination rectangles and filtering. Getting the coordinate
- * transformation right at the subpixel level can be tricky, and rendercheck
- * can test this for you.
- *
- * This call is required if PrepareComposite() ever succeeds.
- */
- void (*Composite) (PixmapPtr pDst,
- int srcX,
- int srcY,
- int maskX,
- int maskY,
- int dstX,
- int dstY,
- int width,
- int height);
-
- /**
- * DoneComposite() finishes a set of Composite operations.
- *
- * @param pPixmap destination pixmap.
- *
- * The DoneComposite() call is called at the end of a series of consecutive
- * Composite() calls following a successful PrepareComposite(). This allows
- * drivers to finish up emitting drawing commands that were buffered, or
- * clean up state from PrepareComposite().
- *
- * This call is required if PrepareComposite() ever succeeds.
- */
- void (*DoneComposite) (PixmapPtr pDst);
- /** @} */
-
- /**
- * UploadToScreen() loads a rectangle of data from src into pDst.
- *
- * @param pDst destination pixmap
- * @param x destination X coordinate.
- * @param y destination Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied
- * @param src pointer to the beginning of the source data
- * @param src_pitch pitch (in bytes) of the lines of source data.
- *
- * UploadToScreen() copies data in system memory beginning at src (with
- * pitch src_pitch) into the destination pixmap from (x, y) to
- * (x + width, y + height). This is typically done with hostdata uploads,
- * where the CPU sets up a blit command on the hardware with instructions
- * that the blit data will be fed through some sort of aperture on the card.
- *
- * If UploadToScreen() is performed asynchronously, it is up to the driver
- * to call exaMarkSync(). This is in contrast to most other acceleration
- * calls in EXA.
- *
- * UploadToScreen() can aid in pixmap migration, but is most important for
- * the performance of exaGlyphs() (antialiased font drawing) by allowing
- * pipelining of data uploads, avoiding a sync of the card after each glyph.
- *
- * @return TRUE if the driver successfully uploaded the data. FALSE
- * indicates that EXA should fall back to doing the upload in software.
- *
- * UploadToScreen() is not required, but is recommended if Composite
- * acceleration is supported.
- */
- Bool (*UploadToScreen) (PixmapPtr pDst,
- int x,
- int y,
- int w,
- int h,
- char *src,
- int src_pitch);
-
- /**
- * UploadToScratch() is no longer used and will be removed next time the EXA
- * major version needs to be bumped.
- */
- Bool (*UploadToScratch) (PixmapPtr pSrc,
- PixmapPtr pDst);
-
- /**
- * DownloadFromScreen() loads a rectangle of data from pSrc into dst
- *
- * @param pSrc source pixmap
- * @param x source X coordinate.
- * @param y source Y coordinate
- * @param width width of the rectangle to be copied
- * @param height height of the rectangle to be copied
- * @param dst pointer to the beginning of the destination data
- * @param dst_pitch pitch (in bytes) of the lines of destination data.
- *
- * DownloadFromScreen() copies data from offscreen memory in pSrc from
- * (x, y) to (x + width, y + height), to system memory starting at
- * dst (with pitch dst_pitch). This would usually be done
- * using scatter-gather DMA, supported by a DRM call, or by blitting to AGP
- * and then synchronously reading from AGP. Because the implementation
- * might be synchronous, EXA leaves it up to the driver to call
- * exaMarkSync() if DownloadFromScreen() was asynchronous. This is in
- * contrast to most other acceleration calls in EXA.
- *
- * DownloadFromScreen() can aid in the largest bottleneck in pixmap
- * migration, which is the read from framebuffer when evicting pixmaps from
- * framebuffer memory. Thus, it is highly recommended, even though
- * implementations are typically complicated.
- *
- * @return TRUE if the driver successfully downloaded the data. FALSE
- * indicates that EXA should fall back to doing the download in software.
- *
- * DownloadFromScreen() is not required, but is highly recommended.
- */
- Bool (*DownloadFromScreen)(PixmapPtr pSrc,
- int x, int y,
- int w, int h,
- char *dst, int dst_pitch);
-
- /**
- * MarkSync() requests that the driver mark a synchronization point,
- * returning an driver-defined integer marker which could be requested for
- * synchronization to later in WaitMarker(). This might be used in the
- * future to avoid waiting for full hardware stalls before accessing pixmap
- * data with the CPU, but is not important in the current incarnation of
- * EXA.
- *
- * Note that drivers should call exaMarkSync() when they have done some
- * acceleration, rather than their own MarkSync() handler, as otherwise EXA
- * will be unaware of the driver's acceleration and not sync to it during
- * fallbacks.
- *
- * MarkSync() is optional.
- */
- int (*MarkSync) (ScreenPtr pScreen);
-
- /**
- * WaitMarker() waits for all rendering before the given marker to have
- * completed. If the driver does not implement MarkSync(), marker is
- * meaningless, and all rendering by the hardware should be completed before
- * WaitMarker() returns.
- *
- * Note that drivers should call exaWaitSync() to wait for all acceleration
- * to finish, as otherwise EXA will be unaware of the driver having
- * synchronized, resulting in excessive WaitMarker() calls.
- *
- * WaitMarker() is required of all drivers.
- */
- void (*WaitMarker) (ScreenPtr pScreen, int marker);
-
- /** @{ */
- /**
- * PrepareAccess() is called before CPU access to an offscreen pixmap.
- *
- * @param pPix the pixmap being accessed
- * @param index the index of the pixmap being accessed.
- *
- * PrepareAccess() will be called before CPU access to an offscreen pixmap.
- * This can be used to set up hardware surfaces for byteswapping or
- * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
- * making CPU access use a different aperture.
- *
- * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC,
- * #EXA_PREPARE_MASK, #EXA_PREPARE_AUX_DEST, #EXA_PREPARE_AUX_SRC, or
- * #EXA_PREPARE_AUX_MASK. Since only up to #EXA_NUM_PREPARE_INDICES pixmaps
- * will have PrepareAccess() called on them per operation, drivers can have
- * a small, statically-allocated space to maintain state for PrepareAccess()
- * and FinishAccess() in. Note that PrepareAccess() is only called once per
- * pixmap and operation, regardless of whether the pixmap is used as a
- * destination and/or source, and the index may not reflect the usage.
- *
- * PrepareAccess() may fail. An example might be the case of hardware that
- * can set up 1 or 2 surfaces for CPU access, but not 3. If PrepareAccess()
- * fails, EXA will migrate the pixmap to system memory.
- * DownloadFromScreen() must be implemented and must not fail if a driver
- * wishes to fail in PrepareAccess(). PrepareAccess() must not fail when
- * pPix is the visible screen, because the visible screen can not be
- * migrated.
- *
- * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
- * drawing.
- * @return FALSE if PrepareAccess() is unsuccessful and EXA should use
- * DownloadFromScreen() to migate the pixmap out.
- */
- Bool (*PrepareAccess)(PixmapPtr pPix, int index);
-
- /**
- * FinishAccess() is called after CPU access to an offscreen pixmap.
- *
- * @param pPix the pixmap being accessed
- * @param index the index of the pixmap being accessed.
- *
- * FinishAccess() will be called after finishing CPU access of an offscreen
- * pixmap set up by PrepareAccess(). Note that the FinishAccess() will not be
- * called if PrepareAccess() failed and the pixmap was migrated out.
- */
- void (*FinishAccess)(PixmapPtr pPix, int index);
-
- /**
- * PixmapIsOffscreen() is an optional driver replacement to
- * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour
- * of exaPixmapHasGpuCopy().
- *
- * @param pPix the pixmap
- * @return TRUE if the given drawable is in framebuffer memory.
- *
- * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
- * memory, meaning that acceleration could probably be done to it, and that it
- * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
- * with the CPU.
- *
- *
- */
- Bool (*PixmapIsOffscreen)(PixmapPtr pPix);
-
- /** @name PrepareAccess() and FinishAccess() indices
- * @{
- */
- /**
- * EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or
- * read from.
- */
- #define EXA_PREPARE_DEST 0
- /**
- * EXA_PREPARE_SRC is the index for a pixmap that may be read from
- */
- #define EXA_PREPARE_SRC 1
- /**
- * EXA_PREPARE_SRC is the index for a second pixmap that may be read
- * from.
- */
- #define EXA_PREPARE_MASK 2
- /**
- * EXA_PREPARE_AUX* are additional indices for other purposes, e.g.
- * separate alpha maps with Composite operations.
- */
- #define EXA_PREPARE_AUX_DEST 3
- #define EXA_PREPARE_AUX_SRC 4
- #define EXA_PREPARE_AUX_MASK 5
- #define EXA_NUM_PREPARE_INDICES 6
- /** @} */
-
- /**
- * maxPitchPixels controls the pitch limitation for rendering from
- * the card.
- * The driver should never receive a request for rendering a pixmap
- * that has a pitch (in pixels) beyond maxPitchPixels.
- *
- * Setting this field is optional -- if your hardware doesn't have
- * a pitch limitation in pixels, don't set this. If neither this value
- * nor maxPitchBytes is set, then maxPitchPixels is set to maxX.
- * If set, it must not be smaller than maxX.
- *
- * @sa maxPitchBytes
- */
- int maxPitchPixels;
-
- /**
- * maxPitchBytes controls the pitch limitation for rendering from
- * the card.
- * The driver should never receive a request for rendering a pixmap
- * that has a pitch (in bytes) beyond maxPitchBytes.
- *
- * Setting this field is optional -- if your hardware doesn't have
- * a pitch limitation in bytes, don't set this.
- * If set, it must not be smaller than maxX * 4.
- * There's no default value for maxPitchBytes.
- *
- * @sa maxPitchPixels
- */
- int maxPitchBytes;
-
- /* Hooks to allow driver to its own pixmap memory management */
- void *(*CreatePixmap)(ScreenPtr pScreen, int size, int align);
- void (*DestroyPixmap)(ScreenPtr pScreen, void *driverPriv);
- /**
- * Returning a pixmap with non-NULL devPrivate.ptr implies a pixmap which is
- * not offscreen, which will never be accelerated and Prepare/FinishAccess won't
- * be called.
- */
- Bool (*ModifyPixmapHeader)(PixmapPtr pPixmap, int width, int height,
- int depth, int bitsPerPixel, int devKind,
- pointer pPixData);
-
- /* hooks for drivers with tiling support:
- * driver MUST fill out new_fb_pitch with valid pitch of pixmap
- */
- void *(*CreatePixmap2)(ScreenPtr pScreen, int width, int height,
- int depth, int usage_hint, int bitsPerPixel,
- int *new_fb_pitch);
- /** @} */
-} ExaDriverRec, *ExaDriverPtr;
-
-/** @name EXA driver flags
- * @{
- */
-/**
- * EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support
- * offscreen pixmaps.
- */
-#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
-
-/**
- * EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps
- * to have a power-of-two pitch.
- */
-#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
-
-/**
- * EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only
- * support copies that are (left-to-right, top-to-bottom) or
- * (right-to-left, bottom-to-top).
- */
-#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
-
-/**
- * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle
- * all pixmap addressing and migration.
- */
-#define EXA_HANDLES_PIXMAPS (1 << 3)
-
-/**
- * EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the
- * EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no
- * such hooks, this flag has no effect.
- */
-#define EXA_SUPPORTS_PREPARE_AUX (1 << 4)
-
-/**
- * EXA_SUPPORTS_OFFSCREEN_OVERLAPS indicates to EXA that the driver Copy hooks
- * can handle the source and destination occupying overlapping offscreen memory
- * areas. This allows the offscreen memory defragmentation code to defragment
- * areas where the defragmented position overlaps the fragmented position.
- *
- * Typically this is supported by traditional 2D engines but not by 3D engines.
- */
-#define EXA_SUPPORTS_OFFSCREEN_OVERLAPS (1 << 5)
-
-/**
- * EXA_MIXED_PIXMAPS will hide unacceleratable pixmaps from drivers and manage the
- * problem known software fallbacks like trapezoids. This only migrates pixmaps one way
- * into a driver pixmap and then pins it.
- */
-#define EXA_MIXED_PIXMAPS (1 << 6)
-
-/** @} */
-
-/* in exa.c */
-extern _X_EXPORT ExaDriverPtr
-exaDriverAlloc(void);
-
-extern _X_EXPORT Bool
-exaDriverInit(ScreenPtr pScreen,
- ExaDriverPtr pScreenInfo);
-
-extern _X_EXPORT void
-exaDriverFini(ScreenPtr pScreen);
-
-extern _X_EXPORT void
-exaMarkSync(ScreenPtr pScreen);
-extern _X_EXPORT void
-exaWaitSync(ScreenPtr pScreen);
-
-extern _X_EXPORT unsigned long
-exaGetPixmapOffset(PixmapPtr pPix);
-
-extern _X_EXPORT unsigned long
-exaGetPixmapPitch(PixmapPtr pPix);
-
-extern _X_EXPORT unsigned long
-exaGetPixmapSize(PixmapPtr pPix);
-
-extern _X_EXPORT void *
-exaGetPixmapDriverPrivate(PixmapPtr p);
-
-
-/* in exa_offscreen.c */
-extern _X_EXPORT ExaOffscreenArea *
-exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
- Bool locked,
- ExaOffscreenSaveProc save,
- pointer privData);
-
-extern _X_EXPORT ExaOffscreenArea *
-exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea *area);
-
-extern _X_EXPORT void
-ExaOffscreenMarkUsed (PixmapPtr pPixmap);
-
-extern _X_EXPORT void
-exaEnableDisableFBAccess (int index, Bool enable);
-
-extern _X_EXPORT Bool
-exaDrawableIsOffscreen (DrawablePtr pDrawable);
-
-/* in exa.c */
-extern _X_EXPORT void
-exaMoveInPixmap (PixmapPtr pPixmap);
-
-extern _X_EXPORT void
-exaMoveOutPixmap (PixmapPtr pPixmap);
-
-
-/* in exa_unaccel.c */
-extern _X_EXPORT CARD32
-exaGetPixmapFirstPixel (PixmapPtr pPixmap);
-
-
-/**
- * Returns TRUE if the given planemask covers all the significant bits in the
- * pixel values for pDrawable.
- */
-#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
- (((_pm) & FbFullMask((_pDrawable)->depth)) == \
- FbFullMask((_pDrawable)->depth))
-
-#endif /* EXA_H */
+/*
+ *
+ * Copyright (C) 2000 Keith Packard
+ * 2004 Eric Anholt
+ * 2005 Zack Rusin
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Copyright holders make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/** @file
+ * This is the header containing the public API of EXA for exa drivers.
+ */
+
+#ifndef EXA_H
+#define EXA_H
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "picturestr.h"
+#include "fb.h"
+
+#define EXA_VERSION_MAJOR 2
+#define EXA_VERSION_MINOR 5
+#define EXA_VERSION_RELEASE 0
+
+typedef struct _ExaOffscreenArea ExaOffscreenArea;
+
+typedef void (*ExaOffscreenSaveProc) (ScreenPtr pScreen,
+ ExaOffscreenArea * area);
+
+typedef enum _ExaOffscreenState {
+ ExaOffscreenAvail,
+ ExaOffscreenRemovable,
+ ExaOffscreenLocked
+} ExaOffscreenState;
+
+struct _ExaOffscreenArea {
+ int base_offset; /* allocation base */
+ int offset; /* aligned offset */
+ int size; /* total allocation size */
+ unsigned last_use;
+ pointer privData;
+
+ ExaOffscreenSaveProc save;
+
+ ExaOffscreenState state;
+
+ ExaOffscreenArea *next;
+
+ unsigned eviction_cost;
+
+ ExaOffscreenArea *prev; /* Double-linked list for defragmentation */
+ int align; /* required alignment */
+};
+
+/**
+ * The ExaDriver structure is allocated through exaDriverAlloc(), and then
+ * fllled in by drivers.
+ */
+typedef struct _ExaDriver {
+ /**
+ * exa_major and exa_minor should be set by the driver to the version of
+ * EXA which the driver was compiled for (or configures itself at runtime
+ * to support). This allows EXA to extend the structure for new features
+ * without breaking ABI for drivers compiled against older versions.
+ */
+ int exa_major, exa_minor;
+
+ /**
+ * memoryBase is the address of the beginning of framebuffer memory.
+ * The visible screen should be within memoryBase to memoryBase +
+ * memorySize.
+ */
+ CARD8 *memoryBase;
+
+ /**
+ * offScreenBase is the offset from memoryBase of the beginning of the area
+ * to be managed by EXA's linear offscreen memory manager.
+ *
+ * In XFree86 DDX drivers, this is probably:
+ * (pScrn->displayWidth * cpp * pScrn->virtualY)
+ */
+ unsigned long offScreenBase;
+
+ /**
+ * memorySize is the length (in bytes) of framebuffer memory beginning
+ * from memoryBase.
+ *
+ * The offscreen memory manager will manage the area beginning at
+ * (memoryBase + offScreenBase), with a length of (memorySize -
+ * offScreenBase)
+ *
+ * In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024)
+ */
+ unsigned long memorySize;
+
+ /**
+ * pixmapOffsetAlign is the byte alignment necessary for pixmap offsets
+ * within framebuffer.
+ *
+ * Hardware typically has a required alignment of offsets, which may or may
+ * not be a power of two. EXA will ensure that pixmaps managed by the
+ * offscreen memory manager meet this alignment requirement.
+ */
+ int pixmapOffsetAlign;
+
+ /**
+ * pixmapPitchAlign is the byte alignment necessary for pixmap pitches
+ * within the framebuffer.
+ *
+ * Hardware typically has a required alignment of pitches for acceleration.
+ * For 3D hardware, Composite acceleration often requires that source and
+ * mask pixmaps (textures) have a power-of-two pitch, which can be demanded
+ * using EXA_OFFSCREEN_ALIGN_POT. These pitch requirements only apply to
+ * pixmaps managed by the offscreen memory manager. Thus, it is up to the
+ * driver to ensure that the visible screen has an appropriate pitch for
+ * acceleration.
+ */
+ int pixmapPitchAlign;
+
+ /**
+ * The flags field is bitfield of boolean values controlling EXA's behavior.
+ *
+ * The flags in clude EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and
+ * EXA_TWO_BITBLT_DIRECTIONS.
+ */
+ int flags;
+
+ /** @{ */
+ /**
+ * maxX controls the X coordinate limitation for rendering from the card.
+ * The driver should never receive a request for rendering beyond maxX
+ * in the X direction from the origin of a pixmap.
+ */
+ int maxX;
+
+ /**
+ * maxY controls the Y coordinate limitation for rendering from the card.
+ * The driver should never receive a request for rendering beyond maxY
+ * in the Y direction from the origin of a pixmap.
+ */
+ int maxY;
+ /** @} */
+
+ /* private */
+ ExaOffscreenArea *offScreenAreas;
+ Bool needsSync;
+ int lastMarker;
+
+ /** @name Solid
+ * @{
+ */
+ /**
+ * PrepareSolid() sets up the driver for doing a solid fill.
+ * @param pPixmap Destination pixmap
+ * @param alu raster operation
+ * @param planemask write mask for the fill
+ * @param fg "foreground" color for the fill
+ *
+ * This call should set up the driver for doing a series of solid fills
+ * through the Solid() call. The alu raster op is one of the GX*
+ * graphics functions listed in X.h, and typically maps to a similar
+ * single-byte "ROP" setting in all hardware. The planemask controls
+ * which bits of the destination should be affected, and will only represent
+ * the bits up to the depth of pPixmap. The fg is the pixel value of the
+ * foreground color referred to in ROP descriptions.
+ *
+ * Note that many drivers will need to store some of the data in the driver
+ * private record, for sending to the hardware with each drawing command.
+ *
+ * The PrepareSolid() call is required of all drivers, but it may fail for any
+ * reason. Failure results in a fallback to software rendering.
+ */
+ Bool (*PrepareSolid) (PixmapPtr pPixmap,
+ int alu, Pixel planemask, Pixel fg);
+
+ /**
+ * Solid() performs a solid fill set up in the last PrepareSolid() call.
+ *
+ * @param pPixmap destination pixmap
+ * @param x1 left coordinate
+ * @param y1 top coordinate
+ * @param x2 right coordinate
+ * @param y2 bottom coordinate
+ *
+ * Performs the fill set up by the last PrepareSolid() call, covering the
+ * area from (x1,y1) to (x2,y2) in pPixmap. Note that the coordinates are
+ * in the coordinate space of the destination pixmap, so the driver will
+ * need to set up the hardware's offset and pitch for the destination
+ * coordinates according to the pixmap's offset and pitch within
+ * framebuffer. This likely means using exaGetPixmapOffset() and
+ * exaGetPixmapPitch().
+ *
+ * This call is required if PrepareSolid() ever succeeds.
+ */
+ void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
+
+ /**
+ * DoneSolid() finishes a set of solid fills.
+ *
+ * @param pPixmap destination pixmap.
+ *
+ * The DoneSolid() call is called at the end of a series of consecutive
+ * Solid() calls following a successful PrepareSolid(). This allows drivers
+ * to finish up emitting drawing commands that were buffered, or clean up
+ * state from PrepareSolid().
+ *
+ * This call is required if PrepareSolid() ever succeeds.
+ */
+ void (*DoneSolid) (PixmapPtr pPixmap);
+ /** @} */
+
+ /** @name Copy
+ * @{
+ */
+ /**
+ * PrepareCopy() sets up the driver for doing a copy within video
+ * memory.
+ *
+ * @param pSrcPixmap source pixmap
+ * @param pDstPixmap destination pixmap
+ * @param dx X copy direction
+ * @param dy Y copy direction
+ * @param alu raster operation
+ * @param planemask write mask for the fill
+ *
+ * This call should set up the driver for doing a series of copies from the
+ * the pSrcPixmap to the pDstPixmap. The dx flag will be positive if the
+ * hardware should do the copy from the left to the right, and dy will be
+ * positive if the copy should be done from the top to the bottom. This
+ * is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap.
+ * If your hardware can only support blits that are (left to right, top to
+ * bottom) or (right to left, bottom to top), then you should set
+ * #EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to
+ * ones that meet those requirements. The alu raster op is one of the GX*
+ * graphics functions listed in X.h, and typically maps to a similar
+ * single-byte "ROP" setting in all hardware. The planemask controls which
+ * bits of the destination should be affected, and will only represent the
+ * bits up to the depth of pPixmap.
+ *
+ * Note that many drivers will need to store some of the data in the driver
+ * private record, for sending to the hardware with each drawing command.
+ *
+ * The PrepareCopy() call is required of all drivers, but it may fail for any
+ * reason. Failure results in a fallback to software rendering.
+ */
+ Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
+ PixmapPtr pDstPixmap,
+ int dx, int dy, int alu, Pixel planemask);
+
+ /**
+ * Copy() performs a copy set up in the last PrepareCopy call.
+ *
+ * @param pDstPixmap destination pixmap
+ * @param srcX source X coordinate
+ * @param srcY source Y coordinate
+ * @param dstX destination X coordinate
+ * @param dstY destination Y coordinate
+ * @param width width of the rectangle to be copied
+ * @param height height of the rectangle to be copied.
+ *
+ * Performs the copy set up by the last PrepareCopy() call, copying the
+ * rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source
+ * pixmap to the same-sized rectangle at (dstX, dstY) in the destination
+ * pixmap. Those rectangles may overlap in memory, if
+ * pSrcPixmap == pDstPixmap. Note that this call does not receive the
+ * pSrcPixmap as an argument -- if it's needed in this function, it should
+ * be stored in the driver private during PrepareCopy(). As with Solid(),
+ * the coordinates are in the coordinate space of each pixmap, so the driver
+ * will need to set up source and destination pitches and offsets from those
+ * pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch().
+ *
+ * This call is required if PrepareCopy ever succeeds.
+ */
+ void (*Copy) (PixmapPtr pDstPixmap,
+ int srcX,
+ int srcY, int dstX, int dstY, int width, int height);
+
+ /**
+ * DoneCopy() finishes a set of copies.
+ *
+ * @param pPixmap destination pixmap.
+ *
+ * The DoneCopy() call is called at the end of a series of consecutive
+ * Copy() calls following a successful PrepareCopy(). This allows drivers
+ * to finish up emitting drawing commands that were buffered, or clean up
+ * state from PrepareCopy().
+ *
+ * This call is required if PrepareCopy() ever succeeds.
+ */
+ void (*DoneCopy) (PixmapPtr pDstPixmap);
+ /** @} */
+
+ /** @name Composite
+ * @{
+ */
+ /**
+ * CheckComposite() checks to see if a composite operation could be
+ * accelerated.
+ *
+ * @param op Render operation
+ * @param pSrcPicture source Picture
+ * @param pMaskPicture mask picture
+ * @param pDstPicture destination Picture
+ *
+ * The CheckComposite() call checks if the driver could handle acceleration
+ * of op with the given source, mask, and destination pictures. This allows
+ * drivers to check source and destination formats, supported operations,
+ * transformations, and component alpha state, and send operations it can't
+ * support to software rendering early on. This avoids costly pixmap
+ * migration to the wrong places when the driver can't accelerate
+ * operations. Note that because migration hasn't happened, the driver
+ * can't know during CheckComposite() what the offsets and pitches of the
+ * pixmaps are going to be.
+ *
+ * See PrepareComposite() for more details on likely issues that drivers
+ * will have in accelerating Composite operations.
+ *
+ * The CheckComposite() call is recommended if PrepareComposite() is
+ * implemented, but is not required.
+ */
+ Bool (*CheckComposite) (int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture, PicturePtr pDstPicture);
+
+ /**
+ * PrepareComposite() sets up the driver for doing a Composite operation
+ * described in the Render extension protocol spec.
+ *
+ * @param op Render operation
+ * @param pSrcPicture source Picture
+ * @param pMaskPicture mask picture
+ * @param pDstPicture destination Picture
+ * @param pSrc source pixmap
+ * @param pMask mask pixmap
+ * @param pDst destination pixmap
+ *
+ * This call should set up the driver for doing a series of Composite
+ * operations, as described in the Render protocol spec, with the given
+ * pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and
+ * pDst are the pixmaps containing the pixel data, and should be used for
+ * setting the offset and pitch used for the coordinate spaces for each of
+ * the Pictures.
+ *
+ * Notes on interpreting Picture structures:
+ * - The Picture structures will always have a valid pDrawable.
+ * - The Picture structures will never have alphaMap set.
+ * - The mask Picture (and therefore pMask) may be NULL, in which case the
+ * operation is simply src OP dst instead of src IN mask OP dst, and
+ * mask coordinates should be ignored.
+ * - pMarkPicture may have componentAlpha set, which greatly changes
+ * the behavior of the Composite operation. componentAlpha has no effect
+ * when set on pSrcPicture or pDstPicture.
+ * - The source and mask Pictures may have a transformation set
+ * (Picture->transform != NULL), which means that the source coordinates
+ * should be transformed by that transformation, resulting in scaling,
+ * rotation, etc. The PictureTransformPoint() call can transform
+ * coordinates for you. Transforms have no effect on Pictures when used
+ * as a destination.
+ * - The source and mask pictures may have a filter set. PictFilterNearest
+ * and PictFilterBilinear are defined in the Render protocol, but others
+ * may be encountered, and must be handled correctly (usually by
+ * PrepareComposite failing, and falling back to software). Filters have
+ * no effect on Pictures when used as a destination.
+ * - The source and mask Pictures may have repeating set, which must be
+ * respected. Many chipsets will be unable to support repeating on
+ * pixmaps that have a width or height that is not a power of two.
+ *
+ * If your hardware can't support source pictures (textures) with
+ * non-power-of-two pitches, you should set #EXA_OFFSCREEN_ALIGN_POT.
+ *
+ * Note that many drivers will need to store some of the data in the driver
+ * private record, for sending to the hardware with each drawing command.
+ *
+ * The PrepareComposite() call is not required. However, it is highly
+ * recommended for performance of antialiased font rendering and performance
+ * of cairo applications. Failure results in a fallback to software
+ * rendering.
+ */
+ Bool (*PrepareComposite) (int op,
+ PicturePtr pSrcPicture,
+ PicturePtr pMaskPicture,
+ PicturePtr pDstPicture,
+ PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
+
+ /**
+ * Composite() performs a Composite operation set up in the last
+ * PrepareComposite() call.
+ *
+ * @param pDstPixmap destination pixmap
+ * @param srcX source X coordinate
+ * @param srcY source Y coordinate
+ * @param maskX source X coordinate
+ * @param maskY source Y coordinate
+ * @param dstX destination X coordinate
+ * @param dstY destination Y coordinate
+ * @param width destination rectangle width
+ * @param height destination rectangle height
+ *
+ * Performs the Composite operation set up by the last PrepareComposite()
+ * call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height)
+ * in the destination Pixmap. Note that if a transformation was set on
+ * the source or mask Pictures, the source rectangles may not be the same
+ * size as the destination rectangles and filtering. Getting the coordinate
+ * transformation right at the subpixel level can be tricky, and rendercheck
+ * can test this for you.
+ *
+ * This call is required if PrepareComposite() ever succeeds.
+ */
+ void (*Composite) (PixmapPtr pDst,
+ int srcX,
+ int srcY,
+ int maskX,
+ int maskY, int dstX, int dstY, int width, int height);
+
+ /**
+ * DoneComposite() finishes a set of Composite operations.
+ *
+ * @param pPixmap destination pixmap.
+ *
+ * The DoneComposite() call is called at the end of a series of consecutive
+ * Composite() calls following a successful PrepareComposite(). This allows
+ * drivers to finish up emitting drawing commands that were buffered, or
+ * clean up state from PrepareComposite().
+ *
+ * This call is required if PrepareComposite() ever succeeds.
+ */
+ void (*DoneComposite) (PixmapPtr pDst);
+ /** @} */
+
+ /**
+ * UploadToScreen() loads a rectangle of data from src into pDst.
+ *
+ * @param pDst destination pixmap
+ * @param x destination X coordinate.
+ * @param y destination Y coordinate
+ * @param width width of the rectangle to be copied
+ * @param height height of the rectangle to be copied
+ * @param src pointer to the beginning of the source data
+ * @param src_pitch pitch (in bytes) of the lines of source data.
+ *
+ * UploadToScreen() copies data in system memory beginning at src (with
+ * pitch src_pitch) into the destination pixmap from (x, y) to
+ * (x + width, y + height). This is typically done with hostdata uploads,
+ * where the CPU sets up a blit command on the hardware with instructions
+ * that the blit data will be fed through some sort of aperture on the card.
+ *
+ * If UploadToScreen() is performed asynchronously, it is up to the driver
+ * to call exaMarkSync(). This is in contrast to most other acceleration
+ * calls in EXA.
+ *
+ * UploadToScreen() can aid in pixmap migration, but is most important for
+ * the performance of exaGlyphs() (antialiased font drawing) by allowing
+ * pipelining of data uploads, avoiding a sync of the card after each glyph.
+ *
+ * @return TRUE if the driver successfully uploaded the data. FALSE
+ * indicates that EXA should fall back to doing the upload in software.
+ *
+ * UploadToScreen() is not required, but is recommended if Composite
+ * acceleration is supported.
+ */
+ Bool (*UploadToScreen) (PixmapPtr pDst,
+ int x,
+ int y, int w, int h, char *src, int src_pitch);
+
+ /**
+ * UploadToScratch() is no longer used and will be removed next time the EXA
+ * major version needs to be bumped.
+ */
+ Bool (*UploadToScratch) (PixmapPtr pSrc, PixmapPtr pDst);
+
+ /**
+ * DownloadFromScreen() loads a rectangle of data from pSrc into dst
+ *
+ * @param pSrc source pixmap
+ * @param x source X coordinate.
+ * @param y source Y coordinate
+ * @param width width of the rectangle to be copied
+ * @param height height of the rectangle to be copied
+ * @param dst pointer to the beginning of the destination data
+ * @param dst_pitch pitch (in bytes) of the lines of destination data.
+ *
+ * DownloadFromScreen() copies data from offscreen memory in pSrc from
+ * (x, y) to (x + width, y + height), to system memory starting at
+ * dst (with pitch dst_pitch). This would usually be done
+ * using scatter-gather DMA, supported by a DRM call, or by blitting to AGP
+ * and then synchronously reading from AGP. Because the implementation
+ * might be synchronous, EXA leaves it up to the driver to call
+ * exaMarkSync() if DownloadFromScreen() was asynchronous. This is in
+ * contrast to most other acceleration calls in EXA.
+ *
+ * DownloadFromScreen() can aid in the largest bottleneck in pixmap
+ * migration, which is the read from framebuffer when evicting pixmaps from
+ * framebuffer memory. Thus, it is highly recommended, even though
+ * implementations are typically complicated.
+ *
+ * @return TRUE if the driver successfully downloaded the data. FALSE
+ * indicates that EXA should fall back to doing the download in software.
+ *
+ * DownloadFromScreen() is not required, but is highly recommended.
+ */
+ Bool (*DownloadFromScreen) (PixmapPtr pSrc,
+ int x, int y,
+ int w, int h, char *dst, int dst_pitch);
+
+ /**
+ * MarkSync() requests that the driver mark a synchronization point,
+ * returning an driver-defined integer marker which could be requested for
+ * synchronization to later in WaitMarker(). This might be used in the
+ * future to avoid waiting for full hardware stalls before accessing pixmap
+ * data with the CPU, but is not important in the current incarnation of
+ * EXA.
+ *
+ * Note that drivers should call exaMarkSync() when they have done some
+ * acceleration, rather than their own MarkSync() handler, as otherwise EXA
+ * will be unaware of the driver's acceleration and not sync to it during
+ * fallbacks.
+ *
+ * MarkSync() is optional.
+ */
+ int (*MarkSync) (ScreenPtr pScreen);
+
+ /**
+ * WaitMarker() waits for all rendering before the given marker to have
+ * completed. If the driver does not implement MarkSync(), marker is
+ * meaningless, and all rendering by the hardware should be completed before
+ * WaitMarker() returns.
+ *
+ * Note that drivers should call exaWaitSync() to wait for all acceleration
+ * to finish, as otherwise EXA will be unaware of the driver having
+ * synchronized, resulting in excessive WaitMarker() calls.
+ *
+ * WaitMarker() is required of all drivers.
+ */
+ void (*WaitMarker) (ScreenPtr pScreen, int marker);
+
+ /** @{ */
+ /**
+ * PrepareAccess() is called before CPU access to an offscreen pixmap.
+ *
+ * @param pPix the pixmap being accessed
+ * @param index the index of the pixmap being accessed.
+ *
+ * PrepareAccess() will be called before CPU access to an offscreen pixmap.
+ * This can be used to set up hardware surfaces for byteswapping or
+ * untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
+ * making CPU access use a different aperture.
+ *
+ * The index is one of #EXA_PREPARE_DEST, #EXA_PREPARE_SRC,
+ * #EXA_PREPARE_MASK, #EXA_PREPARE_AUX_DEST, #EXA_PREPARE_AUX_SRC, or
+ * #EXA_PREPARE_AUX_MASK. Since only up to #EXA_NUM_PREPARE_INDICES pixmaps
+ * will have PrepareAccess() called on them per operation, drivers can have
+ * a small, statically-allocated space to maintain state for PrepareAccess()
+ * and FinishAccess() in. Note that PrepareAccess() is only called once per
+ * pixmap and operation, regardless of whether the pixmap is used as a
+ * destination and/or source, and the index may not reflect the usage.
+ *
+ * PrepareAccess() may fail. An example might be the case of hardware that
+ * can set up 1 or 2 surfaces for CPU access, but not 3. If PrepareAccess()
+ * fails, EXA will migrate the pixmap to system memory.
+ * DownloadFromScreen() must be implemented and must not fail if a driver
+ * wishes to fail in PrepareAccess(). PrepareAccess() must not fail when
+ * pPix is the visible screen, because the visible screen can not be
+ * migrated.
+ *
+ * @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
+ * drawing.
+ * @return FALSE if PrepareAccess() is unsuccessful and EXA should use
+ * DownloadFromScreen() to migate the pixmap out.
+ */
+ Bool (*PrepareAccess) (PixmapPtr pPix, int index);
+
+ /**
+ * FinishAccess() is called after CPU access to an offscreen pixmap.
+ *
+ * @param pPix the pixmap being accessed
+ * @param index the index of the pixmap being accessed.
+ *
+ * FinishAccess() will be called after finishing CPU access of an offscreen
+ * pixmap set up by PrepareAccess(). Note that the FinishAccess() will not be
+ * called if PrepareAccess() failed and the pixmap was migrated out.
+ */
+ void (*FinishAccess) (PixmapPtr pPix, int index);
+
+ /**
+ * PixmapIsOffscreen() is an optional driver replacement to
+ * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour
+ * of exaPixmapHasGpuCopy().
+ *
+ * @param pPix the pixmap
+ * @return TRUE if the given drawable is in framebuffer memory.
+ *
+ * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen
+ * memory, meaning that acceleration could probably be done to it, and that it
+ * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it
+ * with the CPU.
+ *
+ *
+ */
+ Bool (*PixmapIsOffscreen) (PixmapPtr pPix);
+
+ /** @name PrepareAccess() and FinishAccess() indices
+ * @{
+ */
+ /**
+ * EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or
+ * read from.
+ */
+#define EXA_PREPARE_DEST 0
+ /**
+ * EXA_PREPARE_SRC is the index for a pixmap that may be read from
+ */
+#define EXA_PREPARE_SRC 1
+ /**
+ * EXA_PREPARE_SRC is the index for a second pixmap that may be read
+ * from.
+ */
+#define EXA_PREPARE_MASK 2
+ /**
+ * EXA_PREPARE_AUX* are additional indices for other purposes, e.g.
+ * separate alpha maps with Composite operations.
+ */
+#define EXA_PREPARE_AUX_DEST 3
+#define EXA_PREPARE_AUX_SRC 4
+#define EXA_PREPARE_AUX_MASK 5
+#define EXA_NUM_PREPARE_INDICES 6
+ /** @} */
+
+ /**
+ * maxPitchPixels controls the pitch limitation for rendering from
+ * the card.
+ * The driver should never receive a request for rendering a pixmap
+ * that has a pitch (in pixels) beyond maxPitchPixels.
+ *
+ * Setting this field is optional -- if your hardware doesn't have
+ * a pitch limitation in pixels, don't set this. If neither this value
+ * nor maxPitchBytes is set, then maxPitchPixels is set to maxX.
+ * If set, it must not be smaller than maxX.
+ *
+ * @sa maxPitchBytes
+ */
+ int maxPitchPixels;
+
+ /**
+ * maxPitchBytes controls the pitch limitation for rendering from
+ * the card.
+ * The driver should never receive a request for rendering a pixmap
+ * that has a pitch (in bytes) beyond maxPitchBytes.
+ *
+ * Setting this field is optional -- if your hardware doesn't have
+ * a pitch limitation in bytes, don't set this.
+ * If set, it must not be smaller than maxX * 4.
+ * There's no default value for maxPitchBytes.
+ *
+ * @sa maxPitchPixels
+ */
+ int maxPitchBytes;
+
+ /* Hooks to allow driver to its own pixmap memory management */
+ void *(*CreatePixmap) (ScreenPtr pScreen, int size, int align);
+ void (*DestroyPixmap) (ScreenPtr pScreen, void *driverPriv);
+ /**
+ * Returning a pixmap with non-NULL devPrivate.ptr implies a pixmap which is
+ * not offscreen, which will never be accelerated and Prepare/FinishAccess won't
+ * be called.
+ */
+ Bool (*ModifyPixmapHeader) (PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData);
+
+ /* hooks for drivers with tiling support:
+ * driver MUST fill out new_fb_pitch with valid pitch of pixmap
+ */
+ void *(*CreatePixmap2) (ScreenPtr pScreen, int width, int height,
+ int depth, int usage_hint, int bitsPerPixel,
+ int *new_fb_pitch);
+ /** @} */
+} ExaDriverRec, *ExaDriverPtr;
+
+/** @name EXA driver flags
+ * @{
+ */
+/**
+ * EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support
+ * offscreen pixmaps.
+ */
+#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
+
+/**
+ * EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps
+ * to have a power-of-two pitch.
+ */
+#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
+
+/**
+ * EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only
+ * support copies that are (left-to-right, top-to-bottom) or
+ * (right-to-left, bottom-to-top).
+ */
+#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
+
+/**
+ * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle
+ * all pixmap addressing and migration.
+ */
+#define EXA_HANDLES_PIXMAPS (1 << 3)
+
+/**
+ * EXA_SUPPORTS_PREPARE_AUX indicates to EXA that the driver can handle the
+ * EXA_PREPARE_AUX* indices in the Prepare/FinishAccess hooks. If there are no
+ * such hooks, this flag has no effect.
+ */
+#define EXA_SUPPORTS_PREPARE_AUX (1 << 4)
+
+/**
+ * EXA_SUPPORTS_OFFSCREEN_OVERLAPS indicates to EXA that the driver Copy hooks
+ * can handle the source and destination occupying overlapping offscreen memory
+ * areas. This allows the offscreen memory defragmentation code to defragment
+ * areas where the defragmented position overlaps the fragmented position.
+ *
+ * Typically this is supported by traditional 2D engines but not by 3D engines.
+ */
+#define EXA_SUPPORTS_OFFSCREEN_OVERLAPS (1 << 5)
+
+/**
+ * EXA_MIXED_PIXMAPS will hide unacceleratable pixmaps from drivers and manage the
+ * problem known software fallbacks like trapezoids. This only migrates pixmaps one way
+ * into a driver pixmap and then pins it.
+ */
+#define EXA_MIXED_PIXMAPS (1 << 6)
+
+/** @} */
+
+/* in exa.c */
+extern _X_EXPORT ExaDriverPtr exaDriverAlloc(void);
+
+extern _X_EXPORT Bool
+ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo);
+
+extern _X_EXPORT void
+ exaDriverFini(ScreenPtr pScreen);
+
+extern _X_EXPORT void
+ exaMarkSync(ScreenPtr pScreen);
+extern _X_EXPORT void
+ exaWaitSync(ScreenPtr pScreen);
+
+extern _X_EXPORT unsigned long
+ exaGetPixmapOffset(PixmapPtr pPix);
+
+extern _X_EXPORT unsigned long
+ exaGetPixmapPitch(PixmapPtr pPix);
+
+extern _X_EXPORT unsigned long
+ exaGetPixmapSize(PixmapPtr pPix);
+
+extern _X_EXPORT void *exaGetPixmapDriverPrivate(PixmapPtr p);
+
+/* in exa_offscreen.c */
+extern _X_EXPORT ExaOffscreenArea *exaOffscreenAlloc(ScreenPtr pScreen,
+ int size, int align,
+ Bool locked,
+ ExaOffscreenSaveProc save,
+ pointer privData);
+
+extern _X_EXPORT ExaOffscreenArea *exaOffscreenFree(ScreenPtr pScreen,
+ ExaOffscreenArea * area);
+
+extern _X_EXPORT void
+ ExaOffscreenMarkUsed(PixmapPtr pPixmap);
+
+extern _X_EXPORT void
+ exaEnableDisableFBAccess(int index, Bool enable);
+
+extern _X_EXPORT Bool
+ exaDrawableIsOffscreen(DrawablePtr pDrawable);
+
+/* in exa.c */
+extern _X_EXPORT void
+ exaMoveInPixmap(PixmapPtr pPixmap);
+
+extern _X_EXPORT void
+ exaMoveOutPixmap(PixmapPtr pPixmap);
+
+/* in exa_unaccel.c */
+extern _X_EXPORT CARD32
+ exaGetPixmapFirstPixel(PixmapPtr pPixmap);
+
+/**
+ * Returns TRUE if the given planemask covers all the significant bits in the
+ * pixel values for pDrawable.
+ */
+#define EXA_PM_IS_SOLID(_pDrawable, _pm) \
+ (((_pm) & FbFullMask((_pDrawable)->depth)) == \
+ FbFullMask((_pDrawable)->depth))
+
+#endif /* EXA_H */
diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c
index 5600539d6..0e948f414 100644
--- a/xorg-server/exa/exa_accel.c
+++ b/xorg-server/exa/exa_accel.c
@@ -37,48 +37,46 @@
static void
exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
- DDXPointPtr ppt, int *pwidth, int fSorted)
+ DDXPointPtr ppt, int *pwidth, int fSorted)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- ExaScreenPriv (pScreen);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
- ExaPixmapPriv (pPixmap);
- BoxPtr pextent, pbox;
- int nbox;
- int extentX1, extentX2, extentY1, extentY2;
- int fullX1, fullX2, fullY1;
- int partX1, partX2;
- int off_x, off_y;
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ ExaScreenPriv(pScreen);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ ExaPixmapPriv(pPixmap);
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ int partX1, partX2;
+ int off_x, off_y;
if (pExaScr->fallback_counter ||
- pExaScr->swappedOut ||
- pGC->fillStyle != FillSolid ||
- pExaPixmap->accel_blocked)
- {
- ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
- return;
+ pExaScr->swappedOut ||
+ pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) {
+ ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
}
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[1];
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
- exaDoMigration (pixmaps, 1, TRUE);
+ exaDoMigration(pixmaps, 1, TRUE);
}
- if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
- !(*pExaScr->info->PrepareSolid) (pPixmap,
- pGC->alu,
- pGC->planemask,
- pGC->fgPixel))
- {
- ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
- return;
+ if (!(pPixmap = exaGetOffscreenPixmap(pDrawable, &off_x, &off_y)) ||
+ !(*pExaScr->info->PrepareSolid) (pPixmap,
+ pGC->alu,
+ pGC->planemask, pGC->fgPixel)) {
+ ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
}
pextent = RegionExtents(pClip);
@@ -86,66 +84,63 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
extentY1 = pextent->y1;
extentX2 = pextent->x2;
extentY2 = pextent->y2;
- while (n--)
- {
- fullX1 = ppt->x;
- fullY1 = ppt->y;
- fullX2 = fullX1 + (int) *pwidth;
- ppt++;
- pwidth++;
-
- if (fullY1 < extentY1 || extentY2 <= fullY1)
- continue;
-
- if (fullX1 < extentX1)
- fullX1 = extentX1;
-
- if (fullX2 > extentX2)
- fullX2 = extentX2;
-
- if (fullX1 >= fullX2)
- continue;
-
- nbox = RegionNumRects (pClip);
- if (nbox == 1)
- {
- (*pExaScr->info->Solid) (pPixmap,
- fullX1 + off_x, fullY1 + off_y,
- fullX2 + off_x, fullY1 + 1 + off_y);
- }
- else
- {
- pbox = RegionRects(pClip);
- while(nbox--)
- {
- if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
- {
- partX1 = pbox->x1;
- if (partX1 < fullX1)
- partX1 = fullX1;
- partX2 = pbox->x2;
- if (partX2 > fullX2)
- partX2 = fullX2;
- if (partX2 > partX1) {
- (*pExaScr->info->Solid) (pPixmap,
- partX1 + off_x, fullY1 + off_y,
- partX2 + off_x, fullY1 + 1 + off_y);
- }
- }
- pbox++;
- }
- }
+ while (n--) {
+ fullX1 = ppt->x;
+ fullY1 = ppt->y;
+ fullX2 = fullX1 + (int) *pwidth;
+ ppt++;
+ pwidth++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ nbox = RegionNumRects(pClip);
+ if (nbox == 1) {
+ (*pExaScr->info->Solid) (pPixmap,
+ fullX1 + off_x, fullY1 + off_y,
+ fullX2 + off_x, fullY1 + 1 + off_y);
+ }
+ else {
+ pbox = RegionRects(pClip);
+ while (nbox--) {
+ if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ if (partX2 > partX1) {
+ (*pExaScr->info->Solid) (pPixmap,
+ partX1 + off_x, fullY1 + off_y,
+ partX2 + off_x,
+ fullY1 + 1 + off_y);
+ }
+ }
+ pbox++;
+ }
+ }
}
(*pExaScr->info->DoneSolid) (pPixmap);
exaMarkSync(pScreen);
}
static Bool
-exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int format, char *bits, int src_stride)
+exaDoPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int format, char *bits, int src_stride)
{
- ExaScreenPriv (pDrawable->pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaScreenPriv(pDrawable->pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
+
ExaPixmapPriv(pPix);
RegionPtr pClip;
BoxPtr pbox;
@@ -154,284 +149,280 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int bpp = pDrawable->bitsPerPixel;
Bool ret = TRUE;
- if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
- return FALSE;
+ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
+ !pExaScr->info->UploadToScreen)
+ return FALSE;
/* If there's a system copy, we want to save the result there */
if (pExaPixmap->pDamage)
- return FALSE;
+ return FALSE;
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
- return FALSE;
+ return FALSE;
/* Only accelerate copies: no rop or planemask. */
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
- return FALSE;
+ return FALSE;
if (pExaScr->swappedOut)
- return FALSE;
+ return FALSE;
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[1];
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPix;
- pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPix;
+ pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
- exaDoMigration (pixmaps, 1, TRUE);
+ exaDoMigration(pixmaps, 1, TRUE);
}
- pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+ pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
if (!pPix)
- return FALSE;
+ return FALSE;
x += pDrawable->x;
y += pDrawable->y;
pClip = fbGetCompositeClip(pGC);
for (nbox = RegionNumRects(pClip),
- pbox = RegionRects(pClip);
- nbox--;
- pbox++)
- {
- int x1 = x;
- int y1 = y;
- int x2 = x + w;
- int y2 = y + h;
- char *src;
- Bool ok;
-
- if (x1 < pbox->x1)
- x1 = pbox->x1;
- if (y1 < pbox->y1)
- y1 = pbox->y1;
- if (x2 > pbox->x2)
- x2 = pbox->x2;
- if (y2 > pbox->y2)
- y2 = pbox->y2;
- if (x1 >= x2 || y1 >= y2)
- continue;
-
- src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
- ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
- x2 - x1, y2 - y1, src, src_stride);
- /* We have to fall back completely, and ignore what has already been completed.
- * Messing with the fb layer directly like we used to is completely unacceptable.
- */
- if (!ok) {
- ret = FALSE;
- break;
- }
+ pbox = RegionRects(pClip); nbox--; pbox++) {
+ int x1 = x;
+ int y1 = y;
+ int x2 = x + w;
+ int y2 = y + h;
+ char *src;
+ Bool ok;
+
+ if (x1 < pbox->x1)
+ x1 = pbox->x1;
+ if (y1 < pbox->y1)
+ y1 = pbox->y1;
+ if (x2 > pbox->x2)
+ x2 = pbox->x2;
+ if (y2 > pbox->y2)
+ y2 = pbox->y2;
+ if (x1 >= x2 || y1 >= y2)
+ continue;
+
+ src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
+ ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
+ x2 - x1, y2 - y1, src, src_stride);
+ /* We have to fall back completely, and ignore what has already been completed.
+ * Messing with the fb layer directly like we used to is completely unacceptable.
+ */
+ if (!ok) {
+ ret = FALSE;
+ break;
+ }
}
if (ret)
- exaMarkSync(pDrawable->pScreen);
+ exaMarkSync(pDrawable->pScreen);
return ret;
}
static void
-exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits)
+exaPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *bits)
{
if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
- PixmapBytePad(w, pDrawable->depth)))
- ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
- bits);
+ PixmapBytePad(w, pDrawable->depth)))
+ ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ bits);
}
static Bool inline
-exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
- GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
+exaCopyNtoNTwoDir(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
{
- ExaScreenPriv (pDstDrawable->pScreen);
+ ExaScreenPriv(pDstDrawable->pScreen);
PixmapPtr pSrcPixmap, pDstPixmap;
int src_off_x, src_off_y, dst_off_x, dst_off_y;
int dirsetup;
/* Need to get both pixmaps to call the driver routines */
- pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y);
- pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y);
+ pSrcPixmap = exaGetOffscreenPixmap(pSrcDrawable, &src_off_x, &src_off_y);
+ pDstPixmap = exaGetOffscreenPixmap(pDstDrawable, &dst_off_x, &dst_off_y);
if (!pSrcPixmap || !pDstPixmap)
- return FALSE;
+ return FALSE;
/*
* Now the case of a chip that only supports xdir = ydir = 1 or
* xdir = ydir = -1, but we have xdir != ydir.
*/
- dirsetup = 0; /* No direction set up yet. */
+ dirsetup = 0; /* No direction set up yet. */
for (; nbox; pbox++, nbox--) {
- if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
- /* Do a xdir = ydir = -1 blit instead. */
- if (dirsetup != -1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = -1;
- if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
- pDstPixmap,
- -1, -1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- (*pExaScr->info->Copy)(pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
- /* Do a xdir = ydir = 1 blit instead. */
- if (dirsetup != 1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = 1;
- if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
- pDstPixmap,
- 1, 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- (*pExaScr->info->Copy)(pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- } else if (dx >= 0) {
- /*
- * xdir = 1, ydir = -1.
- * Perform line-by-line xdir = ydir = 1 blits, going up.
- */
- int i;
- if (dirsetup != 1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = 1;
- if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
- pDstPixmap,
- 1, 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
- (*pExaScr->info->Copy)(pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy + i,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- } else {
- /*
- * xdir = -1, ydir = 1.
- * Perform line-by-line xdir = ydir = -1 blits, going down.
- */
- int i;
- if (dirsetup != -1) {
- if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
- dirsetup = -1;
- if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
- pDstPixmap,
- -1, -1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask :
- FB_ALLONES))
- return FALSE;
- }
- for (i = 0; i < pbox->y2 - pbox->y1; i++)
- (*pExaScr->info->Copy)(pDstPixmap,
- src_off_x + pbox->x1 + dx,
- src_off_y + pbox->y1 + dy + i,
- dst_off_x + pbox->x1,
- dst_off_y + pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- }
+ if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = -1;
+ if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
+ pDstPixmap,
+ -1, -1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ (*pExaScr->info->Copy) (pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = 1;
+ if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
+ pDstPixmap,
+ 1, 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ (*pExaScr->info->Copy) (pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (dx >= 0) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+
+ if (dirsetup != 1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = 1;
+ if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
+ pDstPixmap,
+ 1, 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*pExaScr->info->Copy) (pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy + i,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+
+ if (dirsetup != -1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = -1;
+ if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap,
+ pDstPixmap,
+ -1, -1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*pExaScr->info->Copy) (pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy + i,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
}
if (dirsetup != 0)
- pExaScr->info->DoneCopy(pDstPixmap);
+ pExaScr->info->DoneCopy(pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
return TRUE;
}
Bool
-exaHWCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown)
+exaHWCopyNtoN(DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox, int dx, int dy, Bool reverse, Bool upsidedown)
{
- ExaScreenPriv (pDstDrawable->pScreen);
+ ExaScreenPriv(pDstDrawable->pScreen);
PixmapPtr pSrcPixmap, pDstPixmap;
ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
- int src_off_x, src_off_y;
- int dst_off_x, dst_off_y;
+ int src_off_x, src_off_y;
+ int dst_off_x, dst_off_y;
RegionPtr srcregion = NULL, dstregion = NULL;
xRectangle *rects;
Bool ret = TRUE;
/* avoid doing copy operations if no boxes */
if (nbox == 0)
- return TRUE;
+ return TRUE;
- pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
- pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+ pSrcPixmap = exaGetDrawablePixmap(pSrcDrawable);
+ pDstPixmap = exaGetDrawablePixmap(pDstDrawable);
- exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
- exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
+ exaGetDrawableDeltas(pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
+ exaGetDrawableDeltas(pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
rects = malloc(nbox * sizeof(xRectangle));
if (rects) {
- int i;
- int ordering;
-
- for (i = 0; i < nbox; i++) {
- rects[i].x = pbox[i].x1 + dx + src_off_x;
- rects[i].y = pbox[i].y1 + dy + src_off_y;
- rects[i].width = pbox[i].x2 - pbox[i].x1;
- rects[i].height = pbox[i].y2 - pbox[i].y1;
- }
-
- /* This must match the RegionCopy() logic for reversing rect order */
- if (nbox == 1 || (dx > 0 && dy > 0) ||
- (pDstDrawable != pSrcDrawable &&
- (pDstDrawable->type != DRAWABLE_WINDOW ||
- pSrcDrawable->type != DRAWABLE_WINDOW)))
- ordering = CT_YXBANDED;
- else
- ordering = CT_UNSORTED;
-
- srcregion = RegionFromRects(nbox, rects, ordering);
- free(rects);
-
- if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
- pGC->fillStyle, pGC->alu,
- pGC->clientClipType)) {
- dstregion = RegionCreate(NullBox, 0);
- RegionCopy(dstregion, srcregion);
- RegionTranslate(dstregion, dst_off_x - dx - src_off_x,
- dst_off_y - dy - src_off_y);
- }
- }
+ int i;
+ int ordering;
+
+ for (i = 0; i < nbox; i++) {
+ rects[i].x = pbox[i].x1 + dx + src_off_x;
+ rects[i].y = pbox[i].y1 + dy + src_off_y;
+ rects[i].width = pbox[i].x2 - pbox[i].x1;
+ rects[i].height = pbox[i].y2 - pbox[i].y1;
+ }
+ /* This must match the RegionCopy() logic for reversing rect order */
+ if (nbox == 1 || (dx > 0 && dy > 0) ||
+ (pDstDrawable != pSrcDrawable &&
+ (pDstDrawable->type != DRAWABLE_WINDOW ||
+ pSrcDrawable->type != DRAWABLE_WINDOW)))
+ ordering = CT_YXBANDED;
+ else
+ ordering = CT_UNSORTED;
+
+ srcregion = RegionFromRects(nbox, rects, ordering);
+ free(rects);
+
+ if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
+ pGC->fillStyle, pGC->alu,
+ pGC->clientClipType)) {
+ dstregion = RegionCreate(NullBox, 0);
+ RegionCopy(dstregion, srcregion);
+ RegionTranslate(dstregion, dst_off_x - dx - src_off_x,
+ dst_off_y - dy - src_off_y);
+ }
+ }
- pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
- pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
+ pSrcExaPixmap = ExaGetPixmapPriv(pSrcPixmap);
+ pDstExaPixmap = ExaGetPixmapPriv(pDstPixmap);
/* Check whether the accelerator can use this pixmap.
* If the pitch of the pixmaps is out of range, there's nothing
@@ -439,7 +430,7 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable,
*/
if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH ||
pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH)
- goto fallback;
+ goto fallback;
/* If the width or the height of either of the pixmaps
* is out of range, check whether the boxes are actually out of the
@@ -463,158 +454,167 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable,
}
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[2];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pDstPixmap;
- pixmaps[0].pReg = dstregion;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pSrcPixmap;
- pixmaps[1].pReg = srcregion;
-
- exaDoMigration (pixmaps, 2, TRUE);
+ ExaMigrationRec pixmaps[2];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pDstPixmap;
+ pixmaps[0].pReg = dstregion;
+ pixmaps[1].as_dst = FALSE;
+ pixmaps[1].as_src = TRUE;
+ pixmaps[1].pPix = pSrcPixmap;
+ pixmaps[1].pReg = srcregion;
+
+ exaDoMigration(pixmaps, 2, TRUE);
}
/* Mixed directions must be handled specially if the card is lame */
if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
- reverse != upsidedown) {
- if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
- dx, dy))
- goto out;
- goto fallback;
+ reverse != upsidedown) {
+ if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
+ dx, dy))
+ goto out;
+ goto fallback;
}
if (exaPixmapHasGpuCopy(pDstPixmap)) {
- /* Normal blitting. */
- if (exaPixmapHasGpuCopy(pSrcPixmap)) {
- if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
- upsidedown ? -1 : 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask : FB_ALLONES)) {
- goto fallback;
- }
-
- while (nbox--)
- {
- (*pExaScr->info->Copy) (pDstPixmap,
- pbox->x1 + dx + src_off_x,
- pbox->y1 + dy + src_off_y,
- pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- pbox++;
- }
-
- (*pExaScr->info->DoneCopy) (pDstPixmap);
- exaMarkSync (pDstDrawable->pScreen);
- /* UTS: mainly for SHM PutImage's secondary path.
- *
- * Only taking this path for directly accessible pixmaps.
- */
- } else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) {
- int bpp = pSrcDrawable->bitsPerPixel;
- int src_stride = exaGetPixmapPitch(pSrcPixmap);
- CARD8 *src = NULL;
-
- if (!pExaScr->info->UploadToScreen)
- goto fallback;
-
- if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
- goto fallback;
-
- if (pSrcDrawable->bitsPerPixel < 8)
- goto fallback;
-
- if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask)))
- goto fallback;
-
- while (nbox--)
- {
- src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8);
- if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x,
- pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- (char *) src, src_stride))
- goto fallback;
-
- pbox++;
- }
- } else
- goto fallback;
- } else
- goto fallback;
+ /* Normal blitting. */
+ if (exaPixmapHasGpuCopy(pSrcPixmap)) {
+ if (!(*pExaScr->info->PrepareCopy)
+ (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, upsidedown ? -1 : 1,
+ pGC ? pGC->alu : GXcopy, pGC ? pGC->planemask : FB_ALLONES)) {
+ goto fallback;
+ }
+
+ while (nbox--) {
+ (*pExaScr->info->Copy) (pDstPixmap,
+ pbox->x1 + dx + src_off_x,
+ pbox->y1 + dy + src_off_y,
+ pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ (*pExaScr->info->DoneCopy) (pDstPixmap);
+ exaMarkSync(pDstDrawable->pScreen);
+ /* UTS: mainly for SHM PutImage's secondary path.
+ *
+ * Only taking this path for directly accessible pixmaps.
+ */
+ }
+ else if (!pDstExaPixmap->pDamage && pSrcExaPixmap->sys_ptr) {
+ int bpp = pSrcDrawable->bitsPerPixel;
+ int src_stride = exaGetPixmapPitch(pSrcPixmap);
+ CARD8 *src = NULL;
+
+ if (!pExaScr->info->UploadToScreen)
+ goto fallback;
+
+ if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
+ goto fallback;
+
+ if (pSrcDrawable->bitsPerPixel < 8)
+ goto fallback;
+
+ if (pGC &&
+ !(pGC->alu == GXcopy &&
+ EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask)))
+ goto fallback;
+
+ while (nbox--) {
+ src =
+ pSrcExaPixmap->sys_ptr + (pbox->y1 + dy +
+ src_off_y) * src_stride +
+ (pbox->x1 + dx + src_off_x) * (bpp / 8);
+ if (!pExaScr->info->
+ UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1, (char *) src,
+ src_stride))
+ goto fallback;
+
+ pbox++;
+ }
+ }
+ else
+ goto fallback;
+ }
+ else
+ goto fallback;
goto out;
-fallback:
+ fallback:
ret = FALSE;
-out:
+ out:
if (dstregion) {
- RegionUninit(dstregion);
- RegionDestroy(dstregion);
+ RegionUninit(dstregion);
+ RegionDestroy(dstregion);
}
if (srcregion) {
- RegionUninit(srcregion);
- RegionDestroy(srcregion);
+ RegionUninit(srcregion);
+ RegionDestroy(srcregion);
}
return ret;
}
void
-exaCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown,
- Pixel bitplane,
- void *closure)
+exaCopyNtoN(DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
{
ExaScreenPriv(pDstDrawable->pScreen);
if (pExaScr->fallback_counter ||
- (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
- return;
+ (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
+ return;
- if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
- return;
+ if (exaHWCopyNtoN
+ (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
+ upsidedown))
+ return;
/* This is a CopyWindow, it's cleaner to fallback at the original call. */
if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) {
- pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
- return;
+ pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+ return;
}
/* fallback */
- ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+ ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy,
+ reverse, upsidedown, bitplane, closure);
}
RegionPtr
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty)
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
{
- ExaScreenPriv (pDstDrawable->pScreen);
+ ExaScreenPriv(pDstDrawable->pScreen);
if (pExaScr->fallback_counter || pExaScr->swappedOut) {
- return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
- srcx, srcy, width, height, dstx, dsty);
+ return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
}
- return miDoCopy (pSrcDrawable, pDstDrawable, pGC,
- srcx, srcy, width, height,
- dstx, dsty, exaCopyNtoN, 0, NULL);
+ return miDoCopy(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, exaCopyNtoN, 0, NULL);
}
static void
exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
+ DDXPointPtr ppt)
{
- ExaScreenPriv (pDrawable->pScreen);
+ ExaScreenPriv(pDrawable->pScreen);
int i;
xRectangle *prect;
@@ -622,20 +622,20 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
* points.
*/
if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
- ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
- return;
+ ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
+ return;
}
prect = malloc(sizeof(xRectangle) * npt);
for (i = 0; i < npt; i++) {
- prect[i].x = ppt[i].x;
- prect[i].y = ppt[i].y;
- if (i > 0 && mode == CoordModePrevious) {
- prect[i].x += prect[i - 1].x;
- prect[i].y += prect[i - 1].y;
- }
- prect[i].width = 1;
- prect[i].height = 1;
+ prect[i].x = ppt[i].x;
+ prect[i].y = ppt[i].y;
+ if (i > 0 && mode == CoordModePrevious) {
+ prect[i].x += prect[i - 1].x;
+ prect[i].y += prect[i - 1].y;
+ }
+ prect[i].width = 1;
+ prect[i].height = 1;
}
pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
free(prect);
@@ -648,23 +648,23 @@ exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
*/
static void
exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr ppt)
+ DDXPointPtr ppt)
{
- ExaScreenPriv (pDrawable->pScreen);
+ ExaScreenPriv(pDrawable->pScreen);
xRectangle *prect;
int x1, x2, y1, y2;
int i;
if (pExaScr->fallback_counter) {
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
}
/* Don't try to do wide lines or non-solid fill style. */
if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
- pGC->fillStyle != FillSolid) {
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
+ pGC->fillStyle != FillSolid) {
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
}
prect = malloc(sizeof(xRectangle) * (npt - 1));
@@ -672,37 +672,40 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
y1 = ppt[0].y;
/* If we have any non-horizontal/vertical, fall back. */
for (i = 0; i < npt - 1; i++) {
- if (mode == CoordModePrevious) {
- x2 = x1 + ppt[i + 1].x;
- y2 = y1 + ppt[i + 1].y;
- } else {
- x2 = ppt[i + 1].x;
- y2 = ppt[i + 1].y;
- }
-
- if (x1 != x2 && y1 != y2) {
- free(prect);
- ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
- return;
- }
-
- if (x1 < x2) {
- prect[i].x = x1;
- prect[i].width = x2 - x1 + 1;
- } else {
- prect[i].x = x2;
- prect[i].width = x1 - x2 + 1;
- }
- if (y1 < y2) {
- prect[i].y = y1;
- prect[i].height = y2 - y1 + 1;
- } else {
- prect[i].y = y2;
- prect[i].height = y1 - y2 + 1;
- }
-
- x1 = x2;
- y1 = y2;
+ if (mode == CoordModePrevious) {
+ x2 = x1 + ppt[i + 1].x;
+ y2 = y1 + ppt[i + 1].y;
+ }
+ else {
+ x2 = ppt[i + 1].x;
+ y2 = ppt[i + 1].y;
+ }
+
+ if (x1 != x2 && y1 != y2) {
+ free(prect);
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
+ }
+
+ if (x1 < x2) {
+ prect[i].x = x1;
+ prect[i].width = x2 - x1 + 1;
+ }
+ else {
+ prect[i].x = x2;
+ prect[i].width = x1 - x2 + 1;
+ }
+ if (y1 < y2) {
+ prect[i].y = y1;
+ prect[i].height = y2 - y1 + 1;
+ }
+ else {
+ prect[i].y = y2;
+ prect[i].height = y1 - y2 + 1;
+ }
+
+ x1 = x2;
+ y1 = y2;
}
pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
free(prect);
@@ -714,80 +717,78 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
* acceleration if so.
*/
static void
-exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg)
+exaPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSeg)
{
- ExaScreenPriv (pDrawable->pScreen);
+ ExaScreenPriv(pDrawable->pScreen);
xRectangle *prect;
int i;
/* Don't try to do wide lines or non-solid fill style. */
if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
- pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid)
- {
- ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
- return;
+ pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) {
+ ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+ return;
}
/* If we have any non-horizontal/vertical, fall back. */
for (i = 0; i < nseg; i++) {
- if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
- ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
- return;
- }
+ if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
+ ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+ return;
+ }
}
prect = malloc(sizeof(xRectangle) * nseg);
for (i = 0; i < nseg; i++) {
- if (pSeg[i].x1 < pSeg[i].x2) {
- prect[i].x = pSeg[i].x1;
- prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
- } else {
- prect[i].x = pSeg[i].x2;
- prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
- }
- if (pSeg[i].y1 < pSeg[i].y2) {
- prect[i].y = pSeg[i].y1;
- prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
- } else {
- prect[i].y = pSeg[i].y2;
- prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
- }
-
- /* don't paint last pixel */
- if (pGC->capStyle == CapNotLast) {
- if (prect[i].width == 1)
- prect[i].height--;
- else
- prect[i].width--;
- }
+ if (pSeg[i].x1 < pSeg[i].x2) {
+ prect[i].x = pSeg[i].x1;
+ prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
+ }
+ else {
+ prect[i].x = pSeg[i].x2;
+ prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
+ }
+ if (pSeg[i].y1 < pSeg[i].y2) {
+ prect[i].y = pSeg[i].y1;
+ prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
+ }
+ else {
+ prect[i].y = pSeg[i].y2;
+ prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
+ }
+
+ /* don't paint last pixel */
+ if (pGC->capStyle == CapNotLast) {
+ if (prect[i].width == 1)
+ prect[i].height--;
+ else
+ prect[i].width--;
+ }
}
pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
free(prect);
}
-static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
- Pixel pixel, CARD32 planemask, CARD32 alu,
- unsigned int clientClipType);
+static Bool exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion,
+ Pixel pixel, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType);
static void
-exaPolyFillRect(DrawablePtr pDrawable,
- GCPtr pGC,
- int nrect,
- xRectangle *prect)
+exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect)
{
- ExaScreenPriv (pDrawable->pScreen);
- RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
- ExaPixmapPriv (pPixmap);
+ ExaScreenPriv(pDrawable->pScreen);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ ExaPixmapPriv(pPixmap);
register BoxPtr pbox;
- BoxPtr pextent;
- int extentX1, extentX2, extentY1, extentY2;
- int fullX1, fullX2, fullY1, fullY2;
- int partX1, partX2, partY1, partY2;
- int xoff, yoff;
- int xorg, yorg;
- int n;
+ BoxPtr pextent;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1, fullY2;
+ int partX1, partX2, partY1, partY2;
+ int xoff, yoff;
+ int xorg, yorg;
+ int n;
RegionPtr pReg = RegionFromRects(nrect, prect, CT_UNSORTED);
/* Compute intersection of rects and clip region */
@@ -795,62 +796,58 @@ exaPolyFillRect(DrawablePtr pDrawable,
RegionIntersect(pReg, pClip, pReg);
if (!RegionNumRects(pReg)) {
- goto out;
+ goto out;
}
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
if (pExaScr->fallback_counter || pExaScr->swappedOut ||
- pExaPixmap->accel_blocked)
- {
- goto fallback;
+ pExaPixmap->accel_blocked) {
+ goto fallback;
}
/* For ROPs where overlaps don't matter, convert rectangles to region and
* call exaFillRegion{Solid,Tiled}.
*/
if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
- (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
- pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
- pGC->alu == GXset)) {
- if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
- exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
- pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
- pGC->alu, pGC->clientClipType)) ||
- (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
- exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
- pGC->planemask, pGC->alu,
- pGC->clientClipType))) {
- goto out;
- }
+ (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
+ pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
+ pGC->alu == GXset)) {
+ if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
+ exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
+ pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
+ pGC->alu, pGC->clientClipType)) ||
+ (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
+ exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
+ pGC->planemask, pGC->alu,
+ pGC->clientClipType))) {
+ goto out;
+ }
}
if (pGC->fillStyle != FillSolid &&
- !(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
- {
- goto fallback;
+ !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
+ goto fallback;
}
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[1];
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
- exaDoMigration (pixmaps, 1, TRUE);
+ exaDoMigration(pixmaps, 1, TRUE);
}
- if (!exaPixmapHasGpuCopy (pPixmap) ||
- !(*pExaScr->info->PrepareSolid) (pPixmap,
- pGC->alu,
- pGC->planemask,
- pGC->fgPixel))
- {
-fallback:
- ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
- goto out;
+ if (!exaPixmapHasGpuCopy(pPixmap) ||
+ !(*pExaScr->info->PrepareSolid) (pPixmap,
+ pGC->alu,
+ pGC->planemask, pGC->fgPixel)) {
+ fallback:
+ ExaCheckPolyFillRect(pDrawable, pGC, nrect, prect);
+ goto out;
}
xorg = pDrawable->x;
@@ -861,72 +858,68 @@ fallback:
extentY1 = pextent->y1;
extentX2 = pextent->x2;
extentY2 = pextent->y2;
- while (nrect--)
- {
- fullX1 = prect->x + xorg;
- fullY1 = prect->y + yorg;
- fullX2 = fullX1 + (int) prect->width;
- fullY2 = fullY1 + (int) prect->height;
- prect++;
-
- if (fullX1 < extentX1)
- fullX1 = extentX1;
-
- if (fullY1 < extentY1)
- fullY1 = extentY1;
-
- if (fullX2 > extentX2)
- fullX2 = extentX2;
-
- if (fullY2 > extentY2)
- fullY2 = extentY2;
-
- if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
- continue;
- n = RegionNumRects (pClip);
- if (n == 1)
- {
- (*pExaScr->info->Solid) (pPixmap,
- fullX1 + xoff, fullY1 + yoff,
- fullX2 + xoff, fullY2 + yoff);
- }
- else
- {
- pbox = RegionRects(pClip);
- /*
- * clip the rectangle to each box in the clip region
- * this is logically equivalent to calling Intersect(),
- * but rectangles may overlap each other here.
- */
- while(n--)
- {
- partX1 = pbox->x1;
- if (partX1 < fullX1)
- partX1 = fullX1;
- partY1 = pbox->y1;
- if (partY1 < fullY1)
- partY1 = fullY1;
- partX2 = pbox->x2;
- if (partX2 > fullX2)
- partX2 = fullX2;
- partY2 = pbox->y2;
- if (partY2 > fullY2)
- partY2 = fullY2;
-
- pbox++;
-
- if (partX1 < partX2 && partY1 < partY2) {
- (*pExaScr->info->Solid) (pPixmap,
- partX1 + xoff, partY1 + yoff,
- partX2 + xoff, partY2 + yoff);
- }
- }
- }
+ while (nrect--) {
+ fullX1 = prect->x + xorg;
+ fullY1 = prect->y + yorg;
+ fullX2 = fullX1 + (int) prect->width;
+ fullY2 = fullY1 + (int) prect->height;
+ prect++;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullY1 < extentY1)
+ fullY1 = extentY1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullY2 > extentY2)
+ fullY2 = extentY2;
+
+ if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
+ continue;
+ n = RegionNumRects(pClip);
+ if (n == 1) {
+ (*pExaScr->info->Solid) (pPixmap,
+ fullX1 + xoff, fullY1 + yoff,
+ fullX2 + xoff, fullY2 + yoff);
+ }
+ else {
+ pbox = RegionRects(pClip);
+ /*
+ * clip the rectangle to each box in the clip region
+ * this is logically equivalent to calling Intersect(),
+ * but rectangles may overlap each other here.
+ */
+ while (n--) {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partY1 = pbox->y1;
+ if (partY1 < fullY1)
+ partY1 = fullY1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ partY2 = pbox->y2;
+ if (partY2 > fullY2)
+ partY2 = fullY2;
+
+ pbox++;
+
+ if (partX1 < partX2 && partY1 < partY2) {
+ (*pExaScr->info->Solid) (pPixmap,
+ partX1 + xoff, partY1 + yoff,
+ partX2 + xoff, partY2 + yoff);
+ }
+ }
+ }
}
(*pExaScr->info->DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
-out:
+ out:
RegionUninit(pReg);
RegionDestroy(pReg);
}
@@ -957,9 +950,10 @@ const GCOps exaOps = {
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
- RegionRec rgnDst;
- int dx, dy;
- PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ RegionRec rgnDst;
+ int dx, dy;
+ PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+
ExaScreenPriv(pWin->drawable.pScreen);
dx = ptOldOrg.x - pWin->drawable.x;
@@ -971,38 +965,37 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
#ifdef COMPOSITE
if (pPixmap->screen_x || pPixmap->screen_y)
- RegionTranslate(&rgnDst,
- -pPixmap->screen_x, -pPixmap->screen_y);
+ RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y);
#endif
if (pExaScr->fallback_counter) {
- pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
- goto fallback;
+ pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+ goto fallback;
}
pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
- miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
- NULL,
- &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
+ miCopyRegion(&pPixmap->drawable, &pPixmap->drawable,
+ NULL, &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
-fallback:
+ fallback:
RegionUninit(&rgnDst);
if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
- pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
- RegionTranslate(prgnSrc, dx, dy);
- ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
+ pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
+ RegionTranslate(prgnSrc, dx, dy);
+ ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
}
}
static Bool
-exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
- CARD32 planemask, CARD32 alu, unsigned int clientClipType)
+exaFillRegionSolid(DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
+ CARD32 planemask, CARD32 alu, unsigned int clientClipType)
{
ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
- ExaPixmapPriv (pPixmap);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ ExaPixmapPriv(pPixmap);
int xoff, yoff;
Bool ret = FALSE;
@@ -1010,69 +1003,67 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
RegionTranslate(pRegion, xoff, yoff);
if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
- goto out;
+ goto out;
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[1];
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
- alu, clientClipType) ? NULL : pRegion;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
+ alu,
+ clientClipType) ? NULL :
+ pRegion;
- exaDoMigration (pixmaps, 1, TRUE);
+ exaDoMigration(pixmaps, 1, TRUE);
}
- if (exaPixmapHasGpuCopy (pPixmap) &&
- (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
- {
- int nbox;
- BoxPtr pBox;
-
- nbox = RegionNumRects (pRegion);
- pBox = RegionRects (pRegion);
-
- while (nbox--)
- {
- (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
- pBox->y2);
- pBox++;
- }
- (*pExaScr->info->DoneSolid) (pPixmap);
- exaMarkSync(pDrawable->pScreen);
-
- if (pExaPixmap->pDamage &&
- pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
- pDrawable->width == 1 && pDrawable->height == 1 &&
- pDrawable->bitsPerPixel != 24) {
- ExaPixmapPriv(pPixmap);
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
-
- switch (pDrawable->bitsPerPixel) {
- case 32:
- *(CARD32*)pExaPixmap->sys_ptr = pixel;
- break;
- case 16:
- *(CARD16*)pExaPixmap->sys_ptr = pixel;
- break;
- case 8:
- case 4:
- case 1:
- *(CARD8*)pExaPixmap->sys_ptr = pixel;
- }
-
- RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys,
- pRegion);
- RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB,
- pRegion);
- RegionSubtract(pending_damage, pending_damage, pRegion);
- }
-
- ret = TRUE;
+ if (exaPixmapHasGpuCopy(pPixmap) &&
+ (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) {
+ int nbox;
+ BoxPtr pBox;
+
+ nbox = RegionNumRects(pRegion);
+ pBox = RegionRects(pRegion);
+
+ while (nbox--) {
+ (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
+ pBox->y2);
+ pBox++;
+ }
+ (*pExaScr->info->DoneSolid) (pPixmap);
+ exaMarkSync(pDrawable->pScreen);
+
+ if (pExaPixmap->pDamage &&
+ pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
+ pDrawable->width == 1 && pDrawable->height == 1 &&
+ pDrawable->bitsPerPixel != 24) {
+ ExaPixmapPriv(pPixmap);
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+
+ switch (pDrawable->bitsPerPixel) {
+ case 32:
+ *(CARD32 *) pExaPixmap->sys_ptr = pixel;
+ break;
+ case 16:
+ *(CARD16 *) pExaPixmap->sys_ptr = pixel;
+ break;
+ case 8:
+ case 4:
+ case 1:
+ *(CARD8 *) pExaPixmap->sys_ptr = pixel;
+ }
+
+ RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, pRegion);
+ RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, pRegion);
+ RegionSubtract(pending_damage, pending_damage, pRegion);
+ }
+
+ ret = TRUE;
}
-out:
+ out:
RegionTranslate(pRegion, -xoff, -yoff);
return ret;
@@ -1082,9 +1073,9 @@ out:
* Based on fbFillRegionTiled(), fbTile().
*/
Bool
-exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
- DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
- unsigned int clientClipType)
+exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType)
{
ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap;
@@ -1092,8 +1083,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
int xoff, yoff;
int tileWidth, tileHeight;
- int nbox = RegionNumRects (pRegion);
- BoxPtr pBox = RegionRects (pRegion);
+ int nbox = RegionNumRects(pRegion);
+ BoxPtr pBox = RegionRects(pRegion);
Bool ret = FALSE;
int i;
@@ -1104,156 +1095,158 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
* FillRegionSolid, saving numerous copies.
*/
if (tileWidth == 1 && tileHeight == 1)
- return exaFillRegionSolid(pDrawable, pRegion,
- exaGetPixmapFirstPixel (pTile), planemask,
- alu, clientClipType);
+ return exaFillRegionSolid(pDrawable, pRegion,
+ exaGetPixmapFirstPixel(pTile), planemask,
+ alu, clientClipType);
- pPixmap = exaGetDrawablePixmap (pDrawable);
- pExaPixmap = ExaGetPixmapPriv (pPixmap);
+ pPixmap = exaGetDrawablePixmap(pDrawable);
+ pExaPixmap = ExaGetPixmapPriv(pPixmap);
if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
- pTileExaPixmap->accel_blocked)
- return FALSE;
+ pTileExaPixmap->accel_blocked)
+ return FALSE;
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[2];
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
- alu, clientClipType) ? NULL : pRegion;
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pTile;
- pixmaps[1].pReg = NULL;
-
- exaDoMigration (pixmaps, 2, TRUE);
+ ExaMigrationRec pixmaps[2];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
+ alu,
+ clientClipType) ? NULL :
+ pRegion;
+ pixmaps[1].as_dst = FALSE;
+ pixmaps[1].as_src = TRUE;
+ pixmaps[1].pPix = pTile;
+ pixmaps[1].pReg = NULL;
+
+ exaDoMigration(pixmaps, 2, TRUE);
}
- pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+ pPixmap = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
if (!pPixmap || !exaPixmapHasGpuCopy(pTile))
- return FALSE;
-
- if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
- {
- if (xoff || yoff)
- RegionTranslate(pRegion, xoff, yoff);
-
- for (i = 0; i < nbox; i++)
- {
- int height = pBox[i].y2 - pBox[i].y1;
- int dstY = pBox[i].y1;
- int tileY;
-
- if (alu == GXcopy)
- height = min(height, tileHeight);
-
- modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
-
- while (height > 0) {
- int width = pBox[i].x2 - pBox[i].x1;
- int dstX = pBox[i].x1;
- int tileX;
- int h = tileHeight - tileY;
-
- if (alu == GXcopy)
- width = min(width, tileWidth);
-
- if (h > height)
- h = height;
- height -= h;
-
- modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
- tileX);
-
- while (width > 0) {
- int w = tileWidth - tileX;
- if (w > width)
- w = width;
- width -= w;
-
- (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
- w, h);
- dstX += w;
- tileX = 0;
- }
- dstY += h;
- tileY = 0;
- }
- }
- (*pExaScr->info->DoneCopy) (pPixmap);
-
- /* With GXcopy, we only need to do the basic algorithm up to the tile
- * size; then, we can just keep doubling the destination in each
- * direction until it fills the box. This way, the number of copy
- * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
- * rx/ry is the ratio between box and tile width/height. This can make
- * a big difference if each driver copy incurs a significant constant
- * overhead.
- */
- if (alu != GXcopy)
- ret = TRUE;
- else {
- Bool more_copy = FALSE;
-
- for (i = 0; i < nbox; i++) {
- int dstX = pBox[i].x1 + tileWidth;
- int dstY = pBox[i].y1 + tileHeight;
-
- if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
- more_copy = TRUE;
- break;
- }
- }
-
- if (more_copy == FALSE)
- ret = TRUE;
-
- if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
- 1, 1, alu, planemask)) {
- for (i = 0; i < nbox; i++)
- {
- int dstX = pBox[i].x1 + tileWidth;
- int dstY = pBox[i].y1 + tileHeight;
- int width = min(pBox[i].x2 - dstX, tileWidth);
- int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);
-
- while (dstX < pBox[i].x2) {
- (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
- dstX, pBox[i].y1, width, height);
- dstX += width;
- width = min(pBox[i].x2 - dstX, width * 2);
- }
-
- width = pBox[i].x2 - pBox[i].x1;
- height = min(pBox[i].y2 - dstY, tileHeight);
-
- while (dstY < pBox[i].y2) {
- (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
- pBox[i].x1, dstY, width, height);
- dstY += height;
- height = min(pBox[i].y2 - dstY, height * 2);
- }
- }
-
- (*pExaScr->info->DoneCopy) (pPixmap);
-
- ret = TRUE;
- }
- }
-
- exaMarkSync(pDrawable->pScreen);
-
- if (xoff || yoff)
- RegionTranslate(pRegion, -xoff, -yoff);
+ return FALSE;
+
+ if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) {
+ if (xoff || yoff)
+ RegionTranslate(pRegion, xoff, yoff);
+
+ for (i = 0; i < nbox; i++) {
+ int height = pBox[i].y2 - pBox[i].y1;
+ int dstY = pBox[i].y1;
+ int tileY;
+
+ if (alu == GXcopy)
+ height = min(height, tileHeight);
+
+ modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
+
+ while (height > 0) {
+ int width = pBox[i].x2 - pBox[i].x1;
+ int dstX = pBox[i].x1;
+ int tileX;
+ int h = tileHeight - tileY;
+
+ if (alu == GXcopy)
+ width = min(width, tileWidth);
+
+ if (h > height)
+ h = height;
+ height -= h;
+
+ modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
+ tileX);
+
+ while (width > 0) {
+ int w = tileWidth - tileX;
+
+ if (w > width)
+ w = width;
+ width -= w;
+
+ (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
+ w, h);
+ dstX += w;
+ tileX = 0;
+ }
+ dstY += h;
+ tileY = 0;
+ }
+ }
+ (*pExaScr->info->DoneCopy) (pPixmap);
+
+ /* With GXcopy, we only need to do the basic algorithm up to the tile
+ * size; then, we can just keep doubling the destination in each
+ * direction until it fills the box. This way, the number of copy
+ * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
+ * rx/ry is the ratio between box and tile width/height. This can make
+ * a big difference if each driver copy incurs a significant constant
+ * overhead.
+ */
+ if (alu != GXcopy)
+ ret = TRUE;
+ else {
+ Bool more_copy = FALSE;
+
+ for (i = 0; i < nbox; i++) {
+ int dstX = pBox[i].x1 + tileWidth;
+ int dstY = pBox[i].y1 + tileHeight;
+
+ if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
+ more_copy = TRUE;
+ break;
+ }
+ }
+
+ if (more_copy == FALSE)
+ ret = TRUE;
+
+ if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
+ 1, 1, alu,
+ planemask)) {
+ for (i = 0; i < nbox; i++) {
+ int dstX = pBox[i].x1 + tileWidth;
+ int dstY = pBox[i].y1 + tileHeight;
+ int width = min(pBox[i].x2 - dstX, tileWidth);
+ int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);
+
+ while (dstX < pBox[i].x2) {
+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
+ dstX, pBox[i].y1, width,
+ height);
+ dstX += width;
+ width = min(pBox[i].x2 - dstX, width * 2);
+ }
+
+ width = pBox[i].x2 - pBox[i].x1;
+ height = min(pBox[i].y2 - dstY, tileHeight);
+
+ while (dstY < pBox[i].y2) {
+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
+ pBox[i].x1, dstY, width,
+ height);
+ dstY += height;
+ height = min(pBox[i].y2 - dstY, height * 2);
+ }
+ }
+
+ (*pExaScr->info->DoneCopy) (pPixmap);
+
+ ret = TRUE;
+ }
+ }
+
+ exaMarkSync(pDrawable->pScreen);
+
+ if (xoff || yoff)
+ RegionTranslate(pRegion, -xoff, -yoff);
}
return ret;
}
-
/**
* Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
*
@@ -1262,45 +1255,46 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
* the pixmap out of framebuffer.
*/
void
-exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d)
+exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
{
- ExaScreenPriv (pDrawable->pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaScreenPriv(pDrawable->pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
+
ExaPixmapPriv(pPix);
int xoff, yoff;
Bool ok;
if (pExaScr->fallback_counter || pExaScr->swappedOut)
- goto fallback;
+ goto fallback;
/* If there's a system copy, we want to save the result there */
if (pExaPixmap->pDamage)
- goto fallback;
+ goto fallback;
- pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+ pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);
if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
- goto fallback;
+ goto fallback;
/* Only cover the ZPixmap, solid copy case. */
if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
- goto fallback;
+ goto fallback;
/* Only try to handle the 8bpp and up cases, since we don't want to think
* about <8bpp.
*/
if (pDrawable->bitsPerPixel < 8)
- goto fallback;
+ goto fallback;
ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
- pDrawable->y + y + yoff, w, h, d,
- PixmapBytePad(w, pDrawable->depth));
+ pDrawable->y + y + yoff, w, h, d,
+ PixmapBytePad(w, pDrawable->depth));
if (ok) {
- exaWaitSync(pDrawable->pScreen);
- return;
+ exaWaitSync(pDrawable->pScreen);
+ return;
}
-fallback:
+ fallback:
ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d);
}
diff --git a/xorg-server/exa/exa_classic.c b/xorg-server/exa/exa_classic.c
index 919b29df2..1fa534bc6 100644
--- a/xorg-server/exa/exa_classic.c
+++ b/xorg-server/exa/exa_classic.c
@@ -33,15 +33,15 @@
/* This file holds the classic exa specific implementation. */
-static _X_INLINE void*
+static _X_INLINE void *
ExaGetPixmapAddress(PixmapPtr p)
{
ExaPixmapPriv(p);
if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr)
- return pExaPixmap->fb_ptr;
+ return pExaPixmap->fb_ptr;
else
- return pExaPixmap->sys_ptr;
+ return pExaPixmap->sys_ptr;
}
/**
@@ -54,19 +54,20 @@ ExaGetPixmapAddress(PixmapPtr p)
*/
PixmapPtr
exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
+ unsigned usage_hint)
{
PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
+ ExaPixmapPrivPtr pExaPixmap;
BoxRec box;
int bpp;
+
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
- return NullPixmap;
+ return NullPixmap;
swap(pExaScr, pScreen, CreatePixmap);
- pPixmap = pScreen->CreatePixmap (pScreen, w, h, depth, usage_hint);
+ pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
swap(pExaScr, pScreen, CreatePixmap);
if (!pPixmap)
@@ -82,9 +83,9 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
* migrated.
*/
if (!w || !h)
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
else
- pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
pExaPixmap->sys_pitch = pPixmap->devKind;
@@ -97,28 +98,28 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
if (pExaPixmap->fb_pitch > 131071) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap (pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
+ swap(pExaScr, pScreen, DestroyPixmap);
+ pScreen->DestroyPixmap(pPixmap);
+ swap(pExaScr, pScreen, DestroyPixmap);
+ return NULL;
}
/* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate (NULL, NULL,
- DamageReportNone, TRUE,
- pScreen, pPixmap);
+ pExaPixmap->pDamage = DamageCreate(NULL, NULL,
+ DamageReportNone, TRUE,
+ pScreen, pPixmap);
if (pExaPixmap->pDamage == NULL) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap (pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
+ swap(pExaScr, pScreen, DestroyPixmap);
+ pScreen->DestroyPixmap(pPixmap);
+ swap(pExaScr, pScreen, DestroyPixmap);
+ return NULL;
}
- DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
/* This ensures that pending damage reflects the current operation. */
/* This is used by exa to optimize migration. */
- DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
+ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
pExaPixmap->area = NULL;
@@ -134,19 +135,19 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
RegionInit(&pExaPixmap->validSys, &box, 0);
RegionInit(&pExaPixmap->validFB, &box, 0);
- exaSetAccelBlock(pExaScr, pExaPixmap,
- w, h, bpp);
+ exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
/* During a fallback we must prepare access. */
if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
return pPixmap;
}
Bool
-exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData)
+exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData)
{
ScreenPtr pScreen;
ExaScreenPrivPtr pExaScr;
@@ -167,41 +168,39 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
if (devKind > 0)
pExaPixmap->sys_pitch = devKind;
- /* Classic EXA:
- * - Framebuffer.
- * - Scratch pixmap with gpu memory.
- */
- if (pExaScr->info->memoryBase && pPixData) {
- if ((CARD8 *)pPixData >= pExaScr->info->memoryBase &&
- ((CARD8 *)pPixData - pExaScr->info->memoryBase) <
- pExaScr->info->memorySize) {
- pExaPixmap->fb_ptr = pPixData;
- pExaPixmap->fb_pitch = devKind;
- pExaPixmap->use_gpu_copy = TRUE;
- }
- }
+ /* Classic EXA:
+ * - Framebuffer.
+ * - Scratch pixmap with gpu memory.
+ */
+ if (pExaScr->info->memoryBase && pPixData) {
+ if ((CARD8 *) pPixData >= pExaScr->info->memoryBase &&
+ ((CARD8 *) pPixData - pExaScr->info->memoryBase) <
+ pExaScr->info->memorySize) {
+ pExaPixmap->fb_ptr = pPixData;
+ pExaPixmap->fb_pitch = devKind;
+ pExaPixmap->use_gpu_copy = TRUE;
+ }
+ }
if (width > 0 && height > 0 && bitsPerPixel > 0) {
- exaSetFbPitch(pExaScr, pExaPixmap,
- width, height, bitsPerPixel);
+ exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
- exaSetAccelBlock(pExaScr, pExaPixmap,
- width, height, bitsPerPixel);
+ exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
}
- /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or
- * gpu memory, so there's no need to track damage.
- */
- if (pExaPixmap->pDamage) {
- DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- }
+ /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or
+ * gpu memory, so there's no need to track damage.
+ */
+ if (pExaPixmap->pDamage) {
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+ }
}
swap(pExaScr, pScreen, ModifyPixmapHeader);
ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
+ bitsPerPixel, devKind, pPixData);
swap(pExaScr, pScreen, ModifyPixmapHeader);
/* Always NULL this, we don't want lingering pointers. */
@@ -211,36 +210,34 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept
}
Bool
-exaDestroyPixmap_classic (PixmapPtr pPixmap)
+exaDestroyPixmap_classic(PixmapPtr pPixmap)
{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
Bool ret;
- if (pPixmap->refcnt == 1)
- {
- ExaPixmapPriv (pPixmap);
-
- exaDestroyPixmap(pPixmap);
-
- if (pExaPixmap->area)
- {
- DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
- (void*)pPixmap->drawable.id,
- ExaGetPixmapPriv(pPixmap)->area->offset,
- pPixmap->drawable.width,
- pPixmap->drawable.height));
- /* Free the offscreen area */
- exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area);
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- }
- RegionUninit(&pExaPixmap->validSys);
- RegionUninit(&pExaPixmap->validFB);
+ if (pPixmap->refcnt == 1) {
+ ExaPixmapPriv(pPixmap);
+
+ exaDestroyPixmap(pPixmap);
+
+ if (pExaPixmap->area) {
+ DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
+ (void *) pPixmap->drawable.id,
+ ExaGetPixmapPriv(pPixmap)->area->offset,
+ pPixmap->drawable.width, pPixmap->drawable.height));
+ /* Free the offscreen area */
+ exaOffscreenFree(pPixmap->drawable.pScreen, pExaPixmap->area);
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
+ }
+ RegionUninit(&pExaPixmap->validSys);
+ RegionUninit(&pExaPixmap->validFB);
}
swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap (pPixmap);
+ ret = pScreen->DestroyPixmap(pPixmap);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
@@ -250,17 +247,20 @@ Bool
exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
ExaPixmapPriv(pPixmap);
Bool ret;
if (pExaScr->info->PixmapIsOffscreen) {
- void* old_ptr = pPixmap->devPrivate.ptr;
- pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
- ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
- pPixmap->devPrivate.ptr = old_ptr;
- } else
- ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr);
+ void *old_ptr = pPixmap->devPrivate.ptr;
+
+ pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
+ ret = pExaScr->info->PixmapIsOffscreen(pPixmap);
+ pPixmap->devPrivate.ptr = old_ptr;
+ }
+ else
+ ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr);
return ret;
}
diff --git a/xorg-server/exa/exa_driver.c b/xorg-server/exa/exa_driver.c
index 795cb00cd..d467ca928 100644
--- a/xorg-server/exa/exa_driver.c
+++ b/xorg-server/exa/exa_driver.c
@@ -33,7 +33,7 @@
/* This file holds the driver allocated pixmaps specific implementation. */
-static _X_INLINE void*
+static _X_INLINE void *
ExaGetPixmapAddress(PixmapPtr p)
{
ExaPixmapPriv(p);
@@ -48,16 +48,17 @@ ExaGetPixmapAddress(PixmapPtr p)
*/
PixmapPtr
exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
+ unsigned usage_hint)
{
PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
+ ExaPixmapPrivPtr pExaPixmap;
int bpp;
size_t paddedWidth, datasize;
+
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
- return NullPixmap;
+ return NullPixmap;
swap(pExaScr, pScreen, CreatePixmap);
pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
@@ -77,28 +78,32 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
pPixmap->devPrivate.ptr = NULL;
if (pExaScr->info->CreatePixmap2) {
- int new_pitch = 0;
- pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch);
- paddedWidth = pExaPixmap->fb_pitch = new_pitch;
+ int new_pitch = 0;
+
+ pExaPixmap->driverPriv =
+ pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp,
+ &new_pitch);
+ paddedWidth = pExaPixmap->fb_pitch = new_pitch;
}
else {
- paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
- if (paddedWidth / 4 > 32767 || h > 32767)
- return NullPixmap;
+ paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ if (paddedWidth / 4 > 32767 || h > 32767)
+ return NullPixmap;
- exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
+ exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
- if (paddedWidth < pExaPixmap->fb_pitch)
- paddedWidth = pExaPixmap->fb_pitch;
- datasize = h * paddedWidth;
- pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, datasize, 0);
+ if (paddedWidth < pExaPixmap->fb_pitch)
+ paddedWidth = pExaPixmap->fb_pitch;
+ datasize = h * paddedWidth;
+ pExaPixmap->driverPriv =
+ pExaScr->info->CreatePixmap(pScreen, datasize, 0);
}
if (!pExaPixmap->driverPriv) {
- swap(pExaScr, pScreen, DestroyPixmap);
- pScreen->DestroyPixmap (pPixmap);
- swap(pExaScr, pScreen, DestroyPixmap);
- return NULL;
+ swap(pExaScr, pScreen, DestroyPixmap);
+ pScreen->DestroyPixmap(pPixmap);
+ swap(pExaScr, pScreen, DestroyPixmap);
+ return NULL;
}
/* Allow ModifyPixmapHeader to set sys_ptr appropriately. */
@@ -107,26 +112,25 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
pExaPixmap->pDamage = NULL;
pExaPixmap->sys_ptr = NULL;
- (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
- paddedWidth, NULL);
+ (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
pExaPixmap->area = NULL;
- exaSetAccelBlock(pExaScr, pExaPixmap,
- w, h, bpp);
+ exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
/* During a fallback we must prepare access. */
if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
return pPixmap;
}
Bool
-exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData)
+exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData)
{
ScreenPtr pScreen;
ExaScreenPrivPtr pExaScr;
@@ -148,36 +152,35 @@ exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth
pExaPixmap->sys_pitch = devKind;
if (width > 0 && height > 0 && bitsPerPixel > 0) {
- exaSetFbPitch(pExaScr, pExaPixmap,
- width, height, bitsPerPixel);
+ exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
- exaSetAccelBlock(pExaScr, pExaPixmap,
- width, height, bitsPerPixel);
+ exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
}
}
if (pExaScr->info->ModifyPixmapHeader) {
- ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
- /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
- * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
- * !has_gpu_copy pixmap. We need to store the pointer,
- * because PrepareAccess won't be called.
- */
- if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
- }
- if (ret == TRUE)
- goto out;
+ ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind,
+ pPixData);
+ /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
+ * If pPixmap->devPrivate.ptr is non-NULL, then we've got a
+ * !has_gpu_copy pixmap. We need to store the pointer,
+ * because PrepareAccess won't be called.
+ */
+ if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
+ }
+ if (ret == TRUE)
+ goto out;
}
swap(pExaScr, pScreen, ModifyPixmapHeader);
ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
+ bitsPerPixel, devKind, pPixData);
swap(pExaScr, pScreen, ModifyPixmapHeader);
-out:
+ out:
/* Always NULL this, we don't want lingering pointers. */
pPixmap->devPrivate.ptr = NULL;
@@ -185,25 +188,25 @@ out:
}
Bool
-exaDestroyPixmap_driver (PixmapPtr pPixmap)
+exaDestroyPixmap_driver(PixmapPtr pPixmap)
{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
Bool ret;
- if (pPixmap->refcnt == 1)
- {
- ExaPixmapPriv (pPixmap);
+ if (pPixmap->refcnt == 1) {
+ ExaPixmapPriv(pPixmap);
- exaDestroyPixmap(pPixmap);
+ exaDestroyPixmap(pPixmap);
- if (pExaPixmap->driverPriv)
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
+ if (pExaPixmap->driverPriv)
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
}
swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap (pPixmap);
+ ret = pScreen->DestroyPixmap(pPixmap);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
@@ -213,6 +216,7 @@ Bool
exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
pointer saved_ptr;
Bool ret;
diff --git a/xorg-server/exa/exa_glyphs.c b/xorg-server/exa/exa_glyphs.c
index 15ef61b1e..2538bce01 100644
--- a/xorg-server/exa/exa_glyphs.c
+++ b/xorg-server/exa/exa_glyphs.c
@@ -1,863 +1,839 @@
-/*
- * Copyright © 2008 Red Hat, Inc.
- * Partly based on code Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Red Hat not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Red Hat makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. SuSE makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Owen Taylor <otaylor@fishsoup.net>
- * Based on code by: Keith Packard
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdlib.h>
-
-#include "exa_priv.h"
-
-#include "mipict.h"
-
-#if DEBUG_GLYPH_CACHE
-#define DBG_GLYPH_CACHE(a) ErrorF a
-#else
-#define DBG_GLYPH_CACHE(a)
-#endif
-
-/* Width of the pixmaps we use for the caches; this should be less than
- * max texture size of the driver; this may need to actually come from
- * the driver.
- */
-#define CACHE_PICTURE_WIDTH 1024
-
-/* Maximum number of glyphs we buffer on the stack before flushing
- * rendering to the mask or destination surface.
- */
-#define GLYPH_BUFFER_SIZE 256
-
-typedef struct {
- PicturePtr mask;
- ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
- int count;
-} ExaGlyphBuffer, *ExaGlyphBufferPtr;
-
-typedef enum {
- ExaGlyphSuccess, /* Glyph added to render buffer */
- ExaGlyphFail, /* out of memory, etc */
- ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */
-} ExaGlyphCacheResult;
-
-void
-exaGlyphsInit(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- int i = 0;
-
- memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches));
-
- pExaScr->glyphCaches[i].format = PICT_a8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16;
- i++;
- pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
- pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32;
- i++;
-
- assert(i == EXA_NUM_GLYPH_CACHES);
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- pExaScr->glyphCaches[i].columns = CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth;
- pExaScr->glyphCaches[i].size = 256;
- pExaScr->glyphCaches[i].hashSize = 557;
- }
-}
-
-static void
-exaUnrealizeGlyphCaches(ScreenPtr pScreen,
- unsigned int format)
-{
- ExaScreenPriv(pScreen);
- int i;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (cache->format != format)
- continue;
-
- if (cache->picture) {
- FreePicture ((pointer) cache->picture, (XID) 0);
- cache->picture = NULL;
- }
-
- free(cache->hashEntries);
- cache->hashEntries = NULL;
-
- free(cache->glyphs);
- cache->glyphs = NULL;
- cache->glyphCount = 0;
- }
-}
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
-/* All caches for a single format share a single pixmap for glyph storage,
- * allowing mixing glyphs of different sizes without paying a penalty
- * for switching between mask pixmaps. (Note that for a size of font
- * right at the border between two sizes, we might be switching for almost
- * every glyph.)
- *
- * This function allocates the storage pixmap, and then fills in the
- * rest of the allocated structures for all caches with the given format.
- */
-static Bool
-exaRealizeGlyphCaches(ScreenPtr pScreen,
- unsigned int format)
-{
- ExaScreenPriv(pScreen);
-
- int depth = PIXMAN_FORMAT_DEPTH(format);
- PictFormatPtr pPictFormat;
- PixmapPtr pPixmap;
- PicturePtr pPicture;
- CARD32 component_alpha;
- int height;
- int i;
- int error;
-
- pPictFormat = PictureMatchFormat(pScreen, depth, format);
- if (!pPictFormat)
- return FALSE;
-
- /* Compute the total vertical size needed for the format */
-
- height = 0;
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
- int rows;
-
- if (cache->format != format)
- continue;
-
- cache->yOffset = height;
-
- rows = (cache->size + cache->columns - 1) / cache->columns;
- height += rows * cache->glyphHeight;
- }
-
- /* Now allocate the pixmap and picture */
- pPixmap = (*pScreen->CreatePixmap) (pScreen,
- CACHE_PICTURE_WIDTH,
- height, depth, 0);
- if (!pPixmap)
- return FALSE;
-
- component_alpha = NeedsComponent(pPictFormat->format);
- pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
- CPComponentAlpha, &component_alpha, serverClient,
- &error);
-
- (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */
-
- if (!pPicture)
- return FALSE;
-
- /* And store the picture in all the caches for the format */
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
- int j;
-
- if (cache->format != format)
- continue;
-
- cache->picture = pPicture;
- cache->picture->refcnt++;
- cache->hashEntries = malloc(sizeof(int) * cache->hashSize);
- cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * cache->size);
- cache->glyphCount = 0;
-
- if (!cache->hashEntries || !cache->glyphs)
- goto bail;
-
- for (j = 0; j < cache->hashSize; j++)
- cache->hashEntries[j] = -1;
-
- cache->evictionPosition = rand() % cache->size;
- }
-
- /* Each cache references the picture individually */
- FreePicture ((pointer) pPicture, (XID) 0);
- return TRUE;
-
-bail:
- exaUnrealizeGlyphCaches(pScreen, format);
- return FALSE;
-}
-
-void
-exaGlyphsFini (ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- int i;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (cache->picture)
- exaUnrealizeGlyphCaches(pScreen, cache->format);
- }
-}
-
-static int
-exaGlyphCacheHashLookup(ExaGlyphCachePtr cache,
- GlyphPtr pGlyph)
-{
- int slot;
-
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- int entryPos = cache->hashEntries[slot];
- if (entryPos == -1)
- return -1;
-
- if (memcmp(pGlyph->sha1, cache->glyphs[entryPos].sha1, sizeof(pGlyph->sha1)) == 0){
- return entryPos;
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-static void
-exaGlyphCacheHashInsert(ExaGlyphCachePtr cache,
- GlyphPtr pGlyph,
- int pos)
-{
- int slot;
-
- memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1));
-
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- if (cache->hashEntries[slot] == -1) {
- cache->hashEntries[slot] = pos;
- return;
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-static void
-exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
- int pos)
-{
- int slot;
- int emptiedSlot = -1;
-
- slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize;
-
- while (TRUE) { /* hash table can never be full */
- int entryPos = cache->hashEntries[slot];
-
- if (entryPos == -1)
- return;
-
- if (entryPos == pos) {
- cache->hashEntries[slot] = -1;
- emptiedSlot = slot;
- } else if (emptiedSlot != -1) {
- /* See if we can move this entry into the emptied slot, we can't
- * do that if if entry would have hashed between the current position
- * and the emptied slot. (taking wrapping into account). Bad positions
- * are:
- *
- * | XXXXXXXXXX |
- * i j
- *
- * |XXX XXXX|
- * j i
- *
- * i - slot, j - emptiedSlot
- *
- * (Knuth 6.4R)
- */
-
- int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize;
-
- if (!((entrySlot >= slot && entrySlot < emptiedSlot) ||
- (emptiedSlot < slot && (entrySlot < emptiedSlot || entrySlot >= slot))))
- {
- cache->hashEntries[emptiedSlot] = entryPos;
- cache->hashEntries[slot] = -1;
- emptiedSlot = slot;
- }
- }
-
- slot--;
- if (slot < 0)
- slot = cache->hashSize - 1;
- }
-}
-
-#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth)
-#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight)
-
-/* The most efficient thing to way to upload the glyph to the screen
- * is to use the UploadToScreen() driver hook; this allows us to
- * pipeline glyph uploads and to avoid creating gpu backed pixmaps for
- * glyphs that we'll never use again.
- *
- * If we can't do it with UploadToScreen (because the glyph has a gpu copy,
- * etc), we fall back to CompositePicture.
- *
- * We need to damage the cache pixmap manually in either case because the damage
- * layer unwrapped the picture screen before calling exaGlyphs.
- */
-static void
-exaGlyphCacheUploadGlyph(ScreenPtr pScreen,
- ExaGlyphCachePtr cache,
- int x,
- int y,
- GlyphPtr pGlyph)
-{
- ExaScreenPriv(pScreen);
- PicturePtr pGlyphPicture = GlyphPicture(pGlyph)[pScreen->myNum];
- PixmapPtr pGlyphPixmap = (PixmapPtr)pGlyphPicture->pDrawable;
- ExaPixmapPriv(pGlyphPixmap);
- PixmapPtr pCachePixmap = (PixmapPtr)cache->picture->pDrawable;
-
- if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaPixmap->accel_blocked)
- goto composite;
-
- /* If the glyph pixmap is already uploaded, no point in doing
- * things this way */
- if (exaPixmapHasGpuCopy(pGlyphPixmap))
- goto composite;
-
- /* UploadToScreen only works if bpp match */
- if (pGlyphPixmap->drawable.bitsPerPixel != pCachePixmap->drawable.bitsPerPixel)
- goto composite;
-
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- /* cache pixmap must have a gpu copy. */
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pCachePixmap;
- pixmaps[0].pReg = NULL;
- exaDoMigration (pixmaps, 1, TRUE);
- }
-
- if (!exaPixmapHasGpuCopy(pCachePixmap))
- goto composite;
-
- /* x,y are in pixmap coordinates, no need for cache{X,Y}off */
- if (pExaScr->info->UploadToScreen(pCachePixmap,
- x,
- y,
- pGlyph->info.width,
- pGlyph->info.height,
- (char *)pExaPixmap->sys_ptr,
- pExaPixmap->sys_pitch))
- goto damage;
-
-composite:
- CompositePicture (PictOpSrc,
- pGlyphPicture,
- None,
- cache->picture,
- 0, 0,
- 0, 0,
- x,
- y,
- pGlyph->info.width,
- pGlyph->info.height);
-
-damage:
- /* The cache pixmap isn't a window, so no need to offset coordinates. */
- exaPixmapDirty (pCachePixmap,
- x,
- y,
- x + cache->glyphWidth,
- y + cache->glyphHeight);
-}
-
-static ExaGlyphCacheResult
-exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
- ExaGlyphCachePtr cache,
- ExaGlyphBufferPtr buffer,
- GlyphPtr pGlyph,
- PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst)
-{
- ExaCompositeRectPtr rect;
- int pos;
- int x, y;
-
- if (buffer->mask && buffer->mask != cache->picture)
- return ExaGlyphNeedFlush;
-
- if (!cache->picture) {
- if (!exaRealizeGlyphCaches(pScreen, cache->format))
- return ExaGlyphFail;
- }
-
- DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n",
- cache->glyphWidth, cache->glyphHeight, cache->format == PICT_a8 ? "A" : "ARGB",
- (long)*(CARD32 *) pGlyph->sha1));
-
- pos = exaGlyphCacheHashLookup(cache, pGlyph);
- if (pos != -1) {
- DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos));
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- } else {
- if (cache->glyphCount < cache->size) {
- /* Space remaining; we fill from the start */
- pos = cache->glyphCount;
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- cache->glyphCount++;
- DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos));
-
- exaGlyphCacheHashInsert(cache, pGlyph, pos);
-
- } else {
- /* Need to evict an entry. We have to see if any glyphs
- * already in the output buffer were at this position in
- * the cache
- */
- pos = cache->evictionPosition;
- x = CACHE_X(pos);
- y = CACHE_Y(pos);
- DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos));
- if (buffer->count) {
- int i;
-
- for (i = 0; i < buffer->count; i++) {
- if (pSrc ?
- (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) :
- (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y)) {
- DBG_GLYPH_CACHE((" must flush buffer\n"));
- return ExaGlyphNeedFlush;
- }
- }
- }
-
- /* OK, we're all set, swap in the new glyph */
- exaGlyphCacheHashRemove(cache, pos);
- exaGlyphCacheHashInsert(cache, pGlyph, pos);
-
- /* And pick a new eviction position */
- cache->evictionPosition = rand() % cache->size;
- }
-
- exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph);
- }
-
- buffer->mask = cache->picture;
-
- rect = &buffer->rects[buffer->count];
-
- if (pSrc)
- {
- rect->xSrc = xSrc;
- rect->ySrc = ySrc;
- rect->xMask = x;
- rect->yMask = y;
- }
- else
- {
- rect->xSrc = x;
- rect->ySrc = y;
- rect->xMask = 0;
- rect->yMask = 0;
- }
-
- rect->pDst = pDst;
- rect->xDst = xDst;
- rect->yDst = yDst;
- rect->width = pGlyph->info.width;
- rect->height = pGlyph->info.height;
-
- buffer->count++;
-
- return ExaGlyphSuccess;
-}
-
-#undef CACHE_X
-#undef CACHE_Y
-
-static ExaGlyphCacheResult
-exaBufferGlyph(ScreenPtr pScreen,
- ExaGlyphBufferPtr buffer,
- GlyphPtr pGlyph,
- PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst)
-{
- ExaScreenPriv(pScreen);
- unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
- int width = pGlyph->info.width;
- int height = pGlyph->info.height;
- ExaCompositeRectPtr rect;
- PicturePtr mask;
- int i;
-
- if (buffer->count == GLYPH_BUFFER_SIZE)
- return ExaGlyphNeedFlush;
-
- if (PICT_FORMAT_BPP(format) == 1)
- format = PICT_a8;
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
-
- if (format == cache->format &&
- width <= cache->glyphWidth &&
- height <= cache->glyphHeight) {
- ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
- &pExaScr->glyphCaches[i],
- buffer,
- pGlyph,
- pSrc,
- pDst,
- xSrc, ySrc,
- xMask, yMask,
- xDst, yDst);
- switch (result) {
- case ExaGlyphFail:
- break;
- case ExaGlyphSuccess:
- case ExaGlyphNeedFlush:
- return result;
- }
- }
- }
-
- /* Couldn't find the glyph in the cache, use the glyph picture directly */
-
- mask = GlyphPicture(pGlyph)[pScreen->myNum];
- if (buffer->mask && buffer->mask != mask)
- return ExaGlyphNeedFlush;
-
- buffer->mask = mask;
-
- rect = &buffer->rects[buffer->count];
- rect->xSrc = xSrc;
- rect->ySrc = ySrc;
- rect->xMask = xMask;
- rect->yMask = yMask;
- rect->xDst = xDst;
- rect->yDst = yDst;
- rect->width = width;
- rect->height = height;
-
- buffer->count++;
-
- return ExaGlyphSuccess;
-}
-
-static void
-exaGlyphsToMask(PicturePtr pMask,
- ExaGlyphBufferPtr buffer)
-{
- exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
- buffer->count, buffer->rects);
-
- buffer->count = 0;
- buffer->mask = NULL;
-}
-
-static void
-exaGlyphsToDst(PicturePtr pSrc,
- PicturePtr pDst,
- ExaGlyphBufferPtr buffer)
-{
- exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
- buffer->rects);
-
- buffer->count = 0;
- buffer->mask = NULL;
-}
-
-/* Cut and paste from render/glyph.c - probably should export it instead */
-static void
-GlyphExtents (int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs,
- BoxPtr extents)
-{
- int x1, x2, y1, y2;
- int n;
- GlyphPtr glyph;
- int x, y;
-
- x = 0;
- y = 0;
- extents->x1 = MAXSHORT;
- extents->x2 = MINSHORT;
- extents->y1 = MAXSHORT;
- extents->y2 = MINSHORT;
- while (nlist--)
- {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- list++;
- while (n--)
- {
- glyph = *glyphs++;
- x1 = x - glyph->info.x;
- if (x1 < MINSHORT)
- x1 = MINSHORT;
- y1 = y - glyph->info.y;
- if (y1 < MINSHORT)
- y1 = MINSHORT;
- x2 = x1 + glyph->info.width;
- if (x2 > MAXSHORT)
- x2 = MAXSHORT;
- y2 = y1 + glyph->info.height;
- if (y2 > MAXSHORT)
- y2 = MAXSHORT;
- if (x1 < extents->x1)
- extents->x1 = x1;
- if (x2 > extents->x2)
- extents->x2 = x2;
- if (y1 < extents->y1)
- extents->y1 = y1;
- if (y2 > extents->y2)
- extents->y2 = y2;
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- }
-}
-
-void
-exaGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- PixmapPtr pMaskPixmap = 0;
- PicturePtr pMask = NULL;
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- int width = 0, height = 0;
- int x, y;
- int first_xOff = list->xOff, first_yOff = list->yOff;
- int n;
- GlyphPtr glyph;
- int error;
- BoxRec extents = {0, 0, 0, 0};
- CARD32 component_alpha;
- ExaGlyphBuffer buffer;
-
- if (maskFormat)
- {
- ExaScreenPriv(pScreen);
- GCPtr pGC;
- xRectangle rect;
-
- GlyphExtents (nlist, list, glyphs, &extents);
-
- if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
- return;
- width = extents.x2 - extents.x1;
- height = extents.y2 - extents.y1;
-
- if (maskFormat->depth == 1) {
- PictFormatPtr a8Format = PictureMatchFormat (pScreen, 8, PICT_a8);
-
- if (a8Format)
- maskFormat = a8Format;
- }
-
- pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- maskFormat->depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pMaskPixmap)
- return;
- component_alpha = NeedsComponent(maskFormat->format);
- pMask = CreatePicture (0, &pMaskPixmap->drawable,
- maskFormat, CPComponentAlpha, &component_alpha,
- serverClient, &error);
- if (!pMask ||
- (!component_alpha && pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, NULL, pMask)))
- {
- PictFormatPtr argbFormat;
-
- (*pScreen->DestroyPixmap) (pMaskPixmap);
-
- if (!pMask)
- return;
-
- /* The driver can't seem to composite to a8, let's try argb (but
- * without component-alpha) */
- FreePicture ((pointer) pMask, (XID) 0);
-
- argbFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
-
- if (argbFormat)
- maskFormat = argbFormat;
-
- pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- maskFormat->depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- if (!pMaskPixmap)
- return;
-
- pMask = CreatePicture (0, &pMaskPixmap->drawable, maskFormat, 0, 0,
- serverClient, &error);
- if (!pMask) {
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- return;
- }
- }
- pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
- ValidateGC (&pMaskPixmap->drawable, pGC);
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
- FreeScratchGC (pGC);
- x = -extents.x1;
- y = -extents.y1;
- }
- else
- {
- x = 0;
- y = 0;
- }
- buffer.count = 0;
- buffer.mask = NULL;
- while (nlist--)
- {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- while (n--)
- {
- glyph = *glyphs++;
-
- if (glyph->info.width > 0 && glyph->info.height > 0)
- {
- /* pGlyph->info.{x,y} compensate for empty space in the glyph. */
- if (maskFormat)
- {
- if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
- 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush)
- {
- exaGlyphsToMask(pMask, &buffer);
- exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
- 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y);
- }
- }
- else
- {
- if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
- xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff,
- 0, 0, x - glyph->info.x, y - glyph->info.y)
- == ExaGlyphNeedFlush)
- {
- exaGlyphsToDst(pSrc, pDst, &buffer);
- exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
- xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff,
- 0, 0, x - glyph->info.x, y - glyph->info.y);
- }
- }
- }
-
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- }
-
- if (buffer.count) {
- if (maskFormat)
- exaGlyphsToMask(pMask, &buffer);
- else
- exaGlyphsToDst(pSrc, pDst, &buffer);
- }
-
- if (maskFormat)
- {
- x = extents.x1;
- y = extents.y1;
- CompositePicture (op,
- pSrc,
- pMask,
- pDst,
- xSrc + x - first_xOff,
- ySrc + y - first_yOff,
- 0, 0,
- x, y,
- width, height);
- FreePicture ((pointer) pMask, (XID) 0);
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- }
-}
+/*
+ * Copyright © 2008 Red Hat, Inc.
+ * Partly based on code Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Red Hat not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Red Hat makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Owen Taylor <otaylor@fishsoup.net>
+ * Based on code by: Keith Packard
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "exa_priv.h"
+
+#include "mipict.h"
+
+#if DEBUG_GLYPH_CACHE
+#define DBG_GLYPH_CACHE(a) ErrorF a
+#else
+#define DBG_GLYPH_CACHE(a)
+#endif
+
+/* Width of the pixmaps we use for the caches; this should be less than
+ * max texture size of the driver; this may need to actually come from
+ * the driver.
+ */
+#define CACHE_PICTURE_WIDTH 1024
+
+/* Maximum number of glyphs we buffer on the stack before flushing
+ * rendering to the mask or destination surface.
+ */
+#define GLYPH_BUFFER_SIZE 256
+
+typedef struct {
+ PicturePtr mask;
+ ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
+ int count;
+} ExaGlyphBuffer, *ExaGlyphBufferPtr;
+
+typedef enum {
+ ExaGlyphSuccess, /* Glyph added to render buffer */
+ ExaGlyphFail, /* out of memory, etc */
+ ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */
+} ExaGlyphCacheResult;
+
+void
+exaGlyphsInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ int i = 0;
+
+ memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches));
+
+ pExaScr->glyphCaches[i].format = PICT_a8;
+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
+ 16;
+ i++;
+ pExaScr->glyphCaches[i].format = PICT_a8;
+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
+ 32;
+ i++;
+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
+ 16;
+ i++;
+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8;
+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight =
+ 32;
+ i++;
+
+ assert(i == EXA_NUM_GLYPH_CACHES);
+
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ pExaScr->glyphCaches[i].columns =
+ CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth;
+ pExaScr->glyphCaches[i].size = 256;
+ pExaScr->glyphCaches[i].hashSize = 557;
+ }
+}
+
+static void
+exaUnrealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
+{
+ ExaScreenPriv(pScreen);
+ int i;
+
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
+
+ if (cache->format != format)
+ continue;
+
+ if (cache->picture) {
+ FreePicture((pointer) cache->picture, (XID) 0);
+ cache->picture = NULL;
+ }
+
+ free(cache->hashEntries);
+ cache->hashEntries = NULL;
+
+ free(cache->glyphs);
+ cache->glyphs = NULL;
+ cache->glyphCount = 0;
+ }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+/* All caches for a single format share a single pixmap for glyph storage,
+ * allowing mixing glyphs of different sizes without paying a penalty
+ * for switching between mask pixmaps. (Note that for a size of font
+ * right at the border between two sizes, we might be switching for almost
+ * every glyph.)
+ *
+ * This function allocates the storage pixmap, and then fills in the
+ * rest of the allocated structures for all caches with the given format.
+ */
+static Bool
+exaRealizeGlyphCaches(ScreenPtr pScreen, unsigned int format)
+{
+ ExaScreenPriv(pScreen);
+
+ int depth = PIXMAN_FORMAT_DEPTH(format);
+ PictFormatPtr pPictFormat;
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ CARD32 component_alpha;
+ int height;
+ int i;
+ int error;
+
+ pPictFormat = PictureMatchFormat(pScreen, depth, format);
+ if (!pPictFormat)
+ return FALSE;
+
+ /* Compute the total vertical size needed for the format */
+
+ height = 0;
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
+ int rows;
+
+ if (cache->format != format)
+ continue;
+
+ cache->yOffset = height;
+
+ rows = (cache->size + cache->columns - 1) / cache->columns;
+ height += rows * cache->glyphHeight;
+ }
+
+ /* Now allocate the pixmap and picture */
+ pPixmap = (*pScreen->CreatePixmap) (pScreen,
+ CACHE_PICTURE_WIDTH, height, depth, 0);
+ if (!pPixmap)
+ return FALSE;
+
+ component_alpha = NeedsComponent(pPictFormat->format);
+ pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
+ CPComponentAlpha, &component_alpha, serverClient,
+ &error);
+
+ (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */
+
+ if (!pPicture)
+ return FALSE;
+
+ /* And store the picture in all the caches for the format */
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
+ int j;
+
+ if (cache->format != format)
+ continue;
+
+ cache->picture = pPicture;
+ cache->picture->refcnt++;
+ cache->hashEntries = malloc(sizeof(int) * cache->hashSize);
+ cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * cache->size);
+ cache->glyphCount = 0;
+
+ if (!cache->hashEntries || !cache->glyphs)
+ goto bail;
+
+ for (j = 0; j < cache->hashSize; j++)
+ cache->hashEntries[j] = -1;
+
+ cache->evictionPosition = rand() % cache->size;
+ }
+
+ /* Each cache references the picture individually */
+ FreePicture((pointer) pPicture, (XID) 0);
+ return TRUE;
+
+ bail:
+ exaUnrealizeGlyphCaches(pScreen, format);
+ return FALSE;
+}
+
+void
+exaGlyphsFini(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ int i;
+
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
+
+ if (cache->picture)
+ exaUnrealizeGlyphCaches(pScreen, cache->format);
+ }
+}
+
+static int
+exaGlyphCacheHashLookup(ExaGlyphCachePtr cache, GlyphPtr pGlyph)
+{
+ int slot;
+
+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
+
+ while (TRUE) { /* hash table can never be full */
+ int entryPos = cache->hashEntries[slot];
+
+ if (entryPos == -1)
+ return -1;
+
+ if (memcmp
+ (pGlyph->sha1, cache->glyphs[entryPos].sha1,
+ sizeof(pGlyph->sha1)) == 0) {
+ return entryPos;
+ }
+
+ slot--;
+ if (slot < 0)
+ slot = cache->hashSize - 1;
+ }
+}
+
+static void
+exaGlyphCacheHashInsert(ExaGlyphCachePtr cache, GlyphPtr pGlyph, int pos)
+{
+ int slot;
+
+ memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1));
+
+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
+
+ while (TRUE) { /* hash table can never be full */
+ if (cache->hashEntries[slot] == -1) {
+ cache->hashEntries[slot] = pos;
+ return;
+ }
+
+ slot--;
+ if (slot < 0)
+ slot = cache->hashSize - 1;
+ }
+}
+
+static void
+exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, int pos)
+{
+ int slot;
+ int emptiedSlot = -1;
+
+ slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize;
+
+ while (TRUE) { /* hash table can never be full */
+ int entryPos = cache->hashEntries[slot];
+
+ if (entryPos == -1)
+ return;
+
+ if (entryPos == pos) {
+ cache->hashEntries[slot] = -1;
+ emptiedSlot = slot;
+ }
+ else if (emptiedSlot != -1) {
+ /* See if we can move this entry into the emptied slot, we can't
+ * do that if if entry would have hashed between the current position
+ * and the emptied slot. (taking wrapping into account). Bad positions
+ * are:
+ *
+ * | XXXXXXXXXX |
+ * i j
+ *
+ * |XXX XXXX|
+ * j i
+ *
+ * i - slot, j - emptiedSlot
+ *
+ * (Knuth 6.4R)
+ */
+
+ int entrySlot =
+ (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize;
+
+ if (!((entrySlot >= slot && entrySlot < emptiedSlot) ||
+ (emptiedSlot < slot &&
+ (entrySlot < emptiedSlot || entrySlot >= slot)))) {
+ cache->hashEntries[emptiedSlot] = entryPos;
+ cache->hashEntries[slot] = -1;
+ emptiedSlot = slot;
+ }
+ }
+
+ slot--;
+ if (slot < 0)
+ slot = cache->hashSize - 1;
+ }
+}
+
+#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth)
+#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight)
+
+/* The most efficient thing to way to upload the glyph to the screen
+ * is to use the UploadToScreen() driver hook; this allows us to
+ * pipeline glyph uploads and to avoid creating gpu backed pixmaps for
+ * glyphs that we'll never use again.
+ *
+ * If we can't do it with UploadToScreen (because the glyph has a gpu copy,
+ * etc), we fall back to CompositePicture.
+ *
+ * We need to damage the cache pixmap manually in either case because the damage
+ * layer unwrapped the picture screen before calling exaGlyphs.
+ */
+static void
+exaGlyphCacheUploadGlyph(ScreenPtr pScreen,
+ ExaGlyphCachePtr cache, int x, int y, GlyphPtr pGlyph)
+{
+ ExaScreenPriv(pScreen);
+ PicturePtr pGlyphPicture = GlyphPicture(pGlyph)[pScreen->myNum];
+ PixmapPtr pGlyphPixmap = (PixmapPtr) pGlyphPicture->pDrawable;
+
+ ExaPixmapPriv(pGlyphPixmap);
+ PixmapPtr pCachePixmap = (PixmapPtr) cache->picture->pDrawable;
+
+ if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut ||
+ pExaPixmap->accel_blocked)
+ goto composite;
+
+ /* If the glyph pixmap is already uploaded, no point in doing
+ * things this way */
+ if (exaPixmapHasGpuCopy(pGlyphPixmap))
+ goto composite;
+
+ /* UploadToScreen only works if bpp match */
+ if (pGlyphPixmap->drawable.bitsPerPixel !=
+ pCachePixmap->drawable.bitsPerPixel)
+ goto composite;
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[1];
+
+ /* cache pixmap must have a gpu copy. */
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pCachePixmap;
+ pixmaps[0].pReg = NULL;
+ exaDoMigration(pixmaps, 1, TRUE);
+ }
+
+ if (!exaPixmapHasGpuCopy(pCachePixmap))
+ goto composite;
+
+ /* x,y are in pixmap coordinates, no need for cache{X,Y}off */
+ if (pExaScr->info->UploadToScreen(pCachePixmap,
+ x,
+ y,
+ pGlyph->info.width,
+ pGlyph->info.height,
+ (char *) pExaPixmap->sys_ptr,
+ pExaPixmap->sys_pitch))
+ goto damage;
+
+ composite:
+ CompositePicture(PictOpSrc,
+ pGlyphPicture,
+ None,
+ cache->picture,
+ 0, 0, 0, 0, x, y, pGlyph->info.width, pGlyph->info.height);
+
+ damage:
+ /* The cache pixmap isn't a window, so no need to offset coordinates. */
+ exaPixmapDirty(pCachePixmap,
+ x, y, x + cache->glyphWidth, y + cache->glyphHeight);
+}
+
+static ExaGlyphCacheResult
+exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
+ ExaGlyphCachePtr cache,
+ ExaGlyphBufferPtr buffer,
+ GlyphPtr pGlyph,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst)
+{
+ ExaCompositeRectPtr rect;
+ int pos;
+ int x, y;
+
+ if (buffer->mask && buffer->mask != cache->picture)
+ return ExaGlyphNeedFlush;
+
+ if (!cache->picture) {
+ if (!exaRealizeGlyphCaches(pScreen, cache->format))
+ return ExaGlyphFail;
+ }
+
+ DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n",
+ cache->glyphWidth, cache->glyphHeight,
+ cache->format == PICT_a8 ? "A" : "ARGB",
+ (long) *(CARD32 *) pGlyph->sha1));
+
+ pos = exaGlyphCacheHashLookup(cache, pGlyph);
+ if (pos != -1) {
+ DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos));
+ x = CACHE_X(pos);
+ y = CACHE_Y(pos);
+ }
+ else {
+ if (cache->glyphCount < cache->size) {
+ /* Space remaining; we fill from the start */
+ pos = cache->glyphCount;
+ x = CACHE_X(pos);
+ y = CACHE_Y(pos);
+ cache->glyphCount++;
+ DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos));
+
+ exaGlyphCacheHashInsert(cache, pGlyph, pos);
+
+ }
+ else {
+ /* Need to evict an entry. We have to see if any glyphs
+ * already in the output buffer were at this position in
+ * the cache
+ */
+ pos = cache->evictionPosition;
+ x = CACHE_X(pos);
+ y = CACHE_Y(pos);
+ DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos));
+ if (buffer->count) {
+ int i;
+
+ for (i = 0; i < buffer->count; i++) {
+ if (pSrc ?
+ (buffer->rects[i].xMask == x &&
+ buffer->rects[i].yMask ==
+ y) : (buffer->rects[i].xSrc == x &&
+ buffer->rects[i].ySrc == y)) {
+ DBG_GLYPH_CACHE((" must flush buffer\n"));
+ return ExaGlyphNeedFlush;
+ }
+ }
+ }
+
+ /* OK, we're all set, swap in the new glyph */
+ exaGlyphCacheHashRemove(cache, pos);
+ exaGlyphCacheHashInsert(cache, pGlyph, pos);
+
+ /* And pick a new eviction position */
+ cache->evictionPosition = rand() % cache->size;
+ }
+
+ exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph);
+ }
+
+ buffer->mask = cache->picture;
+
+ rect = &buffer->rects[buffer->count];
+
+ if (pSrc) {
+ rect->xSrc = xSrc;
+ rect->ySrc = ySrc;
+ rect->xMask = x;
+ rect->yMask = y;
+ }
+ else {
+ rect->xSrc = x;
+ rect->ySrc = y;
+ rect->xMask = 0;
+ rect->yMask = 0;
+ }
+
+ rect->pDst = pDst;
+ rect->xDst = xDst;
+ rect->yDst = yDst;
+ rect->width = pGlyph->info.width;
+ rect->height = pGlyph->info.height;
+
+ buffer->count++;
+
+ return ExaGlyphSuccess;
+}
+
+#undef CACHE_X
+#undef CACHE_Y
+
+static ExaGlyphCacheResult
+exaBufferGlyph(ScreenPtr pScreen,
+ ExaGlyphBufferPtr buffer,
+ GlyphPtr pGlyph,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst, INT16 yDst)
+{
+ ExaScreenPriv(pScreen);
+ unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
+ int width = pGlyph->info.width;
+ int height = pGlyph->info.height;
+ ExaCompositeRectPtr rect;
+ PicturePtr mask;
+ int i;
+
+ if (buffer->count == GLYPH_BUFFER_SIZE)
+ return ExaGlyphNeedFlush;
+
+ if (PICT_FORMAT_BPP(format) == 1)
+ format = PICT_a8;
+
+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i];
+
+ if (format == cache->format &&
+ width <= cache->glyphWidth && height <= cache->glyphHeight) {
+ ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
+ &pExaScr->
+ glyphCaches
+ [i],
+ buffer,
+ pGlyph,
+ pSrc,
+ pDst,
+ xSrc, ySrc,
+ xMask, yMask,
+ xDst, yDst);
+
+ switch (result) {
+ case ExaGlyphFail:
+ break;
+ case ExaGlyphSuccess:
+ case ExaGlyphNeedFlush:
+ return result;
+ }
+ }
+ }
+
+ /* Couldn't find the glyph in the cache, use the glyph picture directly */
+
+ mask = GlyphPicture(pGlyph)[pScreen->myNum];
+ if (buffer->mask && buffer->mask != mask)
+ return ExaGlyphNeedFlush;
+
+ buffer->mask = mask;
+
+ rect = &buffer->rects[buffer->count];
+ rect->xSrc = xSrc;
+ rect->ySrc = ySrc;
+ rect->xMask = xMask;
+ rect->yMask = yMask;
+ rect->xDst = xDst;
+ rect->yDst = yDst;
+ rect->width = width;
+ rect->height = height;
+
+ buffer->count++;
+
+ return ExaGlyphSuccess;
+}
+
+static void
+exaGlyphsToMask(PicturePtr pMask, ExaGlyphBufferPtr buffer)
+{
+ exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
+ buffer->count, buffer->rects);
+
+ buffer->count = 0;
+ buffer->mask = NULL;
+}
+
+static void
+exaGlyphsToDst(PicturePtr pSrc, PicturePtr pDst, ExaGlyphBufferPtr buffer)
+{
+ exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
+ buffer->rects);
+
+ buffer->count = 0;
+ buffer->mask = NULL;
+}
+
+/* Cut and paste from render/glyph.c - probably should export it instead */
+static void
+GlyphExtents(int nlist, GlyphListPtr list, GlyphPtr * glyphs, BoxPtr extents)
+{
+ int x1, x2, y1, y2;
+ int n;
+ GlyphPtr glyph;
+ int x, y;
+
+ x = 0;
+ y = 0;
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+ while (n--) {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+}
+
+void
+exaGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
+{
+ PixmapPtr pMaskPixmap = 0;
+ PicturePtr pMask = NULL;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ int width = 0, height = 0;
+ int x, y;
+ int first_xOff = list->xOff, first_yOff = list->yOff;
+ int n;
+ GlyphPtr glyph;
+ int error;
+ BoxRec extents = { 0, 0, 0, 0 };
+ CARD32 component_alpha;
+ ExaGlyphBuffer buffer;
+
+ if (maskFormat) {
+ ExaScreenPriv(pScreen);
+ GCPtr pGC;
+ xRectangle rect;
+
+ GlyphExtents(nlist, list, glyphs, &extents);
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+ width = extents.x2 - extents.x1;
+ height = extents.y2 - extents.y1;
+
+ if (maskFormat->depth == 1) {
+ PictFormatPtr a8Format = PictureMatchFormat(pScreen, 8, PICT_a8);
+
+ if (a8Format)
+ maskFormat = a8Format;
+ }
+
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ maskFormat->depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pMaskPixmap)
+ return;
+ component_alpha = NeedsComponent(maskFormat->format);
+ pMask = CreatePicture(0, &pMaskPixmap->drawable,
+ maskFormat, CPComponentAlpha, &component_alpha,
+ serverClient, &error);
+ if (!pMask ||
+ (!component_alpha && pExaScr->info->CheckComposite &&
+ !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, NULL, pMask)))
+ {
+ PictFormatPtr argbFormat;
+
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+
+ if (!pMask)
+ return;
+
+ /* The driver can't seem to composite to a8, let's try argb (but
+ * without component-alpha) */
+ FreePicture((pointer) pMask, (XID) 0);
+
+ argbFormat = PictureMatchFormat(pScreen, 32, PICT_a8r8g8b8);
+
+ if (argbFormat)
+ maskFormat = argbFormat;
+
+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ maskFormat->depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pMaskPixmap)
+ return;
+
+ pMask = CreatePicture(0, &pMaskPixmap->drawable, maskFormat, 0, 0,
+ serverClient, &error);
+ if (!pMask) {
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ return;
+ }
+ }
+ pGC = GetScratchGC(pMaskPixmap->drawable.depth, pScreen);
+ ValidateGC(&pMaskPixmap->drawable, pGC);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC(pGC);
+ x = -extents.x1;
+ y = -extents.y1;
+ }
+ else {
+ x = 0;
+ y = 0;
+ }
+ buffer.count = 0;
+ buffer.mask = NULL;
+ while (nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ while (n--) {
+ glyph = *glyphs++;
+
+ if (glyph->info.width > 0 && glyph->info.height > 0) {
+ /* pGlyph->info.{x,y} compensate for empty space in the glyph. */
+ if (maskFormat) {
+ if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+ 0, 0, 0, 0, x - glyph->info.x,
+ y - glyph->info.y) ==
+ ExaGlyphNeedFlush) {
+ exaGlyphsToMask(pMask, &buffer);
+ exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+ 0, 0, 0, 0, x - glyph->info.x,
+ y - glyph->info.y);
+ }
+ }
+ else {
+ if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+ xSrc + (x - glyph->info.x) - first_xOff,
+ ySrc + (y - glyph->info.y) - first_yOff,
+ 0, 0, x - glyph->info.x,
+ y - glyph->info.y)
+ == ExaGlyphNeedFlush) {
+ exaGlyphsToDst(pSrc, pDst, &buffer);
+ exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+ xSrc + (x - glyph->info.x) - first_xOff,
+ ySrc + (y - glyph->info.y) - first_yOff,
+ 0, 0, x - glyph->info.x,
+ y - glyph->info.y);
+ }
+ }
+ }
+
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ list++;
+ }
+
+ if (buffer.count) {
+ if (maskFormat)
+ exaGlyphsToMask(pMask, &buffer);
+ else
+ exaGlyphsToDst(pSrc, pDst, &buffer);
+ }
+
+ if (maskFormat) {
+ x = extents.x1;
+ y = extents.y1;
+ CompositePicture(op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + x - first_xOff,
+ ySrc + y - first_yOff, 0, 0, x, y, width, height);
+ FreePicture((pointer) pMask, (XID) 0);
+ (*pScreen->DestroyPixmap) (pMaskPixmap);
+ }
+}
diff --git a/xorg-server/exa/exa_migration_classic.c b/xorg-server/exa/exa_migration_classic.c
index dd3cd491e..e890f6754 100644
--- a/xorg-server/exa/exa_migration_classic.c
+++ b/xorg-server/exa/exa_migration_classic.c
@@ -46,9 +46,9 @@
* and exaCopyDirtyToFb both needed to do this loop.
*/
static void
-exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
- CARD8 *dst, int dst_pitch)
- {
+exaMemcpyBox(PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
+ CARD8 *dst, int dst_pitch)
+{
int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
int bytes = (pbox->x2 - pbox->x1) * cpp;
@@ -56,9 +56,9 @@ exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
for (i = pbox->y2 - pbox->y1; i; i--) {
- memcpy (dst, src, bytes);
- src += src_pitch;
- dst += dst_pitch;
+ memcpy(dst, src, bytes);
+ src += src_pitch;
+ dst += dst_pitch;
}
}
@@ -68,18 +68,18 @@ exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
* dirtiness.
*/
static Bool
-exaPixmapIsDirty (PixmapPtr pPix)
+exaPixmapIsDirty(PixmapPtr pPix)
{
- ExaPixmapPriv (pPix);
+ ExaPixmapPriv(pPix);
if (pExaPixmap == NULL)
- EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
if (!pExaPixmap->pDamage)
- return FALSE;
+ return FALSE;
return RegionNotEmpty(DamageRegion(pExaPixmap->pDamage)) ||
- !RegionEqual(&pExaPixmap->validSys, &pExaPixmap->validFB);
+ !RegionEqual(&pExaPixmap->validSys, &pExaPixmap->validFB);
}
/**
@@ -90,12 +90,12 @@ exaPixmapIsDirty (PixmapPtr pPix)
* Only valid if using a migration scheme that tracks score.
*/
static Bool
-exaPixmapShouldBeInFB (PixmapPtr pPix)
+exaPixmapShouldBeInFB(PixmapPtr pPix)
{
- ExaPixmapPriv (pPix);
+ ExaPixmapPriv(pPix);
- if (exaPixmapIsPinned (pPix))
- return TRUE;
+ if (exaPixmapIsPinned(pPix))
+ return TRUE;
return pExaPixmap->score >= 0;
}
@@ -106,13 +106,14 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
*/
static void
exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
- Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
- char *sys, int sys_pitch), int fallback_index,
- void (*sync) (ScreenPtr pScreen))
+ Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
+ char *sys, int sys_pitch), int fallback_index,
+ void (*sync) (ScreenPtr pScreen))
{
PixmapPtr pPixmap = migrate->pPix;
- ExaPixmapPriv (pPixmap);
- RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
+
+ ExaPixmapPriv(pPixmap);
+ RegionPtr damage = DamageRegion(pExaPixmap->pDamage);
RegionRec CopyReg;
Bool save_use_gpu_copy;
int save_pitch;
@@ -123,15 +124,12 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
/* Damaged bits are valid in current copy but invalid in other one */
if (pExaPixmap->use_gpu_copy) {
- RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB,
- damage);
- RegionSubtract(&pExaPixmap->validSys, &pExaPixmap->validSys,
- damage);
- } else {
- RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys,
- damage);
- RegionSubtract(&pExaPixmap->validFB, &pExaPixmap->validFB,
- damage);
+ RegionUnion(&pExaPixmap->validFB, &pExaPixmap->validFB, damage);
+ RegionSubtract(&pExaPixmap->validSys, &pExaPixmap->validSys, damage);
+ }
+ else {
+ RegionUnion(&pExaPixmap->validSys, &pExaPixmap->validSys, damage);
+ RegionSubtract(&pExaPixmap->validFB, &pExaPixmap->validFB, damage);
}
RegionEmpty(damage);
@@ -141,63 +139,65 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
RegionSubtract(&CopyReg, pValidSrc, pValidDst);
if (migrate->as_dst) {
- ExaScreenPriv (pPixmap->drawable.pScreen);
+ ExaScreenPriv(pPixmap->drawable.pScreen);
- /* XXX: The pending damage region will be marked as damaged after the
- * operation, so it should serve as an upper bound for the region that
- * needs to be synchronized for the operation. Unfortunately, this
- * causes corruption in some cases, e.g. when starting compiz. See
- * https://bugs.freedesktop.org/show_bug.cgi?id=12916 .
- */
- if (pExaScr->optimize_migration) {
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ /* XXX: The pending damage region will be marked as damaged after the
+ * operation, so it should serve as an upper bound for the region that
+ * needs to be synchronized for the operation. Unfortunately, this
+ * causes corruption in some cases, e.g. when starting compiz. See
+ * https://bugs.freedesktop.org/show_bug.cgi?id=12916 .
+ */
+ if (pExaScr->optimize_migration) {
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
#if DEBUG_MIGRATE
- if (RegionNil(pending_damage)) {
- static Bool firsttime = TRUE;
-
- if (firsttime) {
- ErrorF("%s: Pending damage region empty!\n", __func__);
- firsttime = FALSE;
- }
- }
+ if (RegionNil(pending_damage)) {
+ static Bool firsttime = TRUE;
+
+ if (firsttime) {
+ ErrorF("%s: Pending damage region empty!\n", __func__);
+ firsttime = FALSE;
+ }
+ }
#endif
- /* Try to prevent destination valid region from growing too many
- * rects by filling it up to the extents of the union of the
- * destination valid region and the pending damage region.
- */
- if (RegionNumRects(pValidDst) > 10) {
- BoxRec box;
- BoxPtr pValidExt, pDamageExt;
- RegionRec closure;
-
- pValidExt = RegionExtents(pValidDst);
- pDamageExt = RegionExtents(pending_damage);
-
- box.x1 = min(pValidExt->x1, pDamageExt->x1);
- box.y1 = min(pValidExt->y1, pDamageExt->y1);
- box.x2 = max(pValidExt->x2, pDamageExt->x2);
- box.y2 = max(pValidExt->y2, pDamageExt->y2);
-
- RegionInit(&closure, &box, 0);
- RegionIntersect(&CopyReg, &CopyReg, &closure);
- } else
- RegionIntersect(&CopyReg, &CopyReg, pending_damage);
- }
-
- /* The caller may provide a region to be subtracted from the calculated
- * dirty region. This is to avoid migration of bits that don't
- * contribute to the result of the operation.
- */
- if (migrate->pReg)
- RegionSubtract(&CopyReg, &CopyReg, migrate->pReg);
- } else {
- /* The caller may restrict the region to be migrated for source pixmaps
- * to what's relevant for the operation.
- */
- if (migrate->pReg)
- RegionIntersect(&CopyReg, &CopyReg, migrate->pReg);
+ /* Try to prevent destination valid region from growing too many
+ * rects by filling it up to the extents of the union of the
+ * destination valid region and the pending damage region.
+ */
+ if (RegionNumRects(pValidDst) > 10) {
+ BoxRec box;
+ BoxPtr pValidExt, pDamageExt;
+ RegionRec closure;
+
+ pValidExt = RegionExtents(pValidDst);
+ pDamageExt = RegionExtents(pending_damage);
+
+ box.x1 = min(pValidExt->x1, pDamageExt->x1);
+ box.y1 = min(pValidExt->y1, pDamageExt->y1);
+ box.x2 = max(pValidExt->x2, pDamageExt->x2);
+ box.y2 = max(pValidExt->y2, pDamageExt->y2);
+
+ RegionInit(&closure, &box, 0);
+ RegionIntersect(&CopyReg, &CopyReg, &closure);
+ }
+ else
+ RegionIntersect(&CopyReg, &CopyReg, pending_damage);
+ }
+
+ /* The caller may provide a region to be subtracted from the calculated
+ * dirty region. This is to avoid migration of bits that don't
+ * contribute to the result of the operation.
+ */
+ if (migrate->pReg)
+ RegionSubtract(&CopyReg, &CopyReg, migrate->pReg);
+ }
+ else {
+ /* The caller may restrict the region to be migrated for source pixmaps
+ * to what's relevant for the operation.
+ */
+ if (migrate->pReg)
+ RegionIntersect(&CopyReg, &CopyReg, migrate->pReg);
}
pBox = RegionRects(&CopyReg);
@@ -209,40 +209,43 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
pPixmap->devKind = pExaPixmap->fb_pitch;
while (nbox--) {
- pBox->x1 = max(pBox->x1, 0);
- pBox->y1 = max(pBox->y1, 0);
- pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
- pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
-
- if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
- continue;
-
- if (!transfer || !transfer (pPixmap,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- (char *) (pExaPixmap->sys_ptr
- + pBox->y1 * pExaPixmap->sys_pitch
- + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8),
- pExaPixmap->sys_pitch))
- {
- if (!access_prepared) {
- ExaDoPrepareAccess(pPixmap, fallback_index);
- access_prepared = TRUE;
- }
- if (fallback_index == EXA_PREPARE_DEST) {
- exaMemcpyBox (pPixmap, pBox,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
- pPixmap->devPrivate.ptr, pPixmap->devKind);
- } else {
- exaMemcpyBox (pPixmap, pBox,
- pPixmap->devPrivate.ptr, pPixmap->devKind,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
- }
- } else
- need_sync = TRUE;
-
- pBox++;
+ pBox->x1 = max(pBox->x1, 0);
+ pBox->y1 = max(pBox->y1, 0);
+ pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
+ pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
+
+ if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
+ continue;
+
+ if (!transfer || !transfer(pPixmap,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ (char *) (pExaPixmap->sys_ptr
+ + pBox->y1 * pExaPixmap->sys_pitch
+ +
+ pBox->x1 *
+ pPixmap->drawable.bitsPerPixel /
+ 8), pExaPixmap->sys_pitch)) {
+ if (!access_prepared) {
+ ExaDoPrepareAccess(pPixmap, fallback_index);
+ access_prepared = TRUE;
+ }
+ if (fallback_index == EXA_PREPARE_DEST) {
+ exaMemcpyBox(pPixmap, pBox,
+ pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
+ pPixmap->devPrivate.ptr, pPixmap->devKind);
+ }
+ else {
+ exaMemcpyBox(pPixmap, pBox,
+ pPixmap->devPrivate.ptr, pPixmap->devKind,
+ pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
+ }
+ }
+ else
+ need_sync = TRUE;
+
+ pBox++;
}
pExaPixmap->use_gpu_copy = save_use_gpu_copy;
@@ -253,7 +256,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
* Removing anything beyond that would lead to data loss.
*/
if (RegionNumRects(pValidSrc) > 20)
- RegionSubtract(pValidSrc, pValidSrc, pValidDst);
+ RegionSubtract(pValidSrc, pValidSrc, pValidDst);
/* The copied bits are now valid in destination */
RegionUnion(pValidDst, pValidDst, &CopyReg);
@@ -261,9 +264,9 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
RegionUninit(&CopyReg);
if (access_prepared)
- exaFinishAccess(&pPixmap->drawable, fallback_index);
+ exaFinishAccess(&pPixmap->drawable, fallback_index);
else if (need_sync && sync)
- sync (pPixmap->drawable.pScreen);
+ sync(pPixmap->drawable.pScreen);
}
/**
@@ -272,15 +275,16 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
* allocated.
*/
void
-exaCopyDirtyToSys (ExaMigrationPtr migrate)
+exaCopyDirtyToSys(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
- ExaScreenPriv (pPixmap->drawable.pScreen);
- ExaPixmapPriv (pPixmap);
+
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+ ExaPixmapPriv(pPixmap);
exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
- pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC,
- exaWaitSync);
+ pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC,
+ exaWaitSync);
}
/**
@@ -289,14 +293,15 @@ exaCopyDirtyToSys (ExaMigrationPtr migrate)
* allocated.
*/
void
-exaCopyDirtyToFb (ExaMigrationPtr migrate)
+exaCopyDirtyToFb(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
- ExaScreenPriv (pPixmap->drawable.pScreen);
- ExaPixmapPriv (pPixmap);
+
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+ ExaPixmapPriv(pPixmap);
exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
- pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL);
+ pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL);
}
/**
@@ -315,54 +320,55 @@ exaCopyDirtyToFb (ExaMigrationPtr migrate)
* all the data, since it's almost surely all valid now.
*/
static void
-exaDoMoveInPixmap (ExaMigrationPtr migrate)
+exaDoMoveInPixmap(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ExaScreenPriv (pScreen);
- ExaPixmapPriv (pPixmap);
+
+ ExaScreenPriv(pScreen);
+ ExaPixmapPriv(pPixmap);
/* If we're VT-switched away, no touching card memory allowed. */
if (pExaScr->swappedOut)
- return;
+ return;
/* If we're not allowed to move, then fail. */
if (exaPixmapIsPinned(pPixmap))
- return;
+ return;
/* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of
* fragility in EXA, and <8bpp is probably not used enough any more to care
* (at least, not in acceleratd paths).
*/
if (pPixmap->drawable.bitsPerPixel < 8)
- return;
+ return;
if (pExaPixmap->accel_blocked)
- return;
+ return;
if (pExaPixmap->area == NULL) {
- pExaPixmap->area =
- exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
- pExaScr->info->pixmapOffsetAlign, FALSE,
- exaPixmapSave, (pointer) pPixmap);
- if (pExaPixmap->area == NULL)
- return;
-
- pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
- pExaPixmap->area->offset;
+ pExaPixmap->area =
+ exaOffscreenAlloc(pScreen, pExaPixmap->fb_size,
+ pExaScr->info->pixmapOffsetAlign, FALSE,
+ exaPixmapSave, (pointer) pPixmap);
+ if (pExaPixmap->area == NULL)
+ return;
+
+ pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
+ pExaPixmap->area->offset;
}
- exaCopyDirtyToFb (migrate);
+ exaCopyDirtyToFb(migrate);
if (exaPixmapHasGpuCopy(pPixmap))
- return;
+ return;
- DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
- (ExaGetPixmapPriv(pPixmap)->area ?
- ExaGetPixmapPriv(pPixmap)->area->offset : 0),
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+ DBG_MIGRATE(("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
+ (ExaGetPixmapPriv(pPixmap)->area ?
+ ExaGetPixmapPriv(pPixmap)->area->offset : 0),
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
pExaPixmap->use_gpu_copy = TRUE;
@@ -371,13 +377,14 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
}
void
-exaMoveInPixmap_classic (PixmapPtr pPixmap)
+exaMoveInPixmap_classic(PixmapPtr pPixmap)
{
- static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
- .pReg = NULL };
+ static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE,
+ .pReg = NULL
+ };
migrate.pPix = pPixmap;
- exaDoMoveInPixmap (&migrate);
+ exaDoMoveInPixmap(&migrate);
}
/**
@@ -385,52 +392,54 @@ exaMoveInPixmap_classic (PixmapPtr pPixmap)
* updated data out if necessary.
*/
static void
-exaDoMoveOutPixmap (ExaMigrationPtr migrate)
+exaDoMoveOutPixmap(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
- ExaPixmapPriv (pPixmap);
+
+ ExaPixmapPriv(pPixmap);
if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
- return;
+ return;
- exaCopyDirtyToSys (migrate);
+ exaCopyDirtyToSys(migrate);
if (exaPixmapHasGpuCopy(pPixmap)) {
- DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
- (void*)(ExaGetPixmapPriv(pPixmap)->area ?
- ExaGetPixmapPriv(pPixmap)->area->offset : 0),
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+ DBG_MIGRATE(("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
+ (void *) (ExaGetPixmapPriv(pPixmap)->area ?
+ ExaGetPixmapPriv(pPixmap)->area->offset : 0),
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
- pExaPixmap->use_gpu_copy = FALSE;
+ pExaPixmap->use_gpu_copy = FALSE;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
}
void
-exaMoveOutPixmap_classic (PixmapPtr pPixmap)
+exaMoveOutPixmap_classic(PixmapPtr pPixmap)
{
- static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
- .pReg = NULL };
+ static ExaMigrationRec migrate = {.as_dst = FALSE,.as_src = TRUE,
+ .pReg = NULL
+ };
migrate.pPix = pPixmap;
- exaDoMoveOutPixmap (&migrate);
+ exaDoMoveOutPixmap(&migrate);
}
-
/**
* Copies out important pixmap data and removes references to framebuffer area.
* Called when the memory manager decides it's time to kick the pixmap out of
* framebuffer entirely.
*/
void
-exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
+exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area)
{
PixmapPtr pPixmap = area->privData;
+
ExaPixmapPriv(pPixmap);
exaMoveOutPixmap(pPixmap);
@@ -448,39 +457,40 @@ exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
* framebuffer memory.
*/
static void
-exaMigrateTowardFb (ExaMigrationPtr migrate)
+exaMigrateTowardFb(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
- ExaPixmapPriv (pPixmap);
+
+ ExaPixmapPriv(pPixmap);
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
- DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
- (pointer)pPixmap));
- return;
+ DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
+ (pointer) pPixmap));
+ return;
}
DBG_MIGRATE(("UseScreen %p score %d\n",
- (pointer)pPixmap, pExaPixmap->score));
+ (pointer) pPixmap, pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
- exaDoMoveInPixmap(migrate);
- pExaPixmap->score = 0;
+ exaDoMoveInPixmap(migrate);
+ pExaPixmap->score = 0;
}
if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
- pExaPixmap->score++;
+ pExaPixmap->score++;
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
- !exaPixmapHasGpuCopy(pPixmap))
- {
- exaDoMoveInPixmap(migrate);
+ !exaPixmapHasGpuCopy(pPixmap)) {
+ exaDoMoveInPixmap(migrate);
}
if (exaPixmapHasGpuCopy(pPixmap)) {
- exaCopyDirtyToFb (migrate);
- ExaOffscreenMarkUsed (pPixmap);
- } else
- exaCopyDirtyToSys (migrate);
+ exaCopyDirtyToFb(migrate);
+ ExaOffscreenMarkUsed(pPixmap);
+ }
+ else
+ exaCopyDirtyToSys(migrate);
}
/**
@@ -488,30 +498,33 @@ exaMigrateTowardFb (ExaMigrationPtr migrate)
* system memory.
*/
static void
-exaMigrateTowardSys (ExaMigrationPtr migrate)
+exaMigrateTowardSys(ExaMigrationPtr migrate)
{
PixmapPtr pPixmap = migrate->pPix;
- ExaPixmapPriv (pPixmap);
- DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score));
+ ExaPixmapPriv(pPixmap);
+
+ DBG_MIGRATE(("UseMem: %p score %d\n", (pointer) pPixmap,
+ pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
- return;
+ return;
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT)
- pExaPixmap->score = 0;
+ pExaPixmap->score = 0;
if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN)
- pExaPixmap->score--;
+ pExaPixmap->score--;
if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
- exaDoMoveOutPixmap(migrate);
+ exaDoMoveOutPixmap(migrate);
if (exaPixmapHasGpuCopy(pPixmap)) {
- exaCopyDirtyToFb (migrate);
- ExaOffscreenMarkUsed (pPixmap);
- } else
- exaCopyDirtyToSys (migrate);
+ exaCopyDirtyToFb(migrate);
+ ExaOffscreenMarkUsed(pPixmap);
+ }
+ else
+ exaCopyDirtyToSys(migrate);
}
/**
@@ -519,9 +532,9 @@ exaMigrateTowardSys (ExaMigrationPtr migrate)
* asserts that both of them are the same.
*/
static Bool
-exaAssertNotDirty (PixmapPtr pPixmap)
+exaAssertNotDirty(PixmapPtr pPixmap)
{
- ExaPixmapPriv (pPixmap);
+ ExaPixmapPriv(pPixmap);
CARD8 *dst, *src;
RegionRec ValidReg;
int dst_pitch, src_pitch, cpp, y, nbox, save_pitch;
@@ -529,15 +542,14 @@ exaAssertNotDirty (PixmapPtr pPixmap)
Bool ret = TRUE, save_use_gpu_copy;
if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
- return ret;
+ return ret;
RegionNull(&ValidReg);
- RegionIntersect(&ValidReg, &pExaPixmap->validFB,
- &pExaPixmap->validSys);
+ RegionIntersect(&ValidReg, &pExaPixmap->validFB, &pExaPixmap->validSys);
nbox = RegionNumRects(&ValidReg);
if (!nbox)
- goto out;
+ goto out;
pBox = RegionRects(&ValidReg);
@@ -551,41 +563,42 @@ exaAssertNotDirty (PixmapPtr pPixmap)
pPixmap->devKind = pExaPixmap->fb_pitch;
if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
- goto skip;
+ goto skip;
while (nbox--) {
- int rowbytes;
-
- pBox->x1 = max(pBox->x1, 0);
- pBox->y1 = max(pBox->y1, 0);
- pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
- pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
-
- if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
- continue;
-
- rowbytes = (pBox->x2 - pBox->x1) * cpp;
- src = (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
- dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
-
- for (y = pBox->y1; y < pBox->y2;
- y++, src += src_pitch, dst += dst_pitch) {
- if (memcmp(dst, src, rowbytes) != 0) {
- ret = FALSE;
- exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
- pBox->y2);
- break;
- }
- }
+ int rowbytes;
+
+ pBox->x1 = max(pBox->x1, 0);
+ pBox->y1 = max(pBox->y1, 0);
+ pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
+ pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
+
+ if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
+ continue;
+
+ rowbytes = (pBox->x2 - pBox->x1) * cpp;
+ src =
+ (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch +
+ pBox->x1 * cpp;
+ dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
+
+ for (y = pBox->y1; y < pBox->y2;
+ y++, src += src_pitch, dst += dst_pitch) {
+ if (memcmp(dst, src, rowbytes) != 0) {
+ ret = FALSE;
+ exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ break;
+ }
+ }
}
-skip:
+ skip:
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
pExaPixmap->use_gpu_copy = save_use_gpu_copy;
pPixmap->devKind = save_pitch;
-out:
+ out:
RegionUninit(&ValidReg);
return ret;
}
@@ -596,9 +609,10 @@ out:
* config file.
*/
void
-exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
+exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
{
ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
+
ExaScreenPriv(pScreen);
int i, j;
@@ -610,117 +624,118 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
* to the pixmap last shouldn't be hard.
*/
if (pExaScr->checkDirtyCorrectness) {
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapIsDirty (pixmaps[i].pPix) &&
- !exaAssertNotDirty (pixmaps[i].pPix))
- ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __func__, i);
- }
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapIsDirty(pixmaps[i].pPix) &&
+ !exaAssertNotDirty(pixmaps[i].pPix))
+ ErrorF("%s: Pixmap %d dirty but not marked as such!\n",
+ __func__, i);
+ }
}
/* If anything is pinned in system memory, we won't be able to
* accelerate.
*/
for (i = 0; i < npixmaps; i++) {
- if (exaPixmapIsPinned (pixmaps[i].pPix) &&
- !exaPixmapHasGpuCopy (pixmaps[i].pPix))
- {
- EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
- pixmaps[i].pPix->drawable.width,
- pixmaps[i].pPix->drawable.height));
- can_accel = FALSE;
- break;
- }
+ if (exaPixmapIsPinned(pixmaps[i].pPix) &&
+ !exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
+ pixmaps[i].pPix->drawable.width,
+ pixmaps[i].pPix->drawable.height));
+ can_accel = FALSE;
+ break;
+ }
}
if (pExaScr->migration == ExaMigrationSmart) {
- /* If we've got something as a destination that we shouldn't cause to
- * become newly dirtied, take the unaccelerated route.
- */
- for (i = 0; i < npixmaps; i++) {
- if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) &&
- !exaPixmapIsDirty (pixmaps[i].pPix))
- {
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapIsDirty (pixmaps[i].pPix))
- exaDoMoveOutPixmap (pixmaps + i);
- }
- return;
- }
- }
-
- /* If we aren't going to accelerate, then we migrate everybody toward
- * system memory, and kick out if it's free.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardSys (pixmaps + i);
- if (!exaPixmapIsDirty (pixmaps[i].pPix))
- exaDoMoveOutPixmap (pixmaps + i);
- }
- return;
- }
-
- /* Finally, the acceleration path. Move them all in. */
- for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardFb(pixmaps + i);
- exaDoMoveInPixmap(pixmaps + i);
- }
- } else if (pExaScr->migration == ExaMigrationGreedy) {
- /* If we can't accelerate, either because the driver can't or because one of
- * the pixmaps is pinned in system memory, then we migrate everybody toward
- * system memory.
- *
- * We also migrate toward system if all pixmaps involved are currently in
- * system memory -- this can mitigate thrashing when there are significantly
- * more pixmaps active than would fit in memory.
- *
- * If not, then we migrate toward FB so that hopefully acceleration can
- * happen.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys (pixmaps + i);
- return;
- }
-
- for (i = 0; i < npixmaps; i++) {
- if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- /* Found one in FB, so move all to FB. */
- for (j = 0; j < npixmaps; j++)
- exaMigrateTowardFb(pixmaps + i);
- return;
- }
- }
-
- /* Nobody's in FB, so move all away from FB. */
- for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys(pixmaps + i);
- } else if (pExaScr->migration == ExaMigrationAlways) {
- /* Always move the pixmaps out if we can't accelerate. If we can
- * accelerate, try to move them all in. If that fails, then move them
- * back out.
- */
- if (!can_accel) {
- for (i = 0; i < npixmaps; i++)
- exaDoMoveOutPixmap(pixmaps + i);
- return;
- }
-
- /* Now, try to move them all into FB */
- for (i = 0; i < npixmaps; i++) {
- exaDoMoveInPixmap(pixmaps + i);
- }
-
- /* If we couldn't fit everything in, abort */
- for (i = 0; i < npixmaps; i++) {
- if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
- return;
- }
- }
-
- /* Yay, everything has a gpu copy, mark memory as used */
- for (i = 0; i < npixmaps; i++) {
- ExaOffscreenMarkUsed (pixmaps[i].pPix);
- }
+ /* If we've got something as a destination that we shouldn't cause to
+ * become newly dirtied, take the unaccelerated route.
+ */
+ for (i = 0; i < npixmaps; i++) {
+ if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB(pixmaps[i].pPix) &&
+ !exaPixmapIsDirty(pixmaps[i].pPix)) {
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapIsDirty(pixmaps[i].pPix))
+ exaDoMoveOutPixmap(pixmaps + i);
+ }
+ return;
+ }
+ }
+
+ /* If we aren't going to accelerate, then we migrate everybody toward
+ * system memory, and kick out if it's free.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++) {
+ exaMigrateTowardSys(pixmaps + i);
+ if (!exaPixmapIsDirty(pixmaps[i].pPix))
+ exaDoMoveOutPixmap(pixmaps + i);
+ }
+ return;
+ }
+
+ /* Finally, the acceleration path. Move them all in. */
+ for (i = 0; i < npixmaps; i++) {
+ exaMigrateTowardFb(pixmaps + i);
+ exaDoMoveInPixmap(pixmaps + i);
+ }
+ }
+ else if (pExaScr->migration == ExaMigrationGreedy) {
+ /* If we can't accelerate, either because the driver can't or because one of
+ * the pixmaps is pinned in system memory, then we migrate everybody toward
+ * system memory.
+ *
+ * We also migrate toward system if all pixmaps involved are currently in
+ * system memory -- this can mitigate thrashing when there are significantly
+ * more pixmaps active than would fit in memory.
+ *
+ * If not, then we migrate toward FB so that hopefully acceleration can
+ * happen.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys(pixmaps + i);
+ return;
+ }
+
+ for (i = 0; i < npixmaps; i++) {
+ if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ /* Found one in FB, so move all to FB. */
+ for (j = 0; j < npixmaps; j++)
+ exaMigrateTowardFb(pixmaps + i);
+ return;
+ }
+ }
+
+ /* Nobody's in FB, so move all away from FB. */
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys(pixmaps + i);
+ }
+ else if (pExaScr->migration == ExaMigrationAlways) {
+ /* Always move the pixmaps out if we can't accelerate. If we can
+ * accelerate, try to move them all in. If that fails, then move them
+ * back out.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaDoMoveOutPixmap(pixmaps + i);
+ return;
+ }
+
+ /* Now, try to move them all into FB */
+ for (i = 0; i < npixmaps; i++) {
+ exaDoMoveInPixmap(pixmaps + i);
+ }
+
+ /* If we couldn't fit everything in, abort */
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ return;
+ }
+ }
+
+ /* Yay, everything has a gpu copy, mark memory as used */
+ for (i = 0; i < npixmaps; i++) {
+ ExaOffscreenMarkUsed(pixmaps[i].pPix);
+ }
}
}
@@ -730,16 +745,17 @@ exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg)
ExaMigrationRec pixmaps[1];
if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- } else {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ }
+ else {
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
}
pixmaps[0].pPix = pPixmap;
pixmaps[0].pReg = pReg;
exaDoMigration(pixmaps, 1, FALSE);
- (void)ExaDoPrepareAccess(pPixmap, index);
+ (void) ExaDoPrepareAccess(pPixmap, index);
}
diff --git a/xorg-server/exa/exa_migration_mixed.c b/xorg-server/exa/exa_migration_mixed.c
index 4b2261943..445c4fcbf 100644
--- a/xorg-server/exa/exa_migration_mixed.c
+++ b/xorg-server/exa/exa_migration_mixed.c
@@ -35,6 +35,7 @@ void
exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
ExaPixmapPriv(pPixmap);
int w = pPixmap->drawable.width, h = pPixmap->drawable.height;
@@ -44,30 +45,34 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap)
/* Already done. */
if (pExaPixmap->driverPriv)
- return;
+ return;
if (exaPixmapIsPinned(pPixmap))
- return;
+ return;
/* Can't accel 1/4 bpp. */
if (pExaPixmap->accel_blocked || bpp < 8)
- return;
+ return;
if (pExaScr->info->CreatePixmap2) {
- int new_pitch = 0;
- pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch);
- paddedWidth = pExaPixmap->fb_pitch = new_pitch;
- } else {
- if (paddedWidth < pExaPixmap->fb_pitch)
- paddedWidth = pExaPixmap->fb_pitch;
- pExaPixmap->driverPriv = pExaScr->info->CreatePixmap(pScreen, paddedWidth*h, 0);
+ int new_pitch = 0;
+
+ pExaPixmap->driverPriv =
+ pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp,
+ &new_pitch);
+ paddedWidth = pExaPixmap->fb_pitch = new_pitch;
+ }
+ else {
+ if (paddedWidth < pExaPixmap->fb_pitch)
+ paddedWidth = pExaPixmap->fb_pitch;
+ pExaPixmap->driverPriv =
+ pExaScr->info->CreatePixmap(pScreen, paddedWidth * h, 0);
}
if (!pExaPixmap->driverPriv)
- return;
+ return;
- (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
- paddedWidth, NULL);
+ (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
}
void
@@ -79,45 +84,45 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
* accelerate.
*/
for (i = 0; i < npixmaps; i++) {
- if (exaPixmapIsPinned (pixmaps[i].pPix) &&
- !exaPixmapHasGpuCopy (pixmaps[i].pPix))
- {
- can_accel = FALSE;
- break;
- }
+ if (exaPixmapIsPinned(pixmaps[i].pPix) &&
+ !exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ can_accel = FALSE;
+ break;
+ }
}
/* We can do nothing. */
if (!can_accel)
- return;
+ return;
for (i = 0; i < npixmaps; i++) {
- PixmapPtr pPixmap = pixmaps[i].pPix;
- ExaPixmapPriv(pPixmap);
-
- if (!pExaPixmap->driverPriv)
- exaCreateDriverPixmap_mixed(pPixmap);
-
- if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- /* This pitch is needed for proper acceleration. For some reason
- * there are pixmaps without pDamage and a bad fb_pitch value.
- * So setting devKind when only exaPixmapHasGpuCopy() is true
- * causes corruption. Pixmaps without pDamage are not migrated
- * and should have a valid devKind at all times, so that's why this
- * isn't causing problems. Pixmaps have their gpu pitch set the
- * first time in the MPH call from exaCreateDriverPixmap_mixed().
- */
- pPixmap->devKind = pExaPixmap->fb_pitch;
- exaCopyDirtyToFb(pixmaps + i);
-
- if (pExaScr->deferred_mixed_pixmap == pPixmap &&
- !pixmaps[i].as_dst && !pixmaps[i].pReg)
- pExaScr->deferred_mixed_pixmap = NULL;
- }
-
- pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+ PixmapPtr pPixmap = pixmaps[i].pPix;
+
+ ExaPixmapPriv(pPixmap);
+
+ if (!pExaPixmap->driverPriv)
+ exaCreateDriverPixmap_mixed(pPixmap);
+
+ if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) {
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
+ /* This pitch is needed for proper acceleration. For some reason
+ * there are pixmaps without pDamage and a bad fb_pitch value.
+ * So setting devKind when only exaPixmapHasGpuCopy() is true
+ * causes corruption. Pixmaps without pDamage are not migrated
+ * and should have a valid devKind at all times, so that's why this
+ * isn't causing problems. Pixmaps have their gpu pitch set the
+ * first time in the MPH call from exaCreateDriverPixmap_mixed().
+ */
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ exaCopyDirtyToFb(pixmaps + i);
+
+ if (pExaScr->deferred_mixed_pixmap == pPixmap &&
+ !pixmaps[i].as_dst && !pixmaps[i].pReg)
+ pExaScr->deferred_mixed_pixmap = NULL;
+ }
+
+ pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
}
}
@@ -138,6 +143,7 @@ void
exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
{
PixmapPtr pPixmap = closure;
+
ExaPixmapPriv(pPixmap);
/* Move back results of software rendering on system memory copy of mixed driver
@@ -147,12 +153,12 @@ exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
* overhead on multiple subsequent software fallbacks.
*/
if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
+ ExaScreenPriv(pPixmap->drawable.pScreen);
- if (pExaScr->deferred_mixed_pixmap &&
- pExaScr->deferred_mixed_pixmap != pPixmap)
- exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
- pExaScr->deferred_mixed_pixmap = pPixmap;
+ if (pExaScr->deferred_mixed_pixmap &&
+ pExaScr->deferred_mixed_pixmap != pPixmap)
+ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+ pExaScr->deferred_mixed_pixmap = pPixmap;
}
}
@@ -171,91 +177,92 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
success = ExaDoPrepareAccess(pPixmap, index);
if (success && has_gpu_copy && pExaPixmap->pDamage) {
- /* You cannot do accelerated operations while a buffer is mapped. */
- exaFinishAccess(&pPixmap->drawable, index);
- /* Update the gpu view of both deferred destination pixmaps and of
- * source pixmaps that were migrated with a bounding region.
- */
- exaMoveInPixmap_mixed(pPixmap);
- success = ExaDoPrepareAccess(pPixmap, index);
-
- if (success) {
- /* We have a gpu pixmap that can be accessed, we don't need the cpu
- * copy anymore. Drivers that prefer DFS, should fail prepare
- * access.
- */
- DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
-
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
-
- return;
- }
+ /* You cannot do accelerated operations while a buffer is mapped. */
+ exaFinishAccess(&pPixmap->drawable, index);
+ /* Update the gpu view of both deferred destination pixmaps and of
+ * source pixmaps that were migrated with a bounding region.
+ */
+ exaMoveInPixmap_mixed(pPixmap);
+ success = ExaDoPrepareAccess(pPixmap, index);
+
+ if (success) {
+ /* We have a gpu pixmap that can be accessed, we don't need the cpu
+ * copy anymore. Drivers that prefer DFS, should fail prepare
+ * access.
+ */
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+
+ free(pExaPixmap->sys_ptr);
+ pExaPixmap->sys_ptr = NULL;
+
+ return;
+ }
}
if (!success) {
- ExaMigrationRec pixmaps[1];
-
- /* Do we need to allocate our system buffer? */
- if (!pExaPixmap->sys_ptr) {
- pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
- pPixmap->drawable.height);
- if (!pExaPixmap->sys_ptr)
- FatalError("EXA: malloc failed for size %d bytes\n",
- pExaPixmap->sys_pitch * pPixmap->drawable.height);
- }
-
- if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- } else {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- }
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = pReg;
-
- if (!pExaPixmap->pDamage &&
- (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
- Bool as_dst = pixmaps[0].as_dst;
-
- /* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
- DamageReportNonEmpty, TRUE,
- pPixmap->drawable.pScreen,
- pPixmap);
-
- DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
- /* This ensures that pending damage reflects the current operation. */
- /* This is used by exa to optimize migration. */
- DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
-
- if (has_gpu_copy) {
- exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
- pPixmap->drawable.height);
-
- /* We don't know which region of the destination will be damaged,
- * have to assume all of it
- */
- if (as_dst) {
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pReg = NULL;
- }
- exaCopyDirtyToSys(pixmaps);
- }
-
- if (as_dst)
- exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
- pPixmap->drawable.height);
- } else if (has_gpu_copy)
- exaCopyDirtyToSys(pixmaps);
-
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- pExaPixmap->use_gpu_copy = FALSE;
+ ExaMigrationRec pixmaps[1];
+
+ /* Do we need to allocate our system buffer? */
+ if (!pExaPixmap->sys_ptr) {
+ pExaPixmap->sys_ptr = malloc(pExaPixmap->sys_pitch *
+ pPixmap->drawable.height);
+ if (!pExaPixmap->sys_ptr)
+ FatalError("EXA: malloc failed for size %d bytes\n",
+ pExaPixmap->sys_pitch * pPixmap->drawable.height);
+ }
+
+ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ }
+ else {
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
+ }
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = pReg;
+
+ if (!pExaPixmap->pDamage &&
+ (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
+ Bool as_dst = pixmaps[0].as_dst;
+
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
+ DamageReportNonEmpty, TRUE,
+ pPixmap->drawable.pScreen,
+ pPixmap);
+
+ DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+ /* This ensures that pending damage reflects the current operation. */
+ /* This is used by exa to optimize migration. */
+ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+
+ if (has_gpu_copy) {
+ exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
+ pPixmap->drawable.height);
+
+ /* We don't know which region of the destination will be damaged,
+ * have to assume all of it
+ */
+ if (as_dst) {
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
+ pixmaps[0].pReg = NULL;
+ }
+ exaCopyDirtyToSys(pixmaps);
+ }
+
+ if (as_dst)
+ exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
+ pPixmap->drawable.height);
+ }
+ else if (has_gpu_copy)
+ exaCopyDirtyToSys(pixmaps);
+
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
+ pExaPixmap->use_gpu_copy = FALSE;
}
}
-
diff --git a/xorg-server/exa/exa_mixed.c b/xorg-server/exa/exa_mixed.c
index 0b1a4a4a4..06817313f 100644
--- a/xorg-server/exa/exa_mixed.c
+++ b/xorg-server/exa/exa_mixed.c
@@ -34,7 +34,7 @@
/* This file holds the driver allocated pixmaps + better initial placement code.
*/
-static _X_INLINE void*
+static _X_INLINE void *
ExaGetPixmapAddress(PixmapPtr p)
{
ExaPixmapPriv(p);
@@ -47,16 +47,17 @@ ExaGetPixmapAddress(PixmapPtr p)
*/
PixmapPtr
exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
+ unsigned usage_hint)
{
PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
+ ExaPixmapPrivPtr pExaPixmap;
int bpp;
size_t paddedWidth;
+
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
- return NullPixmap;
+ return NullPixmap;
swap(pExaScr, pScreen, CreatePixmap);
pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint);
@@ -84,45 +85,44 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
pExaPixmap->pDamage = NULL;
exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp);
- exaSetAccelBlock(pExaScr, pExaPixmap,
- w, h, bpp);
+ exaSetAccelBlock(pExaScr, pExaPixmap, w, h, bpp);
- (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
- paddedWidth, NULL);
+ (*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, paddedWidth, NULL);
/* A scratch pixmap will become a driver pixmap right away. */
if (!w || !h) {
- exaCreateDriverPixmap_mixed(pPixmap);
- pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- } else {
- pExaPixmap->use_gpu_copy = FALSE;
-
- if (w == 1 && h == 1) {
- pExaPixmap->sys_ptr = malloc(paddedWidth);
-
- /* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
- DamageReportNonEmpty, TRUE,
- pPixmap->drawable.pScreen,
- pPixmap);
-
- DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
- /* This ensures that pending damage reflects the current operation. */
- /* This is used by exa to optimize migration. */
- DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
- }
+ exaCreateDriverPixmap_mixed(pPixmap);
+ pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
+ }
+ else {
+ pExaPixmap->use_gpu_copy = FALSE;
+
+ if (w == 1 && h == 1) {
+ pExaPixmap->sys_ptr = malloc(paddedWidth);
+
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
+ DamageReportNonEmpty, TRUE,
+ pPixmap->drawable.pScreen,
+ pPixmap);
+
+ DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+ /* This ensures that pending damage reflects the current operation. */
+ /* This is used by exa to optimize migration. */
+ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+ }
}
/* During a fallback we must prepare access. */
if (pExaScr->fallback_counter)
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
return pPixmap;
}
Bool
exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData)
+ int bitsPerPixel, int devKind, pointer pPixData)
{
ScreenPtr pScreen;
ExaScreenPrivPtr pExaScr;
@@ -137,100 +137,102 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
pExaPixmap = ExaGetPixmapPriv(pPixmap);
if (pPixData) {
- if (pExaPixmap->driverPriv) {
- if (pExaPixmap->pDamage) {
- DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- }
-
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
- }
-
- pExaPixmap->use_gpu_copy = FALSE;
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ if (pExaPixmap->driverPriv) {
+ if (pExaPixmap->pDamage) {
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+ }
+
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
+ }
+
+ pExaPixmap->use_gpu_copy = FALSE;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
}
has_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
if (width <= 0)
- width = pPixmap->drawable.width;
+ width = pPixmap->drawable.width;
if (height <= 0)
- height = pPixmap->drawable.height;
+ height = pPixmap->drawable.height;
if (bitsPerPixel <= 0) {
- if (depth <= 0)
- bitsPerPixel = pPixmap->drawable.bitsPerPixel;
- else
- bitsPerPixel = BitsPerPixel(depth);
+ if (depth <= 0)
+ bitsPerPixel = pPixmap->drawable.bitsPerPixel;
+ else
+ bitsPerPixel = BitsPerPixel(depth);
}
if (depth <= 0)
- depth = pPixmap->drawable.depth;
+ depth = pPixmap->drawable.depth;
if (width != pPixmap->drawable.width ||
- height != pPixmap->drawable.height ||
- depth != pPixmap->drawable.depth ||
- bitsPerPixel != pPixmap->drawable.bitsPerPixel) {
- if (pExaPixmap->driverPriv) {
- if (devKind > 0)
- pExaPixmap->fb_pitch = devKind;
- else
- exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
-
- exaSetAccelBlock(pExaScr, pExaPixmap,
- width, height, bitsPerPixel);
+ height != pPixmap->drawable.height ||
+ depth != pPixmap->drawable.depth ||
+ bitsPerPixel != pPixmap->drawable.bitsPerPixel) {
+ if (pExaPixmap->driverPriv) {
+ if (devKind > 0)
+ pExaPixmap->fb_pitch = devKind;
+ else
+ exaSetFbPitch(pExaScr, pExaPixmap, width, height, bitsPerPixel);
+
+ exaSetAccelBlock(pExaScr, pExaPixmap, width, height, bitsPerPixel);
RegionEmpty(&pExaPixmap->validFB);
}
- /* Need to re-create system copy if there's also a GPU copy */
- if (has_gpu_copy) {
- if (pExaPixmap->sys_ptr) {
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
- DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
- DamageDestroy(pExaPixmap->pDamage);
- pExaPixmap->pDamage = NULL;
- RegionEmpty(&pExaPixmap->validSys);
-
- if (pExaScr->deferred_mixed_pixmap == pPixmap)
- pExaScr->deferred_mixed_pixmap = NULL;
- }
-
- pExaPixmap->sys_pitch = PixmapBytePad(width, depth);
- }
+ /* Need to re-create system copy if there's also a GPU copy */
+ if (has_gpu_copy) {
+ if (pExaPixmap->sys_ptr) {
+ free(pExaPixmap->sys_ptr);
+ pExaPixmap->sys_ptr = NULL;
+ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+ DamageDestroy(pExaPixmap->pDamage);
+ pExaPixmap->pDamage = NULL;
+ RegionEmpty(&pExaPixmap->validSys);
+
+ if (pExaScr->deferred_mixed_pixmap == pPixmap)
+ pExaScr->deferred_mixed_pixmap = NULL;
+ }
+
+ pExaPixmap->sys_pitch = PixmapBytePad(width, depth);
+ }
}
if (has_gpu_copy) {
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- pPixmap->devKind = pExaPixmap->fb_pitch;
- } else {
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
+ pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ }
+ else {
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pPixmap->devKind = pExaPixmap->sys_pitch;
}
/* Only pass driver pixmaps to the driver. */
if (pExaScr->info->ModifyPixmapHeader && pExaPixmap->driverPriv) {
- ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
- if (ret == TRUE)
- goto out;
+ ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind,
+ pPixData);
+ if (ret == TRUE)
+ goto out;
}
swap(pExaScr, pScreen, ModifyPixmapHeader);
ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth,
- bitsPerPixel, devKind, pPixData);
+ bitsPerPixel, devKind, pPixData);
swap(pExaScr, pScreen, ModifyPixmapHeader);
-out:
+ out:
if (has_gpu_copy) {
- pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->fb_pitch = pPixmap->devKind;
- } else {
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
+ pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->fb_pitch = pPixmap->devKind;
+ }
+ else {
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
}
/* Always NULL this, we don't want lingering pointers. */
pPixmap->devPrivate.ptr = NULL;
@@ -241,32 +243,32 @@ out:
Bool
exaDestroyPixmap_mixed(PixmapPtr pPixmap)
{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
Bool ret;
- if (pPixmap->refcnt == 1)
- {
- ExaPixmapPriv (pPixmap);
+ if (pPixmap->refcnt == 1) {
+ ExaPixmapPriv(pPixmap);
- exaDestroyPixmap(pPixmap);
+ exaDestroyPixmap(pPixmap);
- if (pExaScr->deferred_mixed_pixmap == pPixmap)
- pExaScr->deferred_mixed_pixmap = NULL;
+ if (pExaScr->deferred_mixed_pixmap == pPixmap)
+ pExaScr->deferred_mixed_pixmap = NULL;
- if (pExaPixmap->driverPriv)
- pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
- pExaPixmap->driverPriv = NULL;
+ if (pExaPixmap->driverPriv)
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
- if (pExaPixmap->pDamage) {
- free(pExaPixmap->sys_ptr);
- pExaPixmap->sys_ptr = NULL;
- pExaPixmap->pDamage = NULL;
- }
+ if (pExaPixmap->pDamage) {
+ free(pExaPixmap->sys_ptr);
+ pExaPixmap->sys_ptr = NULL;
+ pExaPixmap->pDamage = NULL;
+ }
}
swap(pExaScr, pScreen, DestroyPixmap);
- ret = pScreen->DestroyPixmap (pPixmap);
+ ret = pScreen->DestroyPixmap(pPixmap);
swap(pExaScr, pScreen, DestroyPixmap);
return ret;
@@ -276,13 +278,14 @@ Bool
exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
ExaScreenPriv(pScreen);
ExaPixmapPriv(pPixmap);
pointer saved_ptr;
Bool ret;
if (!pExaPixmap->driverPriv)
- return FALSE;
+ return FALSE;
saved_ptr = pPixmap->devPrivate.ptr;
pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
diff --git a/xorg-server/exa/exa_offscreen.c b/xorg-server/exa/exa_offscreen.c
index 506da616d..5e1d1398e 100644
--- a/xorg-server/exa/exa_offscreen.c
+++ b/xorg-server/exa/exa_offscreen.c
@@ -1,696 +1,678 @@
-/*
- * Copyright © 2003 Anders Carlsson
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Anders Carlsson not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Anders Carlsson makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/** @file
- * This allocator allocates blocks of memory by maintaining a list of areas.
- * When allocating, the contiguous block of areas with the minimum eviction
- * cost is found and evicted in order to make room for the new allocation.
- */
-
-#include "exa_priv.h"
-
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#if DEBUG_OFFSCREEN
-#define DBG_OFFSCREEN(a) ErrorF a
-#else
-#define DBG_OFFSCREEN(a)
-#endif
-
-#if DEBUG_OFFSCREEN
-static void
-ExaOffscreenValidate (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
- ExaOffscreenArea *prev = 0, *area;
-
- assert (pExaScr->info->offScreenAreas->base_offset ==
- pExaScr->info->offScreenBase);
- for (area = pExaScr->info->offScreenAreas; area; area = area->next)
- {
- assert (area->offset >= area->base_offset &&
- area->offset < (area->base_offset + area->size));
- if (prev)
- assert (prev->base_offset + prev->size == area->base_offset);
- prev = area;
- }
- assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
-}
-#else
-#define ExaOffscreenValidate(s)
-#endif
-
-static ExaOffscreenArea *
-ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area)
-{
- if (area->save)
- (*area->save) (pScreen, area);
- return exaOffscreenFree (pScreen, area);
-}
-
-static void
-exaUpdateEvictionCost(ExaOffscreenArea *area, unsigned offScreenCounter)
-{
- unsigned age;
-
- if (area->state == ExaOffscreenAvail)
- return;
-
- age = offScreenCounter - area->last_use;
-
- /* This is unlikely to happen, but could result in a division by zero... */
- if (age > (UINT_MAX / 2)) {
- age = UINT_MAX / 2;
- area->last_use = offScreenCounter - age;
- }
-
- area->eviction_cost = area->size / age;
-}
-
-static ExaOffscreenArea *
-exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align)
-{
- ExaOffscreenArea *begin, *end, *best;
- unsigned cost, best_cost;
- int avail, real_size;
-
- best_cost = UINT_MAX;
- begin = end = pExaScr->info->offScreenAreas;
- avail = 0;
- cost = 0;
- best = 0;
-
- while (end != NULL)
- {
- restart:
- while (begin != NULL && begin->state == ExaOffscreenLocked)
- begin = end = begin->next;
-
- if (begin == NULL)
- break;
-
- /* adjust size needed to account for alignment loss for this area */
- real_size = size + (begin->base_offset + begin->size - size) % align;
-
- while (avail < real_size && end != NULL)
- {
- if (end->state == ExaOffscreenLocked) {
- /* Can't more room here, restart after this locked area */
- avail = 0;
- cost = 0;
- begin = end;
- goto restart;
- }
- avail += end->size;
- exaUpdateEvictionCost(end, pExaScr->offScreenCounter);
- cost += end->eviction_cost;
- end = end->next;
- }
-
- /* Check the cost, update best */
- if (avail >= real_size && cost < best_cost) {
- best = begin;
- best_cost = cost;
- }
-
- avail -= begin->size;
- cost -= begin->eviction_cost;
- begin = begin->next;
- }
-
- return best;
-}
-
-/**
- * exaOffscreenAlloc allocates offscreen memory
- *
- * @param pScreen current screen
- * @param size size in bytes of the allocation
- * @param align byte alignment requirement for the offset of the allocated area
- * @param locked whether the allocated area is locked and can't be kicked out
- * @param save callback for when the area is evicted from memory
- * @param privdata private data for the save callback.
- *
- * Allocates offscreen memory from the device associated with pScreen. size
- * and align deteremine where and how large the allocated area is, and locked
- * will mark whether it should be held in card memory. privdata may be any
- * pointer for the save callback when the area is removed.
- *
- * Note that locked areas do get evicted on VT switch unless the driver
- * requested version 2.1 or newer behavior. In that case, the save callback is
- * still called.
- */
-ExaOffscreenArea *
-exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
- Bool locked,
- ExaOffscreenSaveProc save,
- pointer privData)
-{
- ExaOffscreenArea *area;
- ExaScreenPriv (pScreen);
- int real_size = 0, largest_avail = 0;
-#if DEBUG_OFFSCREEN
- static int number = 0;
- ErrorF("================= ============ allocating a new pixmap %d\n", ++number);
-#endif
-
- ExaOffscreenValidate (pScreen);
- if (!align)
- align = 1;
-
- if (!size)
- {
- DBG_OFFSCREEN (("Alloc 0x%x -> EMPTY\n", size));
- return NULL;
- }
-
- /* throw out requests that cannot fit */
- if (size > (pExaScr->info->memorySize - pExaScr->info->offScreenBase))
- {
- DBG_OFFSCREEN (("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size,
- pExaScr->info->memorySize -
- pExaScr->info->offScreenBase));
- return NULL;
- }
-
- /* Try to find a free space that'll fit. */
- for (area = pExaScr->info->offScreenAreas; area; area = area->next)
- {
- /* skip allocated areas */
- if (area->state != ExaOffscreenAvail)
- continue;
-
- /* adjust size to match alignment requirement */
- real_size = size + (area->base_offset + area->size - size) % align;
-
- /* does it fit? */
- if (real_size <= area->size)
- break;
-
- if (area->size > largest_avail)
- largest_avail = area->size;
- }
-
- if (!area)
- {
- area = exaFindAreaToEvict(pExaScr, size, align);
-
- if (!area)
- {
- DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
- /* Could not allocate memory */
- ExaOffscreenValidate (pScreen);
- return NULL;
- }
-
- /* adjust size needed to account for alignment loss for this area */
- real_size = size + (area->base_offset + area->size - size) % align;
-
- /*
- * Kick out first area if in use
- */
- if (area->state != ExaOffscreenAvail)
- area = ExaOffscreenKickOut (pScreen, area);
- /*
- * Now get the system to merge the other needed areas together
- */
- while (area->size < real_size)
- {
- assert (area->next && area->next->state == ExaOffscreenRemovable);
- (void) ExaOffscreenKickOut (pScreen, area->next);
- }
- }
-
- /* save extra space in new area */
- if (real_size < area->size)
- {
- ExaOffscreenArea *new_area = malloc(sizeof (ExaOffscreenArea));
- if (!new_area)
- return NULL;
- new_area->base_offset = area->base_offset;
-
- new_area->offset = new_area->base_offset;
- new_area->align = 0;
- new_area->size = area->size - real_size;
- new_area->state = ExaOffscreenAvail;
- new_area->save = NULL;
- new_area->last_use = 0;
- new_area->eviction_cost = 0;
- new_area->next = area;
- new_area->prev = area->prev;
- if (area->prev->next)
- area->prev->next = new_area;
- else
- pExaScr->info->offScreenAreas = new_area;
- area->prev = new_area;
- area->base_offset = new_area->base_offset + new_area->size;
- area->size = real_size;
- } else
- pExaScr->numOffscreenAvailable--;
-
- /*
- * Mark this area as in use
- */
- if (locked)
- area->state = ExaOffscreenLocked;
- else
- area->state = ExaOffscreenRemovable;
- area->privData = privData;
- area->save = save;
- area->last_use = pExaScr->offScreenCounter++;
- area->offset = (area->base_offset + align - 1);
- area->offset -= area->offset % align;
- area->align = align;
-
- ExaOffscreenValidate (pScreen);
-
- DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x (0x%x)\n", size,
- area->base_offset, area->offset));
- return area;
-}
-
-/**
- * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
- */
-void
-ExaOffscreenSwapOut (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
-
- ExaOffscreenValidate (pScreen);
- /* loop until a single free area spans the space */
- for (;;)
- {
- ExaOffscreenArea *area = pExaScr->info->offScreenAreas;
-
- if (!area)
- break;
- if (area->state == ExaOffscreenAvail)
- {
- area = area->next;
- if (!area)
- break;
- }
- assert (area->state != ExaOffscreenAvail);
- (void) ExaOffscreenKickOut (pScreen, area);
- ExaOffscreenValidate (pScreen);
- }
- ExaOffscreenValidate (pScreen);
- ExaOffscreenFini (pScreen);
-}
-
-/** Ejects all pixmaps managed by EXA. */
-static void
-ExaOffscreenEjectPixmaps (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
-
- ExaOffscreenValidate (pScreen);
- /* loop until a single free area spans the space */
- for (;;)
- {
- ExaOffscreenArea *area;
-
- for (area = pExaScr->info->offScreenAreas; area != NULL;
- area = area->next)
- {
- if (area->state == ExaOffscreenRemovable &&
- area->save == exaPixmapSave)
- {
- (void) ExaOffscreenKickOut (pScreen, area);
- ExaOffscreenValidate (pScreen);
- break;
- }
- }
- if (area == NULL)
- break;
- }
- ExaOffscreenValidate (pScreen);
-}
-
-void
-ExaOffscreenSwapIn (ScreenPtr pScreen)
-{
- exaOffscreenInit (pScreen);
-}
-
-/**
- * Prepares EXA for disabling of FB access, or restoring it.
- *
- * In version 2.1, the disabling results in pixmaps being ejected, while other
- * allocations remain. With this plus the prevention of migration while
- * swappedOut is set, EXA by itself should not cause any access of the
- * framebuffer to occur while swapped out. Any remaining issues are the
- * responsibility of the driver.
- *
- * Prior to version 2.1, all allocations, including locked ones, are ejected
- * when access is disabled, and the allocator is torn down while swappedOut
- * is set. This is more drastic, and caused implementation difficulties for
- * many drivers that could otherwise handle the lack of FB access while
- * swapped out.
- */
-void
-exaEnableDisableFBAccess (int index, Bool enable)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- ExaScreenPriv (pScreen);
-
- if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
- return;
-
- if (!enable && pExaScr->disableFbCount++ == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapOut (pScreen);
- else
- ExaOffscreenEjectPixmaps (pScreen);
- pExaScr->swappedOut = TRUE;
- }
-
- if (enable && --pExaScr->disableFbCount == 0) {
- if (pExaScr->info->exa_minor < 1)
- ExaOffscreenSwapIn (pScreen);
- pExaScr->swappedOut = FALSE;
- }
-}
-
-/* merge the next free area into this one */
-static void
-ExaOffscreenMerge (ExaScreenPrivPtr pExaScr, ExaOffscreenArea *area)
-{
- ExaOffscreenArea *next = area->next;
-
- /* account for space */
- area->size += next->size;
- /* frob pointer */
- area->next = next->next;
- if (area->next)
- area->next->prev = area;
- else
- pExaScr->info->offScreenAreas->prev = area;
- free(next);
-
- pExaScr->numOffscreenAvailable--;
-}
-
-/**
- * exaOffscreenFree frees an allocation.
- *
- * @param pScreen current screen
- * @param area offscreen area to free
- *
- * exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that
- * the save callback of the area is not called, and it is up to the driver to
- * do any cleanup necessary as a result.
- *
- * @return pointer to the newly freed area. This behavior should not be relied
- * on.
- */
-ExaOffscreenArea *
-exaOffscreenFree (ScreenPtr pScreen, ExaOffscreenArea *area)
-{
- ExaScreenPriv(pScreen);
- ExaOffscreenArea *next = area->next;
- ExaOffscreenArea *prev;
-
- DBG_OFFSCREEN (("Free 0x%x -> 0x%x (0x%x)\n", area->size,
- area->base_offset, area->offset));
- ExaOffscreenValidate (pScreen);
-
- area->state = ExaOffscreenAvail;
- area->save = NULL;
- area->last_use = 0;
- area->eviction_cost = 0;
- /*
- * Find previous area
- */
- if (area == pExaScr->info->offScreenAreas)
- prev = NULL;
- else
- prev = area->prev;
-
- pExaScr->numOffscreenAvailable++;
-
- /* link with next area if free */
- if (next && next->state == ExaOffscreenAvail)
- ExaOffscreenMerge (pExaScr, area);
-
- /* link with prev area if free */
- if (prev && prev->state == ExaOffscreenAvail)
- {
- area = prev;
- ExaOffscreenMerge (pExaScr, area);
- }
-
- ExaOffscreenValidate (pScreen);
- DBG_OFFSCREEN(("\tdone freeing\n"));
- return area;
-}
-
-void
-ExaOffscreenMarkUsed (PixmapPtr pPixmap)
-{
- ExaPixmapPriv (pPixmap);
- ExaScreenPriv (pPixmap->drawable.pScreen);
-
- if (!pExaPixmap || !pExaPixmap->area)
- return;
-
- pExaPixmap->area->last_use = pExaScr->offScreenCounter++;
-}
-
-/**
- * Defragment offscreen memory by compacting allocated areas at the end of it,
- * leaving the total amount of memory available as a single area at the
- * beginning (when there are no pinned allocations).
- */
-_X_HIDDEN ExaOffscreenArea*
-ExaOffscreenDefragment (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
- ExaOffscreenArea *area, *largest_available = NULL;
- int largest_size = 0;
- PixmapPtr pDstPix;
- ExaPixmapPrivPtr pExaDstPix;
-
- pDstPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, 0, 0);
-
- if (!pDstPix)
- return NULL;
-
- pExaDstPix = ExaGetPixmapPriv (pDstPix);
- pExaDstPix->use_gpu_copy = TRUE;
-
- for (area = pExaScr->info->offScreenAreas->prev;
- area != pExaScr->info->offScreenAreas;
- )
- {
- ExaOffscreenArea *prev = area->prev;
- PixmapPtr pSrcPix;
- ExaPixmapPrivPtr pExaSrcPix;
- Bool save_use_gpu_copy;
- int save_pitch;
-
- if (area->state != ExaOffscreenAvail ||
- prev->state == ExaOffscreenLocked ||
- (prev->state == ExaOffscreenRemovable &&
- prev->save != exaPixmapSave)) {
- area = prev;
- continue;
- }
-
- if (prev->state == ExaOffscreenAvail) {
- if (area == largest_available) {
- largest_available = prev;
- largest_size += prev->size;
- }
- area = prev;
- ExaOffscreenMerge (pExaScr, area);
- continue;
- }
-
- if (area->size > largest_size) {
- largest_available = area;
- largest_size = area->size;
- }
-
- pSrcPix = prev->privData;
- pExaSrcPix = ExaGetPixmapPriv (pSrcPix);
-
- pExaDstPix->fb_ptr = pExaScr->info->memoryBase +
- area->base_offset + area->size - prev->size + prev->base_offset -
- prev->offset;
- pExaDstPix->fb_ptr -= (unsigned long)pExaDstPix->fb_ptr % prev->align;
-
- if (pExaDstPix->fb_ptr <= pExaSrcPix->fb_ptr) {
- area = prev;
- continue;
- }
-
- if (!(pExaScr->info->flags & EXA_SUPPORTS_OFFSCREEN_OVERLAPS) &&
- (pExaSrcPix->fb_ptr + prev->size) > pExaDstPix->fb_ptr) {
- area = prev;
- continue;
- }
-
- save_use_gpu_copy = pExaSrcPix->use_gpu_copy;
- save_pitch = pSrcPix->devKind;
-
- pExaSrcPix->use_gpu_copy = TRUE;
- pSrcPix->devKind = pExaSrcPix->fb_pitch;
-
- pDstPix->drawable.width = pSrcPix->drawable.width;
- pDstPix->devKind = pSrcPix->devKind;
- pDstPix->drawable.height = pSrcPix->drawable.height;
- pDstPix->drawable.depth = pSrcPix->drawable.depth;
- pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel;
-
- if (!pExaScr->info->PrepareCopy (pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) {
- pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
- pSrcPix->devKind = save_pitch;
- area = prev;
- continue;
- }
-
- pExaScr->info->Copy (pDstPix, 0, 0, 0, 0, pDstPix->drawable.width,
- pDstPix->drawable.height);
- pExaScr->info->DoneCopy (pDstPix);
- exaMarkSync (pScreen);
-
- DBG_OFFSCREEN(("Before swap: prev=0x%08x-0x%08x-0x%08x area=0x%08x-0x%08x-0x%08x\n",
- prev->base_offset, prev->offset, prev->base_offset + prev->size,
- area->base_offset, area->offset, area->base_offset + area->size));
-
- /* Calculate swapped area offsets and sizes */
- area->base_offset = prev->base_offset;
- area->offset = area->base_offset;
- prev->offset += pExaDstPix->fb_ptr - pExaSrcPix->fb_ptr;
- assert(prev->offset >= pExaScr->info->offScreenBase &&
- prev->offset < pExaScr->info->memorySize);
- prev->base_offset = prev->offset;
- if (area->next)
- prev->size = area->next->base_offset - prev->base_offset;
- else
- prev->size = pExaScr->info->memorySize - prev->base_offset;
- area->size = prev->base_offset - area->base_offset;
-
- DBG_OFFSCREEN(("After swap: area=0x%08x-0x%08x-0x%08x prev=0x%08x-0x%08x-0x%08x\n",
- area->base_offset, area->offset, area->base_offset + area->size,
- prev->base_offset, prev->offset, prev->base_offset + prev->size));
-
- /* Swap areas in list */
- if (area->next)
- area->next->prev = prev;
- else
- pExaScr->info->offScreenAreas->prev = prev;
- if (prev->prev->next)
- prev->prev->next = area;
- else
- pExaScr->info->offScreenAreas = area;
- prev->next = area->next;
- area->next = prev;
- area->prev = prev->prev;
- prev->prev = area;
- if (!area->prev->next)
- pExaScr->info->offScreenAreas = area;
-
-#if DEBUG_OFFSCREEN
- if (prev->prev == prev || prev->next == prev)
- ErrorF("Whoops, prev points to itself!\n");
-
- if (area->prev == area || area->next == area)
- ErrorF("Whoops, area points to itself!\n");
-#endif
-
- pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr;
- pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
- pSrcPix->devKind = save_pitch;
- }
-
- pDstPix->drawable.width = 0;
- pDstPix->drawable.height = 0;
- pDstPix->drawable.depth = 0;
- pDstPix->drawable.bitsPerPixel = 0;
-
- (*pScreen->DestroyPixmap) (pDstPix);
-
- if (area->state == ExaOffscreenAvail && area->size > largest_size)
- return area;
-
- return largest_available;
-}
-
-/**
- * exaOffscreenInit initializes the offscreen memory manager.
- *
- * @param pScreen current screen
- *
- * exaOffscreenInit is called by exaDriverInit to set up the memory manager for
- * the screen, if any offscreen memory is available.
- */
-Bool
-exaOffscreenInit (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
- ExaOffscreenArea *area;
-
- /* Allocate a big free area */
- area = malloc(sizeof (ExaOffscreenArea));
-
- if (!area)
- return FALSE;
-
- area->state = ExaOffscreenAvail;
- area->base_offset = pExaScr->info->offScreenBase;
- area->offset = area->base_offset;
- area->align = 0;
- area->size = pExaScr->info->memorySize - area->base_offset;
- area->save = NULL;
- area->next = NULL;
- area->prev = area;
- area->last_use = 0;
- area->eviction_cost = 0;
-
- /* Add it to the free areas */
- pExaScr->info->offScreenAreas = area;
- pExaScr->offScreenCounter = 1;
- pExaScr->numOffscreenAvailable = 1;
-
- ExaOffscreenValidate (pScreen);
-
- return TRUE;
-}
-
-void
-ExaOffscreenFini (ScreenPtr pScreen)
-{
- ExaScreenPriv (pScreen);
- ExaOffscreenArea *area;
-
- /* just free all of the area records */
- while ((area = pExaScr->info->offScreenAreas))
- {
- pExaScr->info->offScreenAreas = area->next;
- free(area);
- }
-}
+/*
+ * Copyright © 2003 Anders Carlsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Anders Carlsson not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Anders Carlsson makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/** @file
+ * This allocator allocates blocks of memory by maintaining a list of areas.
+ * When allocating, the contiguous block of areas with the minimum eviction
+ * cost is found and evicted in order to make room for the new allocation.
+ */
+
+#include "exa_priv.h"
+
+#include <limits.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#if DEBUG_OFFSCREEN
+#define DBG_OFFSCREEN(a) ErrorF a
+#else
+#define DBG_OFFSCREEN(a)
+#endif
+
+#if DEBUG_OFFSCREEN
+static void
+ExaOffscreenValidate(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ ExaOffscreenArea *prev = 0, *area;
+
+ assert(pExaScr->info->offScreenAreas->base_offset ==
+ pExaScr->info->offScreenBase);
+ for (area = pExaScr->info->offScreenAreas; area; area = area->next) {
+ assert(area->offset >= area->base_offset &&
+ area->offset < (area->base_offset + area->size));
+ if (prev)
+ assert(prev->base_offset + prev->size == area->base_offset);
+ prev = area;
+ }
+ assert(prev->base_offset + prev->size == pExaScr->info->memorySize);
+}
+#else
+#define ExaOffscreenValidate(s)
+#endif
+
+static ExaOffscreenArea *
+ExaOffscreenKickOut(ScreenPtr pScreen, ExaOffscreenArea * area)
+{
+ if (area->save)
+ (*area->save) (pScreen, area);
+ return exaOffscreenFree(pScreen, area);
+}
+
+static void
+exaUpdateEvictionCost(ExaOffscreenArea * area, unsigned offScreenCounter)
+{
+ unsigned age;
+
+ if (area->state == ExaOffscreenAvail)
+ return;
+
+ age = offScreenCounter - area->last_use;
+
+ /* This is unlikely to happen, but could result in a division by zero... */
+ if (age > (UINT_MAX / 2)) {
+ age = UINT_MAX / 2;
+ area->last_use = offScreenCounter - age;
+ }
+
+ area->eviction_cost = area->size / age;
+}
+
+static ExaOffscreenArea *
+exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align)
+{
+ ExaOffscreenArea *begin, *end, *best;
+ unsigned cost, best_cost;
+ int avail, real_size;
+
+ best_cost = UINT_MAX;
+ begin = end = pExaScr->info->offScreenAreas;
+ avail = 0;
+ cost = 0;
+ best = 0;
+
+ while (end != NULL) {
+ restart:
+ while (begin != NULL && begin->state == ExaOffscreenLocked)
+ begin = end = begin->next;
+
+ if (begin == NULL)
+ break;
+
+ /* adjust size needed to account for alignment loss for this area */
+ real_size = size + (begin->base_offset + begin->size - size) % align;
+
+ while (avail < real_size && end != NULL) {
+ if (end->state == ExaOffscreenLocked) {
+ /* Can't more room here, restart after this locked area */
+ avail = 0;
+ cost = 0;
+ begin = end;
+ goto restart;
+ }
+ avail += end->size;
+ exaUpdateEvictionCost(end, pExaScr->offScreenCounter);
+ cost += end->eviction_cost;
+ end = end->next;
+ }
+
+ /* Check the cost, update best */
+ if (avail >= real_size && cost < best_cost) {
+ best = begin;
+ best_cost = cost;
+ }
+
+ avail -= begin->size;
+ cost -= begin->eviction_cost;
+ begin = begin->next;
+ }
+
+ return best;
+}
+
+/**
+ * exaOffscreenAlloc allocates offscreen memory
+ *
+ * @param pScreen current screen
+ * @param size size in bytes of the allocation
+ * @param align byte alignment requirement for the offset of the allocated area
+ * @param locked whether the allocated area is locked and can't be kicked out
+ * @param save callback for when the area is evicted from memory
+ * @param privdata private data for the save callback.
+ *
+ * Allocates offscreen memory from the device associated with pScreen. size
+ * and align deteremine where and how large the allocated area is, and locked
+ * will mark whether it should be held in card memory. privdata may be any
+ * pointer for the save callback when the area is removed.
+ *
+ * Note that locked areas do get evicted on VT switch unless the driver
+ * requested version 2.1 or newer behavior. In that case, the save callback is
+ * still called.
+ */
+ExaOffscreenArea *
+exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
+ Bool locked, ExaOffscreenSaveProc save, pointer privData)
+{
+ ExaOffscreenArea *area;
+
+ ExaScreenPriv(pScreen);
+ int real_size = 0, largest_avail = 0;
+
+#if DEBUG_OFFSCREEN
+ static int number = 0;
+
+ ErrorF("================= ============ allocating a new pixmap %d\n",
+ ++number);
+#endif
+
+ ExaOffscreenValidate(pScreen);
+ if (!align)
+ align = 1;
+
+ if (!size) {
+ DBG_OFFSCREEN(("Alloc 0x%x -> EMPTY\n", size));
+ return NULL;
+ }
+
+ /* throw out requests that cannot fit */
+ if (size > (pExaScr->info->memorySize - pExaScr->info->offScreenBase)) {
+ DBG_OFFSCREEN(("Alloc 0x%x vs (0x%lx) -> TOBIG\n", size,
+ pExaScr->info->memorySize -
+ pExaScr->info->offScreenBase));
+ return NULL;
+ }
+
+ /* Try to find a free space that'll fit. */
+ for (area = pExaScr->info->offScreenAreas; area; area = area->next) {
+ /* skip allocated areas */
+ if (area->state != ExaOffscreenAvail)
+ continue;
+
+ /* adjust size to match alignment requirement */
+ real_size = size + (area->base_offset + area->size - size) % align;
+
+ /* does it fit? */
+ if (real_size <= area->size)
+ break;
+
+ if (area->size > largest_avail)
+ largest_avail = area->size;
+ }
+
+ if (!area) {
+ area = exaFindAreaToEvict(pExaScr, size, align);
+
+ if (!area) {
+ DBG_OFFSCREEN(("Alloc 0x%x -> NOSPACE\n", size));
+ /* Could not allocate memory */
+ ExaOffscreenValidate(pScreen);
+ return NULL;
+ }
+
+ /* adjust size needed to account for alignment loss for this area */
+ real_size = size + (area->base_offset + area->size - size) % align;
+
+ /*
+ * Kick out first area if in use
+ */
+ if (area->state != ExaOffscreenAvail)
+ area = ExaOffscreenKickOut(pScreen, area);
+ /*
+ * Now get the system to merge the other needed areas together
+ */
+ while (area->size < real_size) {
+ assert(area->next && area->next->state == ExaOffscreenRemovable);
+ (void) ExaOffscreenKickOut(pScreen, area->next);
+ }
+ }
+
+ /* save extra space in new area */
+ if (real_size < area->size) {
+ ExaOffscreenArea *new_area = malloc(sizeof(ExaOffscreenArea));
+
+ if (!new_area)
+ return NULL;
+ new_area->base_offset = area->base_offset;
+
+ new_area->offset = new_area->base_offset;
+ new_area->align = 0;
+ new_area->size = area->size - real_size;
+ new_area->state = ExaOffscreenAvail;
+ new_area->save = NULL;
+ new_area->last_use = 0;
+ new_area->eviction_cost = 0;
+ new_area->next = area;
+ new_area->prev = area->prev;
+ if (area->prev->next)
+ area->prev->next = new_area;
+ else
+ pExaScr->info->offScreenAreas = new_area;
+ area->prev = new_area;
+ area->base_offset = new_area->base_offset + new_area->size;
+ area->size = real_size;
+ }
+ else
+ pExaScr->numOffscreenAvailable--;
+
+ /*
+ * Mark this area as in use
+ */
+ if (locked)
+ area->state = ExaOffscreenLocked;
+ else
+ area->state = ExaOffscreenRemovable;
+ area->privData = privData;
+ area->save = save;
+ area->last_use = pExaScr->offScreenCounter++;
+ area->offset = (area->base_offset + align - 1);
+ area->offset -= area->offset % align;
+ area->align = align;
+
+ ExaOffscreenValidate(pScreen);
+
+ DBG_OFFSCREEN(("Alloc 0x%x -> 0x%x (0x%x)\n", size,
+ area->base_offset, area->offset));
+ return area;
+}
+
+/**
+ * Ejects all offscreen areas, and uninitializes the offscreen memory manager.
+ */
+void
+ExaOffscreenSwapOut(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+
+ ExaOffscreenValidate(pScreen);
+ /* loop until a single free area spans the space */
+ for (;;) {
+ ExaOffscreenArea *area = pExaScr->info->offScreenAreas;
+
+ if (!area)
+ break;
+ if (area->state == ExaOffscreenAvail) {
+ area = area->next;
+ if (!area)
+ break;
+ }
+ assert(area->state != ExaOffscreenAvail);
+ (void) ExaOffscreenKickOut(pScreen, area);
+ ExaOffscreenValidate(pScreen);
+ }
+ ExaOffscreenValidate(pScreen);
+ ExaOffscreenFini(pScreen);
+}
+
+/** Ejects all pixmaps managed by EXA. */
+static void
+ExaOffscreenEjectPixmaps(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+
+ ExaOffscreenValidate(pScreen);
+ /* loop until a single free area spans the space */
+ for (;;) {
+ ExaOffscreenArea *area;
+
+ for (area = pExaScr->info->offScreenAreas; area != NULL;
+ area = area->next) {
+ if (area->state == ExaOffscreenRemovable &&
+ area->save == exaPixmapSave) {
+ (void) ExaOffscreenKickOut(pScreen, area);
+ ExaOffscreenValidate(pScreen);
+ break;
+ }
+ }
+ if (area == NULL)
+ break;
+ }
+ ExaOffscreenValidate(pScreen);
+}
+
+void
+ExaOffscreenSwapIn(ScreenPtr pScreen)
+{
+ exaOffscreenInit(pScreen);
+}
+
+/**
+ * Prepares EXA for disabling of FB access, or restoring it.
+ *
+ * In version 2.1, the disabling results in pixmaps being ejected, while other
+ * allocations remain. With this plus the prevention of migration while
+ * swappedOut is set, EXA by itself should not cause any access of the
+ * framebuffer to occur while swapped out. Any remaining issues are the
+ * responsibility of the driver.
+ *
+ * Prior to version 2.1, all allocations, including locked ones, are ejected
+ * when access is disabled, and the allocator is torn down while swappedOut
+ * is set. This is more drastic, and caused implementation difficulties for
+ * many drivers that could otherwise handle the lack of FB access while
+ * swapped out.
+ */
+void
+exaEnableDisableFBAccess(int index, Bool enable)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+
+ ExaScreenPriv(pScreen);
+
+ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
+ return;
+
+ if (!enable && pExaScr->disableFbCount++ == 0) {
+ if (pExaScr->info->exa_minor < 1)
+ ExaOffscreenSwapOut(pScreen);
+ else
+ ExaOffscreenEjectPixmaps(pScreen);
+ pExaScr->swappedOut = TRUE;
+ }
+
+ if (enable && --pExaScr->disableFbCount == 0) {
+ if (pExaScr->info->exa_minor < 1)
+ ExaOffscreenSwapIn(pScreen);
+ pExaScr->swappedOut = FALSE;
+ }
+}
+
+/* merge the next free area into this one */
+static void
+ExaOffscreenMerge(ExaScreenPrivPtr pExaScr, ExaOffscreenArea * area)
+{
+ ExaOffscreenArea *next = area->next;
+
+ /* account for space */
+ area->size += next->size;
+ /* frob pointer */
+ area->next = next->next;
+ if (area->next)
+ area->next->prev = area;
+ else
+ pExaScr->info->offScreenAreas->prev = area;
+ free(next);
+
+ pExaScr->numOffscreenAvailable--;
+}
+
+/**
+ * exaOffscreenFree frees an allocation.
+ *
+ * @param pScreen current screen
+ * @param area offscreen area to free
+ *
+ * exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that
+ * the save callback of the area is not called, and it is up to the driver to
+ * do any cleanup necessary as a result.
+ *
+ * @return pointer to the newly freed area. This behavior should not be relied
+ * on.
+ */
+ExaOffscreenArea *
+exaOffscreenFree(ScreenPtr pScreen, ExaOffscreenArea * area)
+{
+ ExaScreenPriv(pScreen);
+ ExaOffscreenArea *next = area->next;
+ ExaOffscreenArea *prev;
+
+ DBG_OFFSCREEN(("Free 0x%x -> 0x%x (0x%x)\n", area->size,
+ area->base_offset, area->offset));
+ ExaOffscreenValidate(pScreen);
+
+ area->state = ExaOffscreenAvail;
+ area->save = NULL;
+ area->last_use = 0;
+ area->eviction_cost = 0;
+ /*
+ * Find previous area
+ */
+ if (area == pExaScr->info->offScreenAreas)
+ prev = NULL;
+ else
+ prev = area->prev;
+
+ pExaScr->numOffscreenAvailable++;
+
+ /* link with next area if free */
+ if (next && next->state == ExaOffscreenAvail)
+ ExaOffscreenMerge(pExaScr, area);
+
+ /* link with prev area if free */
+ if (prev && prev->state == ExaOffscreenAvail) {
+ area = prev;
+ ExaOffscreenMerge(pExaScr, area);
+ }
+
+ ExaOffscreenValidate(pScreen);
+ DBG_OFFSCREEN(("\tdone freeing\n"));
+ return area;
+}
+
+void
+ExaOffscreenMarkUsed(PixmapPtr pPixmap)
+{
+ ExaPixmapPriv(pPixmap);
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
+ if (!pExaPixmap || !pExaPixmap->area)
+ return;
+
+ pExaPixmap->area->last_use = pExaScr->offScreenCounter++;
+}
+
+/**
+ * Defragment offscreen memory by compacting allocated areas at the end of it,
+ * leaving the total amount of memory available as a single area at the
+ * beginning (when there are no pinned allocations).
+ */
+_X_HIDDEN ExaOffscreenArea *
+ExaOffscreenDefragment(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ ExaOffscreenArea *area, *largest_available = NULL;
+ int largest_size = 0;
+ PixmapPtr pDstPix;
+ ExaPixmapPrivPtr pExaDstPix;
+
+ pDstPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, 0, 0);
+
+ if (!pDstPix)
+ return NULL;
+
+ pExaDstPix = ExaGetPixmapPriv(pDstPix);
+ pExaDstPix->use_gpu_copy = TRUE;
+
+ for (area = pExaScr->info->offScreenAreas->prev;
+ area != pExaScr->info->offScreenAreas;) {
+ ExaOffscreenArea *prev = area->prev;
+ PixmapPtr pSrcPix;
+ ExaPixmapPrivPtr pExaSrcPix;
+ Bool save_use_gpu_copy;
+ int save_pitch;
+
+ if (area->state != ExaOffscreenAvail ||
+ prev->state == ExaOffscreenLocked ||
+ (prev->state == ExaOffscreenRemovable &&
+ prev->save != exaPixmapSave)) {
+ area = prev;
+ continue;
+ }
+
+ if (prev->state == ExaOffscreenAvail) {
+ if (area == largest_available) {
+ largest_available = prev;
+ largest_size += prev->size;
+ }
+ area = prev;
+ ExaOffscreenMerge(pExaScr, area);
+ continue;
+ }
+
+ if (area->size > largest_size) {
+ largest_available = area;
+ largest_size = area->size;
+ }
+
+ pSrcPix = prev->privData;
+ pExaSrcPix = ExaGetPixmapPriv(pSrcPix);
+
+ pExaDstPix->fb_ptr = pExaScr->info->memoryBase +
+ area->base_offset + area->size - prev->size + prev->base_offset -
+ prev->offset;
+ pExaDstPix->fb_ptr -= (unsigned long) pExaDstPix->fb_ptr % prev->align;
+
+ if (pExaDstPix->fb_ptr <= pExaSrcPix->fb_ptr) {
+ area = prev;
+ continue;
+ }
+
+ if (!(pExaScr->info->flags & EXA_SUPPORTS_OFFSCREEN_OVERLAPS) &&
+ (pExaSrcPix->fb_ptr + prev->size) > pExaDstPix->fb_ptr) {
+ area = prev;
+ continue;
+ }
+
+ save_use_gpu_copy = pExaSrcPix->use_gpu_copy;
+ save_pitch = pSrcPix->devKind;
+
+ pExaSrcPix->use_gpu_copy = TRUE;
+ pSrcPix->devKind = pExaSrcPix->fb_pitch;
+
+ pDstPix->drawable.width = pSrcPix->drawable.width;
+ pDstPix->devKind = pSrcPix->devKind;
+ pDstPix->drawable.height = pSrcPix->drawable.height;
+ pDstPix->drawable.depth = pSrcPix->drawable.depth;
+ pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel;
+
+ if (!pExaScr->info->PrepareCopy(pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) {
+ pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
+ pSrcPix->devKind = save_pitch;
+ area = prev;
+ continue;
+ }
+
+ pExaScr->info->Copy(pDstPix, 0, 0, 0, 0, pDstPix->drawable.width,
+ pDstPix->drawable.height);
+ pExaScr->info->DoneCopy(pDstPix);
+ exaMarkSync(pScreen);
+
+ DBG_OFFSCREEN(("Before swap: prev=0x%08x-0x%08x-0x%08x area=0x%08x-0x%08x-0x%08x\n", prev->base_offset, prev->offset, prev->base_offset + prev->size, area->base_offset, area->offset, area->base_offset + area->size));
+
+ /* Calculate swapped area offsets and sizes */
+ area->base_offset = prev->base_offset;
+ area->offset = area->base_offset;
+ prev->offset += pExaDstPix->fb_ptr - pExaSrcPix->fb_ptr;
+ assert(prev->offset >= pExaScr->info->offScreenBase &&
+ prev->offset < pExaScr->info->memorySize);
+ prev->base_offset = prev->offset;
+ if (area->next)
+ prev->size = area->next->base_offset - prev->base_offset;
+ else
+ prev->size = pExaScr->info->memorySize - prev->base_offset;
+ area->size = prev->base_offset - area->base_offset;
+
+ DBG_OFFSCREEN(("After swap: area=0x%08x-0x%08x-0x%08x prev=0x%08x-0x%08x-0x%08x\n", area->base_offset, area->offset, area->base_offset + area->size, prev->base_offset, prev->offset, prev->base_offset + prev->size));
+
+ /* Swap areas in list */
+ if (area->next)
+ area->next->prev = prev;
+ else
+ pExaScr->info->offScreenAreas->prev = prev;
+ if (prev->prev->next)
+ prev->prev->next = area;
+ else
+ pExaScr->info->offScreenAreas = area;
+ prev->next = area->next;
+ area->next = prev;
+ area->prev = prev->prev;
+ prev->prev = area;
+ if (!area->prev->next)
+ pExaScr->info->offScreenAreas = area;
+
+#if DEBUG_OFFSCREEN
+ if (prev->prev == prev || prev->next == prev)
+ ErrorF("Whoops, prev points to itself!\n");
+
+ if (area->prev == area || area->next == area)
+ ErrorF("Whoops, area points to itself!\n");
+#endif
+
+ pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr;
+ pExaSrcPix->use_gpu_copy = save_use_gpu_copy;
+ pSrcPix->devKind = save_pitch;
+ }
+
+ pDstPix->drawable.width = 0;
+ pDstPix->drawable.height = 0;
+ pDstPix->drawable.depth = 0;
+ pDstPix->drawable.bitsPerPixel = 0;
+
+ (*pScreen->DestroyPixmap) (pDstPix);
+
+ if (area->state == ExaOffscreenAvail && area->size > largest_size)
+ return area;
+
+ return largest_available;
+}
+
+/**
+ * exaOffscreenInit initializes the offscreen memory manager.
+ *
+ * @param pScreen current screen
+ *
+ * exaOffscreenInit is called by exaDriverInit to set up the memory manager for
+ * the screen, if any offscreen memory is available.
+ */
+Bool
+exaOffscreenInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ ExaOffscreenArea *area;
+
+ /* Allocate a big free area */
+ area = malloc(sizeof(ExaOffscreenArea));
+
+ if (!area)
+ return FALSE;
+
+ area->state = ExaOffscreenAvail;
+ area->base_offset = pExaScr->info->offScreenBase;
+ area->offset = area->base_offset;
+ area->align = 0;
+ area->size = pExaScr->info->memorySize - area->base_offset;
+ area->save = NULL;
+ area->next = NULL;
+ area->prev = area;
+ area->last_use = 0;
+ area->eviction_cost = 0;
+
+ /* Add it to the free areas */
+ pExaScr->info->offScreenAreas = area;
+ pExaScr->offScreenCounter = 1;
+ pExaScr->numOffscreenAvailable = 1;
+
+ ExaOffscreenValidate(pScreen);
+
+ return TRUE;
+}
+
+void
+ExaOffscreenFini(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ ExaOffscreenArea *area;
+
+ /* just free all of the area records */
+ while ((area = pExaScr->info->offScreenAreas)) {
+ pExaScr->info->offScreenAreas = area->next;
+ free(area);
+ }
+}
diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h
index 70de4bd6f..bde78c3a0 100644
--- a/xorg-server/exa/exa_priv.h
+++ b/xorg-server/exa/exa_priv.h
@@ -68,7 +68,7 @@ do { \
} while (0)
char
-exaDrawableLocation(DrawablePtr pDrawable);
+ exaDrawableLocation(DrawablePtr pDrawable);
#else
#define EXA_FALLBACK(x)
#endif
@@ -115,7 +115,7 @@ typedef struct {
int glyphWidth;
int glyphHeight;
- int size; /* Size of cache; eventually this should be dynamically determined */
+ int size; /* Size of cache; eventually this should be dynamically determined */
/* Hash table mapping from glyph sha1 to position in the glyph; we use
* open addressing with a hash table size determined based on size and large
@@ -125,14 +125,14 @@ typedef struct {
*/
int *hashEntries;
int hashSize;
-
+
ExaCachedGlyphPtr glyphs;
- int glyphCount; /* Current number of glyphs */
-
- PicturePtr picture; /* Where the glyphs of the cache are stored */
- int yOffset; /* y location within the picture where the cache starts */
- int columns; /* Number of columns the glyphs are layed out in */
- int evictionPosition; /* Next random position to evict a glyph */
+ int glyphCount; /* Current number of glyphs */
+
+ PicturePtr picture; /* Where the glyphs of the cache are stored */
+ int yOffset; /* y location within the picture where the cache starts */
+ int columns; /* Number of columns the glyphs are layed out in */
+ int evictionPosition; /* Next random position to evict a glyph */
} ExaGlyphCacheRec, *ExaGlyphCachePtr;
#define EXA_NUM_GLYPH_CACHES 4
@@ -147,57 +147,58 @@ typedef struct _ExaMigrationRec {
RegionPtr pReg;
} ExaMigrationRec, *ExaMigrationPtr;
-typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
+typedef void (*EnableDisableFBAccessProcPtr) (int, Bool);
typedef struct {
ExaDriverPtr info;
- ScreenBlockHandlerProcPtr SavedBlockHandler;
- ScreenWakeupHandlerProcPtr SavedWakeupHandler;
- CreateGCProcPtr SavedCreateGC;
- CloseScreenProcPtr SavedCloseScreen;
- GetImageProcPtr SavedGetImage;
- GetSpansProcPtr SavedGetSpans;
- CreatePixmapProcPtr SavedCreatePixmap;
- DestroyPixmapProcPtr SavedDestroyPixmap;
- CopyWindowProcPtr SavedCopyWindow;
+ ScreenBlockHandlerProcPtr SavedBlockHandler;
+ ScreenWakeupHandlerProcPtr SavedWakeupHandler;
+ CreateGCProcPtr SavedCreateGC;
+ CloseScreenProcPtr SavedCloseScreen;
+ GetImageProcPtr SavedGetImage;
+ GetSpansProcPtr SavedGetSpans;
+ CreatePixmapProcPtr SavedCreatePixmap;
+ DestroyPixmapProcPtr SavedDestroyPixmap;
+ CopyWindowProcPtr SavedCopyWindow;
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
- BitmapToRegionProcPtr SavedBitmapToRegion;
+ BitmapToRegionProcPtr SavedBitmapToRegion;
CreateScreenResourcesProcPtr SavedCreateScreenResources;
- ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
- SourceValidateProcPtr SavedSourceValidate;
- CompositeProcPtr SavedComposite;
- TrianglesProcPtr SavedTriangles;
- GlyphsProcPtr SavedGlyphs;
- TrapezoidsProcPtr SavedTrapezoids;
- AddTrapsProcPtr SavedAddTraps;
- void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
+ SourceValidateProcPtr SavedSourceValidate;
+ CompositeProcPtr SavedComposite;
+ TrianglesProcPtr SavedTriangles;
+ GlyphsProcPtr SavedGlyphs;
+ TrapezoidsProcPtr SavedTrapezoids;
+ AddTrapsProcPtr SavedAddTraps;
+ void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps,
+ Bool can_accel);
Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap);
void (*do_move_in_pixmap) (PixmapPtr pPixmap);
void (*do_move_out_pixmap) (PixmapPtr pPixmap);
- void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
-
- Bool swappedOut;
- enum ExaMigrationHeuristic migration;
- Bool checkDirtyCorrectness;
- unsigned disableFbCount;
- Bool optimize_migration;
- unsigned offScreenCounter;
- unsigned numOffscreenAvailable;
- CARD32 lastDefragment;
- CARD32 nextDefragment;
- PixmapPtr deferred_mixed_pixmap;
+ void (*prepare_access_reg) (PixmapPtr pPixmap, int index, RegionPtr pReg);
+
+ Bool swappedOut;
+ enum ExaMigrationHeuristic migration;
+ Bool checkDirtyCorrectness;
+ unsigned disableFbCount;
+ Bool optimize_migration;
+ unsigned offScreenCounter;
+ unsigned numOffscreenAvailable;
+ CARD32 lastDefragment;
+ CARD32 nextDefragment;
+ PixmapPtr deferred_mixed_pixmap;
/* Reference counting for accessed pixmaps */
struct {
- PixmapPtr pixmap;
- int count;
- Bool retval;
+ PixmapPtr pixmap;
+ int count;
+ Bool retval;
} access[EXA_NUM_PREPARE_INDICES];
/* Holds information on fallbacks that cannot be relayed otherwise. */
unsigned int fallback_flags;
unsigned int fallback_counter;
- ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
+ ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
/**
* Regions affected by fallback composite source / mask operations.
@@ -222,10 +223,13 @@ typedef struct {
#endif
extern DevPrivateKeyRec exaScreenPrivateKeyRec;
+
#define exaScreenPrivateKey (&exaScreenPrivateKeyRec)
extern DevPrivateKeyRec exaPixmapPrivateKeyRec;
+
#define exaPixmapPrivateKey (&exaPixmapPrivateKeyRec)
extern DevPrivateKeyRec exaGCPrivateKeyRec;
+
#define exaGCPrivateKey (&exaGCPrivateKeyRec)
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey))
@@ -291,15 +295,15 @@ extern DevPrivateKeyRec exaGCPrivateKeyRec;
typedef struct {
ExaOffscreenArea *area;
- int score; /**< score for the move-in vs move-out heuristic */
- Bool use_gpu_copy;
+ int score; /**< score for the move-in vs move-out heuristic */
+ Bool use_gpu_copy;
- CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
- int sys_pitch; /**< pitch of pixmap in system memory */
+ CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
+ int sys_pitch; /**< pitch of pixmap in system memory */
- CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
- int fb_pitch; /**< pitch of pixmap in framebuffer memory */
- unsigned int fb_size; /**< size of pixmap in framebuffer memory */
+ CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */
+ int fb_pitch; /**< pitch of pixmap in framebuffer memory */
+ unsigned int fb_size; /**< size of pixmap in framebuffer memory */
/**
* Holds information about whether this pixmap can be used for
@@ -310,19 +314,19 @@ typedef struct {
* EXA_RANGE_WIDTH - set if the pixmap's width is out of range
* EXA_RANGE_HEIGHT - set if the pixmap's height is out of range
*/
- unsigned int accel_blocked;
+ unsigned int accel_blocked;
/**
* The damage record contains the areas of the pixmap's current location
* (framebuffer or system) that have been damaged compared to the other
* location.
*/
- DamagePtr pDamage;
+ DamagePtr pDamage;
/**
* The valid regions mark the valid bits (at least, as they're derived from
* damage, which may be overreported) of a pixmap's system and FB copies.
*/
- RegionRec validSys, validFB;
+ RegionRec validSys, validFB;
/**
* Driver private storage per EXA pixmap
*/
@@ -351,374 +355,383 @@ typedef struct {
* exaDDXDriverInit must be implemented by the DDX using EXA, and is the place
* to set EXA options or hook in screen functions to handle using EXA as the AA.
*/
-void exaDDXDriverInit (ScreenPtr pScreen);
+void exaDDXDriverInit(ScreenPtr pScreen);
/* exa_unaccel.c */
void
-exaPrepareAccessGC(GCPtr pGC);
+ exaPrepareAccessGC(GCPtr pGC);
void
-exaFinishAccessGC(GCPtr pGC);
+ exaFinishAccessGC(GCPtr pGC);
void
-ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted);
+
+ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
void
-ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+
+ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits);
+
+ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits);
void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure);
+
+ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure);
RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty);
+
+ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty);
RegionPtr
-ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane);
+
+ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane);
void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit);
+
+ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit);
void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt);
+
+ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt);
void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment *pSegInit);
+
+ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment * pSegInit);
void
-ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *pArcs);
+ ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs);
void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect);
+
+ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect);
void
-ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
+
+ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr * ppci, pointer pglyphBase);
void
-ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
+
+ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr * ppci, pointer pglyphBase);
void
-ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable,
- int w, int h, int x, int y);
+
+ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable, int w, int h, int x, int y);
void
-ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
+
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
+ unsigned int format, unsigned long planeMask, char *d);
void
-ExaCheckGetSpans (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart);
+
+ExaCheckGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart);
void
-ExaCheckAddTraps (PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off,
- int ntrap,
- xTrap *traps);
+
+ExaCheckAddTraps(PicturePtr pPicture,
+ INT16 x_off, INT16 y_off, int ntrap, xTrap * traps);
/* exa_accel.c */
static _X_INLINE Bool
exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
- unsigned int fillStyle, unsigned char alu,
- unsigned int clientClipType)
+ unsigned int fillStyle, unsigned char alu,
+ unsigned int clientClipType)
{
return ((alu != GXcopy && alu != GXclear && alu != GXset &&
- alu != GXcopyInverted) || fillStyle == FillStippled ||
- clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask));
+ alu != GXcopyInverted) || fillStyle == FillStippled ||
+ clientClipType != CT_NONE ||
+ !EXA_PM_IS_SOLID(pDrawable, planemask));
}
void
-exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
Bool
-exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
- DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
- unsigned int clientClipType);
+
+exaFillRegionTiled(DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType);
void
-exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d);
+
+exaGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
RegionPtr
+
exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx, int dsty);
+ int srcx, int srcy, int width, int height, int dstx, int dsty);
Bool
-exaHWCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown);
-
-void
-exaCopyNtoN (DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GCPtr pGC,
- BoxPtr pbox,
- int nbox,
- int dx,
- int dy,
- Bool reverse,
- Bool upsidedown,
- Pixel bitplane,
- void *closure);
+
+exaHWCopyNtoN(DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox, int dx, int dy, Bool reverse, Bool upsidedown);
+
+void
+
+exaCopyNtoN(DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure);
extern const GCOps exaOps;
void
-ExaCheckComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-void
-ExaCheckGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
+
+ExaCheckComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+
+void
+
+ExaCheckGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
/* exa_offscreen.c */
void
-ExaOffscreenSwapOut (ScreenPtr pScreen);
+ ExaOffscreenSwapOut(ScreenPtr pScreen);
void
-ExaOffscreenSwapIn (ScreenPtr pScreen);
+ ExaOffscreenSwapIn(ScreenPtr pScreen);
-ExaOffscreenArea*
-ExaOffscreenDefragment (ScreenPtr pScreen);
+ExaOffscreenArea *ExaOffscreenDefragment(ScreenPtr pScreen);
Bool
-exaOffscreenInit(ScreenPtr pScreen);
+ exaOffscreenInit(ScreenPtr pScreen);
void
-ExaOffscreenFini (ScreenPtr pScreen);
+ ExaOffscreenFini(ScreenPtr pScreen);
/* exa.c */
Bool
-ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
+ ExaDoPrepareAccess(PixmapPtr pPixmap, int index);
void
-exaPrepareAccess(DrawablePtr pDrawable, int index);
+ exaPrepareAccess(DrawablePtr pDrawable, int index);
void
-exaFinishAccess(DrawablePtr pDrawable, int index);
+ exaFinishAccess(DrawablePtr pDrawable, int index);
void
-exaDestroyPixmap(PixmapPtr pPixmap);
+ exaDestroyPixmap(PixmapPtr pPixmap);
void
-exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
+ exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
void
-exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
- int *xp, int *yp);
+
+exaGetDrawableDeltas(DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *xp, int *yp);
Bool
-exaPixmapHasGpuCopy(PixmapPtr p);
+ exaPixmapHasGpuCopy(PixmapPtr p);
PixmapPtr
-exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp);
+ exaGetOffscreenPixmap(DrawablePtr pDrawable, int *xp, int *yp);
PixmapPtr
-exaGetDrawablePixmap(DrawablePtr pDrawable);
+ exaGetDrawablePixmap(DrawablePtr pDrawable);
void
+
exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
int w, int h, int bpp);
void
+
exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
int w, int h, int bpp);
void
-exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ exaDoMigration(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
Bool
-exaPixmapIsPinned (PixmapPtr pPix);
+ exaPixmapIsPinned(PixmapPtr pPix);
extern const GCFuncs exaGCFuncs;
/* exa_classic.c */
PixmapPtr
+
exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
+ unsigned usage_hint);
Bool
-exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
+
+exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData);
Bool
-exaDestroyPixmap_classic (PixmapPtr pPixmap);
+ exaDestroyPixmap_classic(PixmapPtr pPixmap);
Bool
-exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
+ exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap);
/* exa_driver.c */
PixmapPtr
+
exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
+ unsigned usage_hint);
Bool
-exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
+
+exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ pointer pPixData);
Bool
-exaDestroyPixmap_driver (PixmapPtr pPixmap);
+ exaDestroyPixmap_driver(PixmapPtr pPixmap);
Bool
-exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
+ exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap);
/* exa_mixed.c */
PixmapPtr
+
exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
+ unsigned usage_hint);
Bool
+
exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth,
- int bitsPerPixel, int devKind, pointer pPixData);
+ int bitsPerPixel, int devKind, pointer pPixData);
Bool
-exaDestroyPixmap_mixed(PixmapPtr pPixmap);
+ exaDestroyPixmap_mixed(PixmapPtr pPixmap);
Bool
-exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
+ exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap);
/* exa_migration_mixed.c */
void
-exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
+ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap);
void
-exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
void
-exaMoveInPixmap_mixed(PixmapPtr pPixmap);
+ exaMoveInPixmap_mixed(PixmapPtr pPixmap);
void
-exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
+ exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
void
-exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
/* exa_render.c */
Bool
-exaOpReadsDestination (CARD8 op);
+ exaOpReadsDestination(CARD8 op);
void
-exaComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
+
+exaComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
void
-exaCompositeRects(CARD8 op,
- PicturePtr Src,
- PicturePtr pMask,
- PicturePtr pDst,
- int nrect,
- ExaCompositeRectPtr rects);
+
+exaCompositeRects(CARD8 op,
+ PicturePtr Src,
+ PicturePtr pMask,
+ PicturePtr pDst, int nrect, ExaCompositeRectPtr rects);
void
-exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid *traps);
+
+exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid * traps);
void
-exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntri, xTriangle *tris);
+
+exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle * tris);
/* exa_glyph.c */
void
-exaGlyphsInit(ScreenPtr pScreen);
+ exaGlyphsInit(ScreenPtr pScreen);
void
-exaGlyphsFini (ScreenPtr pScreen);
+ exaGlyphsFini(ScreenPtr pScreen);
void
-exaGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
+
+exaGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs);
/* exa_migration_classic.c */
void
-exaCopyDirtyToSys (ExaMigrationPtr migrate);
+ exaCopyDirtyToSys(ExaMigrationPtr migrate);
void
-exaCopyDirtyToFb (ExaMigrationPtr migrate);
+ exaCopyDirtyToFb(ExaMigrationPtr migrate);
void
-exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
+ exaDoMigration_classic(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel);
void
-exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area);
+ exaPixmapSave(ScreenPtr pScreen, ExaOffscreenArea * area);
void
-exaMoveOutPixmap_classic (PixmapPtr pPixmap);
+ exaMoveOutPixmap_classic(PixmapPtr pPixmap);
void
-exaMoveInPixmap_classic (PixmapPtr pPixmap);
+ exaMoveInPixmap_classic(PixmapPtr pPixmap);
void
-exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
+ exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg);
-#endif /* EXAPRIV_H */
+#endif /* EXAPRIV_H */
diff --git a/xorg-server/exa/exa_render.c b/xorg-server/exa/exa_render.c
index 3974afe87..172e2b56d 100644
--- a/xorg-server/exa/exa_render.c
+++ b/xorg-server/exa/exa_render.c
@@ -33,7 +33,8 @@
#include "mipict.h"
#if DEBUG_TRACE_FALL
-static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
+static void
+exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
{
char format[20];
char size[20];
@@ -41,76 +42,73 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
int temp;
if (!pict) {
- snprintf(string, n, "None");
- return;
+ snprintf(string, n, "None");
+ return;
}
- switch (pict->format)
- {
+ switch (pict->format) {
case PICT_a8r8g8b8:
- snprintf(format, 20, "ARGB8888");
- break;
+ snprintf(format, 20, "ARGB8888");
+ break;
case PICT_x8r8g8b8:
- snprintf(format, 20, "XRGB8888");
- break;
+ snprintf(format, 20, "XRGB8888");
+ break;
case PICT_b8g8r8a8:
- snprintf(format, 20, "BGRA8888");
- break;
+ snprintf(format, 20, "BGRA8888");
+ break;
case PICT_b8g8r8x8:
- snprintf(format, 20, "BGRX8888");
- break;
+ snprintf(format, 20, "BGRX8888");
+ break;
case PICT_r5g6b5:
- snprintf(format, 20, "RGB565 ");
- break;
+ snprintf(format, 20, "RGB565 ");
+ break;
case PICT_x1r5g5b5:
- snprintf(format, 20, "RGB555 ");
- break;
+ snprintf(format, 20, "RGB555 ");
+ break;
case PICT_a8:
- snprintf(format, 20, "A8 ");
- break;
+ snprintf(format, 20, "A8 ");
+ break;
case PICT_a1:
- snprintf(format, 20, "A1 ");
- break;
+ snprintf(format, 20, "A1 ");
+ break;
default:
- snprintf(format, 20, "0x%x", (int)pict->format);
- break;
+ snprintf(format, 20, "0x%x", (int) pict->format);
+ break;
}
if (pict->pDrawable) {
- loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
+ loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
- snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
- pict->pDrawable->height, pict->repeat ?
- " R" : "");
- } else {
- loc = '-';
+ snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+ pict->pDrawable->height, pict->repeat ? " R" : "");
+ }
+ else {
+ loc = '-';
- snprintf(size, 20, "%s", pict->repeat ? " R" : "");
+ snprintf(size, 20, "%s", pict->repeat ? " R" : "");
}
- snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size);
+ snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format,
+ size);
}
static void
exaPrintCompositeFallback(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst)
+ PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
{
char sop[20];
char srcdesc[40], maskdesc[40], dstdesc[40];
- switch(op)
- {
+ switch (op) {
case PictOpSrc:
- snprintf(sop, sizeof(sop), "Src");
- break;
+ snprintf(sop, sizeof(sop), "Src");
+ break;
case PictOpOver:
- snprintf(sop, sizeof(sop), "Over");
- break;
+ snprintf(sop, sizeof(sop), "Over");
+ break;
default:
- snprintf(sop, sizeof(sop), "0x%x", (int)op);
- break;
+ snprintf(sop, sizeof(sop), "0x%x", (int) op);
+ break;
}
exaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
@@ -118,15 +116,14 @@ exaPrintCompositeFallback(CARD8 op,
exaCompositeFallbackPictDesc(pDst, dstdesc, 40);
ErrorF("Composite fallback: op %s, \n"
- " src %s, \n"
- " mask %s, \n"
- " dst %s, \n",
- sop, srcdesc, maskdesc, dstdesc);
+ " src %s, \n"
+ " mask %s, \n"
+ " dst %s, \n", sop, srcdesc, maskdesc, dstdesc);
}
-#endif /* DEBUG_TRACE_FALL */
+#endif /* DEBUG_TRACE_FALL */
Bool
-exaOpReadsDestination (CARD8 op)
+exaOpReadsDestination(CARD8 op)
{
/* FALSE (does not read destination) is the list of ops in the protocol
* document with "0" in the "Fb" column and no "Ab" in the "Fa" column.
@@ -136,20 +133,17 @@ exaOpReadsDestination (CARD8 op)
switch (op) {
case PictOpClear:
case PictOpSrc:
- return FALSE;
+ return FALSE;
default:
- return TRUE;
+ return TRUE;
}
}
-
static Bool
-exaGetPixelFromRGBA(CARD32 *pixel,
- CARD16 red,
- CARD16 green,
- CARD16 blue,
- CARD16 alpha,
- PictFormatPtr pFormat)
+exaGetPixelFromRGBA(CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue, CARD16 alpha, PictFormatPtr pFormat)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
@@ -157,8 +151,8 @@ exaGetPixelFromRGBA(CARD32 *pixel,
*pixel = 0;
if (!PICT_FORMAT_COLOR(pFormat->format) &&
- PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
- return FALSE;
+ PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
+ return FALSE;
rbits = PICT_FORMAT_R(pFormat->format);
gbits = PICT_FORMAT_G(pFormat->format);
@@ -170,28 +164,27 @@ exaGetPixelFromRGBA(CARD32 *pixel,
bshift = pFormat->direct.blue;
ashift = pFormat->direct.alpha;
- *pixel |= ( blue >> (16 - bbits)) << bshift;
- *pixel |= ( red >> (16 - rbits)) << rshift;
- *pixel |= (green >> (16 - gbits)) << gshift;
- *pixel |= (alpha >> (16 - abits)) << ashift;
+ *pixel |= (blue >> (16 - bbits)) << bshift;
+ *pixel |= (red >> (16 - rbits)) << rshift;
+ *pixel |= (green >> (16 - gbits)) << gshift;
+ *pixel |= (alpha >> (16 - abits)) << ashift;
return TRUE;
}
static Bool
-exaGetRGBAFromPixel(CARD32 pixel,
- CARD16 *red,
- CARD16 *green,
- CARD16 *blue,
- CARD16 *alpha,
- PictFormatPtr pFormat,
- PictFormatShort format)
+exaGetRGBAFromPixel(CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ PictFormatPtr pFormat, PictFormatShort format)
{
int rbits, bbits, gbits, abits;
int rshift, bshift, gshift, ashift;
if (!PICT_FORMAT_COLOR(format) && PICT_FORMAT_TYPE(format) != PICT_TYPE_A)
- return FALSE;
+ return FALSE;
rbits = PICT_FORMAT_R(format);
gbits = PICT_FORMAT_G(format);
@@ -199,66 +192,67 @@ exaGetRGBAFromPixel(CARD32 pixel,
abits = PICT_FORMAT_A(format);
if (pFormat) {
- rshift = pFormat->direct.red;
- gshift = pFormat->direct.green;
- bshift = pFormat->direct.blue;
- ashift = pFormat->direct.alpha;
- } else if (format == PICT_a8r8g8b8) {
- rshift = 16;
- gshift = 8;
- bshift = 0;
- ashift = 24;
- } else
- FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match "
- "createSourcePicture()\n");
+ rshift = pFormat->direct.red;
+ gshift = pFormat->direct.green;
+ bshift = pFormat->direct.blue;
+ ashift = pFormat->direct.alpha;
+ }
+ else if (format == PICT_a8r8g8b8) {
+ rshift = 16;
+ gshift = 8;
+ bshift = 0;
+ ashift = 24;
+ }
+ else
+ FatalError("EXA bug: exaGetRGBAFromPixel() doesn't match "
+ "createSourcePicture()\n");
if (rbits) {
- *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
- while (rbits < 16) {
- *red |= *red >> rbits;
- rbits <<= 1;
- }
-
- *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
- while (gbits < 16) {
- *green |= *green >> gbits;
- gbits <<= 1;
- }
-
- *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
- while (bbits < 16) {
- *blue |= *blue >> bbits;
- bbits <<= 1;
- }
- } else {
- *red = 0x0000;
- *green = 0x0000;
- *blue = 0x0000;
+ *red = ((pixel >> rshift) & ((1 << rbits) - 1)) << (16 - rbits);
+ while (rbits < 16) {
+ *red |= *red >> rbits;
+ rbits <<= 1;
+ }
+
+ *green = ((pixel >> gshift) & ((1 << gbits) - 1)) << (16 - gbits);
+ while (gbits < 16) {
+ *green |= *green >> gbits;
+ gbits <<= 1;
+ }
+
+ *blue = ((pixel >> bshift) & ((1 << bbits) - 1)) << (16 - bbits);
+ while (bbits < 16) {
+ *blue |= *blue >> bbits;
+ bbits <<= 1;
+ }
+ }
+ else {
+ *red = 0x0000;
+ *green = 0x0000;
+ *blue = 0x0000;
}
if (abits) {
- *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
- while (abits < 16) {
- *alpha |= *alpha >> abits;
- abits <<= 1;
- }
- } else
- *alpha = 0xffff;
+ *alpha = ((pixel >> ashift) & ((1 << abits) - 1)) << (16 - abits);
+ while (abits < 16) {
+ *alpha |= *alpha >> abits;
+ abits <<= 1;
+ }
+ }
+ else
+ *alpha = 0xffff;
return TRUE;
}
static int
-exaTryDriverSolidFill(PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+exaTryDriverSolidFill(PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
RegionRec region;
BoxPtr pbox;
int nbox;
@@ -268,75 +262,71 @@ exaTryDriverSolidFill(PicturePtr pSrc,
CARD32 pixel;
CARD16 red, green, blue, alpha;
- pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
pDstExaPix = ExaGetPixmapPriv(pDstPix);
/* Check whether the accelerator can use the destination pixmap.
*/
- if (pDstExaPix->accel_blocked)
- {
- return -1;
+ if (pDstExaPix->accel_blocked) {
+ return -1;
}
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pSrc->pDrawable) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
}
- if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
- xSrc, ySrc, 0, 0, xDst, yDst,
- width, height))
- return 1;
+ if (!miComputeCompositeRegion(&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst, width, height))
+ return 1;
- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
+ exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
RegionTranslate(&region, dst_off_x, dst_off_y);
if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
- pixel = exaGetPixmapFirstPixel (pSrcPix);
- } else
- pixel = pSrc->pSourcePict->solidFill.color;
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pixel = exaGetPixmapFirstPixel(pSrcPix);
+ }
+ else
+ pixel = pSrc->pSourcePict->solidFill.color;
if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
- pSrc->pFormat, pSrc->format) ||
- !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
- pDst->pFormat))
- {
- RegionUninit(&region);
- return -1;
+ pSrc->pFormat, pSrc->format) ||
+ !exaGetPixelFromRGBA(&pixel, red, green, blue, alpha, pDst->pFormat)) {
+ RegionUninit(&region);
+ return -1;
}
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[1];
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pDstPix;
- pixmaps[0].pReg = &region;
- exaDoMigration(pixmaps, 1, TRUE);
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pDstPix;
+ pixmaps[0].pReg = &region;
+ exaDoMigration(pixmaps, 1, TRUE);
}
if (!exaPixmapHasGpuCopy(pDstPix)) {
- RegionUninit(&region);
- return 0;
+ RegionUninit(&region);
+ return 0;
}
- if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
- {
- RegionUninit(&region);
- return -1;
+ if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel)) {
+ RegionUninit(&region);
+ return -1;
}
nbox = RegionNumRects(&region);
pbox = RegionRects(&region);
- while (nbox--)
- {
- (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
- pbox++;
+ while (nbox--) {
+ (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2,
+ pbox->y2);
+ pbox++;
}
(*pExaScr->info->DoneSolid) (pDstPix);
@@ -347,30 +337,29 @@ exaTryDriverSolidFill(PicturePtr pSrc,
}
static int
-exaTryDriverCompositeRects(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- int nrect,
- ExaCompositeRectPtr rects)
+exaTryDriverCompositeRects(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ int nrect, ExaCompositeRectPtr rects)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
int src_off_x = 0, src_off_y = 0, mask_off_x = 0, mask_off_y = 0;
int dst_off_x, dst_off_y;
PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
if (!pExaScr->info->PrepareComposite)
- return -1;
+ return -1;
if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
}
if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
}
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
@@ -381,122 +370,120 @@ exaTryDriverCompositeRects(CARD8 op,
* happens within limits.
*/
if (pDstExaPix->accel_blocked ||
- (pSrcExaPix && pSrcExaPix->accel_blocked) ||
- (pMaskExaPix && pMaskExaPix->accel_blocked))
- {
- return -1;
+ (pSrcExaPix && pSrcExaPix->accel_blocked) ||
+ (pMaskExaPix && pMaskExaPix->accel_blocked)) {
+ return -1;
}
if (pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
- {
- return -1;
+ !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) {
+ return -1;
}
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[3];
- int i = 0;
-
- pixmaps[i].as_dst = TRUE;
- pixmaps[i].as_src = exaOpReadsDestination(op);
- pixmaps[i].pPix = pDstPix;
- pixmaps[i].pReg = NULL;
- i++;
-
- if (pSrcPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pSrcPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- if (pMaskPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pMaskPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- exaDoMigration(pixmaps, i, TRUE);
+ ExaMigrationRec pixmaps[3];
+ int i = 0;
+
+ pixmaps[i].as_dst = TRUE;
+ pixmaps[i].as_src = exaOpReadsDestination(op);
+ pixmaps[i].pPix = pDstPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+
+ if (pSrcPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pSrcPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ if (pMaskPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pMaskPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ exaDoMigration(pixmaps, i, TRUE);
}
- pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
+ pDstPix = exaGetOffscreenPixmap(pDst->pDrawable, &dst_off_x, &dst_off_y);
if (!pDstPix)
- return 0;
+ return 0;
if (pSrcPix) {
- pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
- if (!pSrcPix)
- return 0;
+ pSrcPix =
+ exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y);
+ if (!pSrcPix)
+ return 0;
}
if (pMaskPix) {
- pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
- if (!pMaskPix)
- return 0;
+ pMaskPix =
+ exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x, &mask_off_y);
+ if (!pMaskPix)
+ return 0;
}
if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
- pMaskPix, pDstPix))
- return -1;
-
- while (nrect--)
- {
- INT16 xDst = rects->xDst + pDst->pDrawable->x;
- INT16 yDst = rects->yDst + pDst->pDrawable->y;
- INT16 xMask = rects->xMask;
- INT16 yMask = rects->yMask;
- INT16 xSrc = rects->xSrc;
- INT16 ySrc = rects->ySrc;
- RegionRec region;
- BoxPtr pbox;
- int nbox;
-
- if (pMaskPix) {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
- }
-
- if (pSrcPix) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
- }
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- rects->width, rects->height))
- goto next_rect;
-
- RegionTranslate(&region, dst_off_x, dst_off_y);
-
- nbox = RegionNumRects(&region);
- pbox = RegionRects(&region);
-
- xMask = xMask + mask_off_x - xDst - dst_off_x;
- yMask = yMask + mask_off_y - yDst - dst_off_y;
- xSrc = xSrc + src_off_x - xDst - dst_off_x;
- ySrc = ySrc + src_off_y - yDst - dst_off_y;
-
- while (nbox--)
- {
- (*pExaScr->info->Composite) (pDstPix,
- pbox->x1 + xSrc,
- pbox->y1 + ySrc,
- pbox->x1 + xMask,
- pbox->y1 + yMask,
- pbox->x1,
- pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
- }
-
- next_rect:
- RegionUninit(&region);
-
- rects++;
+ pMaskPix, pDstPix))
+ return -1;
+
+ while (nrect--) {
+ INT16 xDst = rects->xDst + pDst->pDrawable->x;
+ INT16 yDst = rects->yDst + pDst->pDrawable->y;
+ INT16 xMask = rects->xMask;
+ INT16 yMask = rects->yMask;
+ INT16 xSrc = rects->xSrc;
+ INT16 ySrc = rects->ySrc;
+ RegionRec region;
+ BoxPtr pbox;
+ int nbox;
+
+ if (pMaskPix) {
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+ }
+
+ if (pSrcPix) {
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+ }
+
+ if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ rects->width, rects->height))
+ goto next_rect;
+
+ RegionTranslate(&region, dst_off_x, dst_off_y);
+
+ nbox = RegionNumRects(&region);
+ pbox = RegionRects(&region);
+
+ xMask = xMask + mask_off_x - xDst - dst_off_x;
+ yMask = yMask + mask_off_y - yDst - dst_off_y;
+ xSrc = xSrc + src_off_x - xDst - dst_off_x;
+ ySrc = ySrc + src_off_y - yDst - dst_off_y;
+
+ while (nbox--) {
+ (*pExaScr->info->Composite) (pDstPix,
+ pbox->x1 + xSrc,
+ pbox->y1 + ySrc,
+ pbox->x1 + xMask,
+ pbox->y1 + yMask,
+ pbox->x1,
+ pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ next_rect:
+ RegionUninit(&region);
+
+ rects++;
}
(*pExaScr->info->DoneComposite) (pDstPix);
@@ -513,14 +500,12 @@ exaTryDriverCompositeRects(CARD8 op,
* software.
*/
void
-exaCompositeRects(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- int nrect,
- ExaCompositeRectPtr rects)
+exaCompositeRects(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst, int nrect, ExaCompositeRectPtr rects)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
int n;
ExaCompositeRectPtr r;
int ret;
@@ -529,123 +514,125 @@ exaCompositeRects(CARD8 op,
* destination directly, so the damage layer takes care of this.
*/
if (!pMask) {
- RegionRec region;
- int x1 = MAXSHORT;
- int y1 = MAXSHORT;
- int x2 = MINSHORT;
- int y2 = MINSHORT;
- BoxRec box;
-
- /* We have to manage the damage ourselves, since CompositeRects isn't
- * something in the screen that can be managed by the damage extension,
- * and EXA depends on damage to track what needs to be migrated between
- * the gpu and the cpu.
- */
-
- /* Compute the overall extents of the composited region - we're making
- * the assumption here that we are compositing a bunch of glyphs that
- * cluster closely together and damaging each glyph individually would
- * be a loss compared to damaging the bounding box.
- */
- n = nrect;
- r = rects;
- while (n--) {
- int rect_x2 = r->xDst + r->width;
- int rect_y2 = r->yDst + r->height;
-
- if (r->xDst < x1) x1 = r->xDst;
- if (r->yDst < y1) y1 = r->yDst;
- if (rect_x2 > x2) x2 = rect_x2;
- if (rect_y2 > y2) y2 = rect_y2;
-
- r++;
- }
-
- if (x2 <= x1 || y2 <= y1)
- return;
-
- box.x1 = x1;
- box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT;
- box.y1 = y1;
- box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT;
-
- /* The pixmap migration code relies on pendingDamage indicating
- * the bounds of the current rendering, so we need to force
- * the actual damage into that region before we do anything, and
- * (see use of DamagePendingRegion in exaCopyDirty)
- */
-
- RegionInit(&region, &box, 1);
-
- DamageRegionAppend(pDst->pDrawable, &region);
-
- RegionUninit(&region);
+ RegionRec region;
+ int x1 = MAXSHORT;
+ int y1 = MAXSHORT;
+ int x2 = MINSHORT;
+ int y2 = MINSHORT;
+ BoxRec box;
+
+ /* We have to manage the damage ourselves, since CompositeRects isn't
+ * something in the screen that can be managed by the damage extension,
+ * and EXA depends on damage to track what needs to be migrated between
+ * the gpu and the cpu.
+ */
+
+ /* Compute the overall extents of the composited region - we're making
+ * the assumption here that we are compositing a bunch of glyphs that
+ * cluster closely together and damaging each glyph individually would
+ * be a loss compared to damaging the bounding box.
+ */
+ n = nrect;
+ r = rects;
+ while (n--) {
+ int rect_x2 = r->xDst + r->width;
+ int rect_y2 = r->yDst + r->height;
+
+ if (r->xDst < x1)
+ x1 = r->xDst;
+ if (r->yDst < y1)
+ y1 = r->yDst;
+ if (rect_x2 > x2)
+ x2 = rect_x2;
+ if (rect_y2 > y2)
+ y2 = rect_y2;
+
+ r++;
+ }
+
+ if (x2 <= x1 || y2 <= y1)
+ return;
+
+ box.x1 = x1;
+ box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT;
+ box.y1 = y1;
+ box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT;
+
+ /* The pixmap migration code relies on pendingDamage indicating
+ * the bounds of the current rendering, so we need to force
+ * the actual damage into that region before we do anything, and
+ * (see use of DamagePendingRegion in exaCopyDirty)
+ */
+
+ RegionInit(&region, &box, 1);
+
+ DamageRegionAppend(pDst->pDrawable, &region);
+
+ RegionUninit(&region);
}
-
+
/************************************************************/
-
- ValidatePicture (pSrc);
+
+ ValidatePicture(pSrc);
if (pMask)
- ValidatePicture (pMask);
- ValidatePicture (pDst);
+ ValidatePicture(pMask);
+ ValidatePicture(pDst);
ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects);
if (ret != 1) {
- if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
- (!pExaScr->info->CheckComposite ||
- ((*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
- pDst) &&
- (*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))) {
- ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask,
- pDst, nrect, rects);
- if (ret == 1) {
- op = PictOpAdd;
- ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
- rects);
- }
- }
-
- if (ret != 1) {
- n = nrect;
- r = rects;
- while (n--) {
- ExaCheckComposite (op, pSrc, pMask, pDst,
- r->xSrc, r->ySrc,
- r->xMask, r->yMask,
- r->xDst, r->yDst,
- r->width, r->height);
- r++;
- }
- }
+ if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
+ (!pExaScr->info->CheckComposite ||
+ ((*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask,
+ pDst) &&
+ (*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask,
+ pDst)))) {
+ ret =
+ exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask, pDst,
+ nrect, rects);
+ if (ret == 1) {
+ op = PictOpAdd;
+ ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
+ rects);
+ }
+ }
+
+ if (ret != 1) {
+ n = nrect;
+ r = rects;
+ while (n--) {
+ ExaCheckComposite(op, pSrc, pMask, pDst,
+ r->xSrc, r->ySrc,
+ r->xMask, r->yMask,
+ r->xDst, r->yDst, r->width, r->height);
+ r++;
+ }
+ }
}
-
+
/************************************************************/
if (!pMask) {
- /* Now we have to flush the damage out from pendingDamage => damage
- * Calling DamageRegionProcessPending has that effect.
- */
+ /* Now we have to flush the damage out from pendingDamage => damage
+ * Calling DamageRegionProcessPending has that effect.
+ */
- DamageRegionProcessPending(pDst->pDrawable);
+ DamageRegionProcessPending(pDst->pDrawable);
}
}
static int
-exaTryDriverComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+exaTryDriverComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
RegionRec region;
BoxPtr pbox;
int nbox;
@@ -654,15 +641,15 @@ exaTryDriverComposite(CARD8 op,
ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
}
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
pDstExaPix = ExaGetPixmapPriv(pDstPix);
if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
}
@@ -671,96 +658,94 @@ exaTryDriverComposite(CARD8 op,
* happens within limits.
*/
if (pDstExaPix->accel_blocked ||
- (pSrcExaPix && pSrcExaPix->accel_blocked) ||
- (pMaskExaPix && (pMaskExaPix->accel_blocked)))
- {
- return -1;
+ (pSrcExaPix && pSrcExaPix->accel_blocked) ||
+ (pMaskExaPix && (pMaskExaPix->accel_blocked))) {
+ return -1;
}
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pMaskPix) {
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
}
if (pSrcPix) {
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
}
if (pExaScr->info->CheckComposite &&
- !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
- {
- return -1;
+ !(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst)) {
+ return -1;
}
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return 1;
+ if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return 1;
- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
+ exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
RegionTranslate(&region, dst_off_x, dst_off_y);
if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[3];
- int i = 0;
-
- pixmaps[i].as_dst = TRUE;
- pixmaps[i].as_src = exaOpReadsDestination(op);
- pixmaps[i].pPix = pDstPix;
- pixmaps[i].pReg = pixmaps[0].as_src ? NULL : &region;
- i++;
-
- if (pSrcPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pSrcPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- if (pMaskPix) {
- pixmaps[i].as_dst = FALSE;
- pixmaps[i].as_src = TRUE;
- pixmaps[i].pPix = pMaskPix;
- pixmaps[i].pReg = NULL;
- i++;
- }
-
- exaDoMigration(pixmaps, i, TRUE);
+ ExaMigrationRec pixmaps[3];
+ int i = 0;
+
+ pixmaps[i].as_dst = TRUE;
+ pixmaps[i].as_src = exaOpReadsDestination(op);
+ pixmaps[i].pPix = pDstPix;
+ pixmaps[i].pReg = pixmaps[0].as_src ? NULL : &region;
+ i++;
+
+ if (pSrcPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pSrcPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ if (pMaskPix) {
+ pixmaps[i].as_dst = FALSE;
+ pixmaps[i].as_src = TRUE;
+ pixmaps[i].pPix = pMaskPix;
+ pixmaps[i].pReg = NULL;
+ i++;
+ }
+
+ exaDoMigration(pixmaps, i, TRUE);
}
if (pSrcPix) {
- pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
- if (!pSrcPix) {
- RegionUninit(&region);
- return 0;
- }
+ pSrcPix =
+ exaGetOffscreenPixmap(pSrc->pDrawable, &src_off_x, &src_off_y);
+ if (!pSrcPix) {
+ RegionUninit(&region);
+ return 0;
+ }
}
if (pMaskPix) {
- pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
- &mask_off_y);
- if (!pMaskPix) {
- RegionUninit(&region);
- return 0;
- }
+ pMaskPix = exaGetOffscreenPixmap(pMask->pDrawable, &mask_off_x,
+ &mask_off_y);
+ if (!pMaskPix) {
+ RegionUninit(&region);
+ return 0;
+ }
}
if (!exaPixmapHasGpuCopy(pDstPix)) {
- RegionUninit(&region);
- return 0;
+ RegionUninit(&region);
+ return 0;
}
if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
- pMaskPix, pDstPix))
- {
- RegionUninit(&region);
- return -1;
+ pMaskPix, pDstPix)) {
+ RegionUninit(&region);
+ return -1;
}
nbox = RegionNumRects(&region);
@@ -772,18 +757,16 @@ exaTryDriverComposite(CARD8 op,
xSrc = xSrc + src_off_x - xDst - dst_off_x;
ySrc = ySrc + src_off_y - yDst - dst_off_y;
- while (nbox--)
- {
- (*pExaScr->info->Composite) (pDstPix,
- pbox->x1 + xSrc,
- pbox->y1 + ySrc,
- pbox->x1 + xMask,
- pbox->y1 + yMask,
- pbox->x1,
- pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- pbox++;
+ while (nbox--) {
+ (*pExaScr->info->Composite) (pDstPix,
+ pbox->x1 + xSrc,
+ pbox->y1 + ySrc,
+ pbox->x1 + xMask,
+ pbox->y1 + yMask,
+ pbox->x1,
+ pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
}
(*pExaScr->info->DoneComposite) (pDstPix);
exaMarkSync(pDst->pDrawable->pScreen);
@@ -843,28 +826,25 @@ exaTryDriverComposite(CARD8 op,
static int
exaTryMagicTwoPassCompositeHelper(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst, CARD16 width, CARD16 height)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
assert(op == PictOpOver);
if (pExaScr->info->CheckComposite &&
- (!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
- pDst) ||
- !(*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))
- {
- return -1;
+ (!(*pExaScr->info->CheckComposite) (PictOpOutReverse, pSrc, pMask,
+ pDst) ||
+ !(*pExaScr->info->CheckComposite) (PictOpAdd, pSrc, pMask, pDst))) {
+ return -1;
}
/* Now, we think we should be able to accelerate this operation. First,
@@ -872,204 +852,197 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
* factors.
*/
exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
+ xDst, yDst, width, height);
/* Then, add in the source value times the destination alpha factors (1.0).
*/
exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
+ xDst, yDst, width, height);
return 1;
}
void
-exaComposite(CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+exaComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
- ExaScreenPriv (pDst->pDrawable->pScreen);
+ ExaScreenPriv(pDst->pDrawable->pScreen);
int ret = -1;
Bool saveSrcRepeat = pSrc->repeat;
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
RegionRec region;
if (pExaScr->swappedOut)
- goto fallback;
+ goto fallback;
/* Remove repeat in source if useless */
if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
- (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
- (ySrc + height) <= pSrc->pDrawable->height)
- pSrc->repeat = 0;
+ (xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
+ (ySrc + height) <= pSrc->pDrawable->height)
+ pSrc->repeat = 0;
if (!pMask && !pSrc->alphaMap && !pDst->alphaMap &&
- (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format))))
+ (op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format))))
{
- if (pSrc->pDrawable ?
- (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
- pSrc->repeat) :
- (pSrc->pSourcePict->type == SourcePictTypeSolidFill))
- {
- ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- } else if (pSrc->pDrawable && !pSrc->transform &&
- ((op == PictOpSrc &&
- (pSrc->format == pDst->format ||
- (PICT_FORMAT_COLOR(pDst->format) &&
- PICT_FORMAT_COLOR(pSrc->format) &&
- pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
- PICT_FORMAT_TYPE(pSrc->format),
- 0,
- PICT_FORMAT_R(pSrc->format),
- PICT_FORMAT_G(pSrc->format),
- PICT_FORMAT_B(pSrc->format))))) ||
- (op == PictOpOver && pSrc->format == pDst->format &&
- !PICT_FORMAT_A(pSrc->format))))
- {
- if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
- (xSrc + width <= pSrc->pDrawable->width) &&
- (ySrc + height <= pSrc->pDrawable->height))
- {
- Bool ret;
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst,
- yDst, width, height))
- goto done;
-
- ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
- RegionRects(&region), RegionNumRects(&region),
- xSrc - xDst, ySrc - yDst, FALSE, FALSE);
- RegionUninit(&region);
-
- /* Reset values to their original values. */
- xDst -= pDst->pDrawable->x;
- yDst -= pDst->pDrawable->y;
- xSrc -= pSrc->pDrawable->x;
- ySrc -= pSrc->pDrawable->y;
-
- if (!ret)
- goto fallback;
-
- goto done;
- }
-
- if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
- pSrc->pDrawable->type == DRAWABLE_PIXMAP)
- {
- DDXPointRec patOrg;
-
- /* Let's see if the driver can do the repeat in one go */
- if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
- !pDst->alphaMap)
- {
- ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
-
- /* Now see if we can use exaFillRegionTiled() */
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst,
- width, height))
- goto done;
-
- /* pattern origin is the point in the destination drawable
- * corresponding to (0,0) in the source */
- patOrg.x = xDst - xSrc;
- patOrg.y = yDst - ySrc;
-
- ret = exaFillRegionTiled(pDst->pDrawable, &region,
- (PixmapPtr)pSrc->pDrawable,
- &patOrg, FB_ALLONES, GXcopy, CT_NONE);
-
- RegionUninit(&region);
-
- if (ret)
- goto done;
-
- /* Let's be correct and restore the variables to their original state. */
- xDst -= pDst->pDrawable->x;
- yDst -= pDst->pDrawable->y;
- xSrc -= pSrc->pDrawable->x;
- ySrc -= pSrc->pDrawable->y;
- }
- }
+ if (pSrc->pDrawable ?
+ (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+ pSrc->repeat) :
+ (pSrc->pSourcePict->type == SourcePictTypeSolidFill)) {
+ ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
+ else if (pSrc->pDrawable && !pSrc->transform &&
+ ((op == PictOpSrc &&
+ (pSrc->format == pDst->format ||
+ (PICT_FORMAT_COLOR(pDst->format) &&
+ PICT_FORMAT_COLOR(pSrc->format) &&
+ pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
+ PICT_FORMAT_TYPE(pSrc->format),
+ 0,
+ PICT_FORMAT_R(pSrc->format),
+ PICT_FORMAT_G(pSrc->format),
+ PICT_FORMAT_B(pSrc->format)))))
+ || (op == PictOpOver && pSrc->format == pDst->format &&
+ !PICT_FORMAT_A(pSrc->format)))) {
+ if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
+ (xSrc + width <= pSrc->pDrawable->width) &&
+ (ySrc + height <= pSrc->pDrawable->height)) {
+ Bool ret;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst,
+ yDst, width, height))
+ goto done;
+
+ ret = exaHWCopyNtoN(pSrc->pDrawable, pDst->pDrawable, NULL,
+ RegionRects(&region),
+ RegionNumRects(&region), xSrc - xDst,
+ ySrc - yDst, FALSE, FALSE);
+ RegionUninit(&region);
+
+ /* Reset values to their original values. */
+ xDst -= pDst->pDrawable->x;
+ yDst -= pDst->pDrawable->y;
+ xSrc -= pSrc->pDrawable->x;
+ ySrc -= pSrc->pDrawable->y;
+
+ if (!ret)
+ goto fallback;
+
+ goto done;
+ }
+
+ if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
+ pSrc->pDrawable->type == DRAWABLE_PIXMAP) {
+ DDXPointRec patOrg;
+
+ /* Let's see if the driver can do the repeat in one go */
+ if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
+ !pDst->alphaMap) {
+ ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
+
+ /* Now see if we can use exaFillRegionTiled() */
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion(&region, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ goto done;
+
+ /* pattern origin is the point in the destination drawable
+ * corresponding to (0,0) in the source */
+ patOrg.x = xDst - xSrc;
+ patOrg.y = yDst - ySrc;
+
+ ret = exaFillRegionTiled(pDst->pDrawable, &region,
+ (PixmapPtr) pSrc->pDrawable,
+ &patOrg, FB_ALLONES, GXcopy, CT_NONE);
+
+ RegionUninit(&region);
+
+ if (ret)
+ goto done;
+
+ /* Let's be correct and restore the variables to their original state. */
+ xDst -= pDst->pDrawable->x;
+ yDst -= pDst->pDrawable->y;
+ xSrc -= pSrc->pDrawable->x;
+ ySrc -= pSrc->pDrawable->y;
+ }
+ }
}
/* Remove repeat in mask if useless */
if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform &&
- xMask >= 0 && (xMask + width) <= pMask->pDrawable->width &&
- yMask >= 0 && (yMask + height) <= pMask->pDrawable->height)
- pMask->repeat = 0;
+ xMask >= 0 && (xMask + width) <= pMask->pDrawable->width &&
+ yMask >= 0 && (yMask + height) <= pMask->pDrawable->height)
+ pMask->repeat = 0;
if (pExaScr->info->PrepareComposite &&
- !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
- {
- Bool isSrcSolid;
-
- ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
- yMask, xDst, yDst, width, height);
- if (ret == 1)
- goto done;
-
- /* For generic masks and solid src pictures, mach64 can do Over in two
- * passes, similar to the component-alpha case.
- */
- isSrcSolid = pSrc->pDrawable ?
- (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
- pSrc->repeat) :
- (pSrc->pSourcePict->type == SourcePictTypeSolidFill);
-
- /* If we couldn't do the Composite in a single pass, and it was a
- * component-alpha Over, see if we can do it in two passes with
- * an OutReverse and then an Add.
- */
- if (ret == -1 && op == PictOpOver && pMask &&
- (pMask->componentAlpha || isSrcSolid)) {
- ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
- xSrc, ySrc,
- xMask, yMask, xDst, yDst,
- width, height);
- if (ret == 1)
- goto done;
- }
+ !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) {
+ Bool isSrcSolid;
+
+ ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
+ yMask, xDst, yDst, width, height);
+ if (ret == 1)
+ goto done;
+
+ /* For generic masks and solid src pictures, mach64 can do Over in two
+ * passes, similar to the component-alpha case.
+ */
+ isSrcSolid = pSrc->pDrawable ?
+ (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+ pSrc->repeat) :
+ (pSrc->pSourcePict->type == SourcePictTypeSolidFill);
+
+ /* If we couldn't do the Composite in a single pass, and it was a
+ * component-alpha Over, see if we can do it in two passes with
+ * an OutReverse and then an Add.
+ */
+ if (ret == -1 && op == PictOpOver && pMask &&
+ (pMask->componentAlpha || isSrcSolid)) {
+ ret = exaTryMagicTwoPassCompositeHelper(op, pSrc, pMask, pDst,
+ xSrc, ySrc,
+ xMask, yMask, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
}
-fallback:
+ fallback:
#if DEBUG_TRACE_FALL
- exaPrintCompositeFallback (op, pSrc, pMask, pDst);
+ exaPrintCompositeFallback(op, pSrc, pMask, pDst);
#endif
- ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
- xMask, yMask, xDst, yDst, width, height);
+ ExaCheckComposite(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
-done:
+ done:
pSrc->repeat = saveSrcRepeat;
if (pMask)
- pMask->repeat = saveMaskRepeat;
+ pMask->repeat = saveMaskRepeat;
}
/**
@@ -1080,51 +1053,47 @@ done:
* See the comments about exaTrapezoids and exaTriangles.
*/
static PicturePtr
-exaCreateAlphaPicture (ScreenPtr pScreen,
- PicturePtr pDst,
- PictFormatPtr pPictFormat,
- CARD16 width,
- CARD16 height)
+exaCreateAlphaPicture(ScreenPtr pScreen,
+ PicturePtr pDst,
+ PictFormatPtr pPictFormat, CARD16 width, CARD16 height)
{
- PixmapPtr pPixmap;
- PicturePtr pPicture;
- GCPtr pGC;
- int error;
- xRectangle rect;
+ PixmapPtr pPixmap;
+ PicturePtr pPicture;
+ GCPtr pGC;
+ int error;
+ xRectangle rect;
if (width > 32767 || height > 32767)
- return 0;
-
- if (!pPictFormat)
- {
- if (pDst->polyEdge == PolyEdgeSharp)
- pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
- else
- pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
- if (!pPictFormat)
- return 0;
+ return 0;
+
+ if (!pPictFormat) {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ pPictFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
+ else
+ pPictFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
+ if (!pPictFormat)
+ return 0;
}
pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- pPictFormat->depth, 0);
+ pPictFormat->depth, 0);
if (!pPixmap)
- return 0;
- pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
- if (!pGC)
- {
- (*pScreen->DestroyPixmap) (pPixmap);
- return 0;
+ return 0;
+ pGC = GetScratchGC(pPixmap->drawable.depth, pScreen);
+ if (!pGC) {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ return 0;
}
- ValidateGC (&pPixmap->drawable, pGC);
+ ValidateGC(&pPixmap->drawable, pGC);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
- ExaCheckPolyFillRect (&pPixmap->drawable, pGC, 1, &rect);
- exaPixmapDirty (pPixmap, 0, 0, width, height);
- FreeScratchGC (pGC);
- pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
- 0, 0, serverClient, &error);
+ ExaCheckPolyFillRect(&pPixmap->drawable, pGC, 1, &rect);
+ exaPixmapDirty(pPixmap, 0, 0, width, height);
+ FreeScratchGC(pGC);
+ pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat,
+ 0, 0, serverClient, &error);
(*pScreen->DestroyPixmap) (pPixmap);
return pPicture;
}
@@ -1143,53 +1112,52 @@ exaCreateAlphaPicture (ScreenPtr pScreen,
* to initialize the contents.
*/
void
-exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid *traps)
+exaTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid * traps)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec bounds;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec bounds;
if (maskFormat) {
- PicturePtr pPicture;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- miTrapezoidBounds (ntrap, traps, &bounds);
-
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return;
-
- xDst = traps[0].left.p1.x >> 16;
- yDst = traps[0].left.p1.y >> 16;
-
- pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
-
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- for (; ntrap; ntrap--, traps++)
- (*ps->RasterizeTrapezoid) (pPicture, traps,
- -bounds.x1, -bounds.y1);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
-
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- } else {
- if (pDst->polyEdge == PolyEdgeSharp)
- maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
- else
- maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
- for (; ntrap; ntrap--, traps++)
- exaTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+ PicturePtr pPicture;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ miTrapezoidBounds(ntrap, traps, &bounds);
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+
+ xDst = traps[0].left.p1.x >> 16;
+ yDst = traps[0].left.p1.y >> 16;
+
+ pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ for (; ntrap; ntrap--, traps++)
+ (*ps->RasterizeTrapezoid) (pPicture, traps, -bounds.x1, -bounds.y1);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture(op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+ FreePicture(pPicture, 0);
+ }
+ else {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
+ for (; ntrap; ntrap--, traps++)
+ exaTrapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
}
}
@@ -1207,50 +1175,51 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
* to initialize the contents.
*/
void
-exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntri, xTriangle *tris)
+exaTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle * tris)
{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec bounds;
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec bounds;
if (maskFormat) {
- PicturePtr pPicture;
- INT16 xDst, yDst;
- INT16 xRel, yRel;
-
- miTriangleBounds (ntri, tris, &bounds);
-
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return;
-
- xDst = tris[0].p1.x >> 16;
- yDst = tris[0].p1.y >> 16;
-
- pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
- bounds.x2 - bounds.x1,
- bounds.y2 - bounds.y1);
- if (!pPicture)
- return;
-
- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
- (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
-
- xRel = bounds.x1 + xSrc - xDst;
- yRel = bounds.y1 + ySrc - yDst;
- CompositePicture (op, pSrc, pPicture, pDst,
- xRel, yRel, 0, 0, bounds.x1, bounds.y1,
- bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
- FreePicture (pPicture, 0);
- } else {
- if (pDst->polyEdge == PolyEdgeSharp)
- maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
- else
- maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
-
- for (; ntri; ntri--, tris++)
- exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
+ PicturePtr pPicture;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ miTriangleBounds(ntri, tris, &bounds);
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+
+ xDst = tris[0].p1.x >> 16;
+ yDst = tris[0].p1.y >> 16;
+
+ pPicture = exaCreateAlphaPicture(pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture(op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+ FreePicture(pPicture, 0);
+ }
+ else {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat(pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat(pScreen, 8, PICT_a8);
+
+ for (; ntri; ntri--, tris++)
+ exaTriangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
}
}
diff --git a/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c
index 219f903b2..571613886 100644
--- a/xorg-server/exa/exa_unaccel.c
+++ b/xorg-server/exa/exa_unaccel.c
@@ -45,7 +45,7 @@ exaPrepareAccessGC(GCPtr pGC)
if (pGC->stipple)
exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
if (pGC->fillStyle == FillTiled)
- exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
}
/**
@@ -55,7 +55,7 @@ void
exaFinishAccessGC(GCPtr pGC)
{
if (pGC->fillStyle == FillTiled)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
if (pGC->stipple)
exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
}
@@ -66,304 +66,303 @@ exaDrawableLocation(DrawablePtr pDrawable)
{
return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
}
-#endif /* DEBUG_TRACE_FALL */
+#endif /* DEBUG_TRACE_FALL */
void
-ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
- DDXPointPtr ppt, int *pwidth, int fSorted)
+ExaCheckFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->FillSpans(pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
- DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+ExaCheckSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->SetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
- int x, int y, int w, int h, int leftPad, int format,
- char *bits)
+ExaCheckPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits)
{
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
ExaPixmapPriv(pPixmap);
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
- exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClipType))
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType))
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
else
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
- DamagePendingRegion(pExaPixmap->pDamage));
- pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+ DamagePendingRegion(pExaPixmap->pDamage));
+ pGC->ops->PutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ bits);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
- Bool upsidedown, Pixel bitplane, void *closure)
+ExaCheckCopyNtoN(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure)
{
RegionRec reg;
int xoff, yoff;
+
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
if (pExaScr->prepare_access_reg && RegionInitBoxes(&reg, pbox, nbox)) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
- exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
- RegionTranslate(&reg, xoff + dx, yoff + dy);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
- RegionUninit(&reg);
- } else
- exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ RegionTranslate(&reg, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
+ RegionUninit(&reg);
+ }
+ else
+ exaPrepareAccess(pSrc, EXA_PREPARE_SRC);
if (pExaScr->prepare_access_reg &&
- !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
- pGC->alu, pGC->clientClipType) &&
- RegionInitBoxes (&reg, pbox, nbox)) {
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
-
- exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
- RegionTranslate(&reg, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
- RegionUninit(&reg);
- } else
- exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+ !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType) &&
+ RegionInitBoxes(&reg, pbox, nbox)) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+ exaGetDrawableDeltas(pDst, pPixmap, &xoff, &yoff);
+ RegionTranslate(&reg, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
+ RegionUninit(&reg);
+ }
+ else
+ exaPrepareAccess(pDst, EXA_PREPARE_DEST);
/* This will eventually call fbCopyNtoN, with some calculation overhead. */
while (nbox--) {
- pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
- pbox++;
+ pGC->ops->CopyArea(pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx,
+ pbox->y1 - pSrc->y + dy, pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1, pbox->x1 - pDst->x,
+ pbox->y1 - pDst->y);
+ pbox++;
}
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ exaFinishAccess(pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess(pDst, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
static void
ExaFallbackPrepareReg(DrawablePtr pDrawable,
- GCPtr pGC,
- int x, int y, int width, int height,
- int index, Bool checkReads)
+ GCPtr pGC,
+ int x, int y, int width, int height,
+ int index, Bool checkReads)
{
ScreenPtr pScreen = pDrawable->pScreen;
+
ExaScreenPriv(pScreen);
if (pExaScr->prepare_access_reg &&
- !(checkReads && exaGCReadsDestination(pDrawable,
- pGC->planemask,
- pGC->fillStyle,
- pGC->alu,
- pGC->clientClipType))) {
- BoxRec box;
- RegionRec reg;
- int xoff, yoff;
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
-
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
- box.x1 = pDrawable->x + x + xoff;
- box.y1 = pDrawable->y + y + yoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- RegionInit(&reg, &box, 1);
- pExaScr->prepare_access_reg(pPixmap, index, &reg);
- RegionUninit(&reg);
- } else
- exaPrepareAccess(pDrawable, index);
+ !(checkReads && exaGCReadsDestination(pDrawable,
+ pGC->planemask,
+ pGC->fillStyle,
+ pGC->alu, pGC->clientClipType))) {
+ BoxRec box;
+ RegionRec reg;
+ int xoff, yoff;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ box.x1 = pDrawable->x + x + xoff;
+ box.y1 = pDrawable->y + y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ RegionInit(&reg, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, &reg);
+ RegionUninit(&reg);
+ }
+ else
+ exaPrepareAccess(pDrawable, index);
}
-
RegionPtr
-ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty)
+ExaCheckCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
{
RegionPtr ret;
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
- EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
- EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyArea(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ exaFinishAccess(pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess(pDst, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
return ret;
}
RegionPtr
-ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int w, int h, int dstx, int dsty,
- unsigned long bitPlane)
+ExaCheckCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane)
{
RegionPtr ret;
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
- exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
- EXA_PREPARE_SRC, FALSE);
- ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
- EXA_PREPARE_DEST, TRUE);
- ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
- bitPlane);
- exaFinishAccess (pSrc, EXA_PREPARE_SRC);
- exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyPlane(pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+ bitPlane);
+ exaFinishAccess(pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess(pDst, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
return ret;
}
void
-ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
- DDXPointPtr pptInit)
+ExaCheckPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->PolyPoint(pDrawable, pGC, mode, npt, pptInit);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
- int mode, int npt, DDXPointPtr ppt)
+ExaCheckPolylines(DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
- pDrawable, exaDrawableLocation(pDrawable),
- pGC->lineWidth, mode, npt));
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ pDrawable, exaDrawableLocation(pDrawable),
+ pGC->lineWidth, mode, npt));
+
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->Polylines(pDrawable, pGC, mode, npt, ppt);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
- int nsegInit, xSegment *pSegInit)
+ExaCheckPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment * pSegInit)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
+ exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->PolySegment(pDrawable, pGC, nsegInit, pSegInit);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
- int narcs, xArc *pArcs)
+ExaCheckPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * pArcs)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->PolyArc(pDrawable, pGC, narcs, pArcs);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
- int nrect, xRectangle *prect)
+ExaCheckPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->PolyFillRect(pDrawable, pGC, nrect, prect);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
+ExaCheckImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr * ppci, pointer pglyphBase)
{
EXA_PRE_FALLBACK_GC(pGC);
- EXA_FALLBACK(("to %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->ImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
+ExaCheckPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr * ppci, pointer pglyphBase)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
- exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->PolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
void
-ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
- DrawablePtr pDrawable,
- int w, int h, int x, int y)
+ExaCheckPushPixels(GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable, int w, int h, int x, int y)
{
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
- exaDrawableLocation(&pBitmap->drawable),
- exaDrawableLocation(pDrawable)));
- ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
- EXA_PREPARE_DEST, TRUE);
+ exaDrawableLocation(&pBitmap->drawable),
+ exaDrawableLocation(pDrawable)));
+ ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, EXA_PREPARE_DEST, TRUE);
ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
- EXA_PREPARE_SRC, FALSE);
- exaPrepareAccessGC (pGC);
- pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
- exaFinishAccessGC (pGC);
- exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_PREPARE_SRC, FALSE);
+ exaPrepareAccessGC(pGC);
+ pGC->ops->PushPixels(pGC, pBitmap, pDrawable, w, h, x, y);
+ exaFinishAccessGC(pGC);
+ exaFinishAccess(&pBitmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK_GC(pGC);
}
@@ -372,77 +371,72 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
DrawablePtr pDrawable = &pWin->drawable;
ScreenPtr pScreen = pDrawable->pScreen;
+
EXA_PRE_FALLBACK(pScreen);
EXA_FALLBACK(("from %p\n", pWin));
/* Only need the source bits, the destination region will be overwritten */
if (pExaScr->prepare_access_reg) {
- PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
- int xoff, yoff;
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ int xoff, yoff;
- exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
- RegionTranslate(prgnSrc, xoff, yoff);
- pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
- RegionTranslate(prgnSrc, -xoff, -yoff);
- } else
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+ exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+ RegionTranslate(prgnSrc, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+ RegionTranslate(prgnSrc, -xoff, -yoff);
+ }
+ else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
swap(pExaScr, pScreen, CopyWindow);
- pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
+ pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
swap(pExaScr, pScreen, CopyWindow);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
EXA_POST_FALLBACK(pScreen);
}
void
ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask, char *d)
+ unsigned int format, unsigned long planeMask, char *d)
{
ScreenPtr pScreen = pDrawable->pScreen;
+
EXA_PRE_FALLBACK(pScreen);
- EXA_FALLBACK(("from %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
- EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, EXA_PREPARE_SRC, FALSE);
swap(pExaScr, pScreen, GetImage);
- pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ pScreen->GetImage(pDrawable, x, y, w, h, format, planeMask, d);
swap(pExaScr, pScreen, GetImage);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
EXA_POST_FALLBACK(pScreen);
}
void
-ExaCheckGetSpans (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart)
+ExaCheckGetSpans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
{
ScreenPtr pScreen = pDrawable->pScreen;
EXA_PRE_FALLBACK(pScreen);
EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
swap(pExaScr, pScreen, GetSpans);
- pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ pScreen->GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
swap(pExaScr, pScreen, GetSpans);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess(pDrawable, EXA_PREPARE_SRC);
EXA_POST_FALLBACK(pScreen);
}
static void
ExaSrcValidate(DrawablePtr pDrawable,
- int x,
- int y,
- int width,
- int height,
- unsigned int subWindowMode)
+ int x, int y, int width, int height, unsigned int subWindowMode)
{
ScreenPtr pScreen = pDrawable->pScreen;
+
ExaScreenPriv(pScreen);
- PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
BoxRec box;
RegionRec reg;
RegionPtr dst;
@@ -455,8 +449,7 @@ ExaSrcValidate(DrawablePtr pDrawable,
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
- dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
- &pExaScr->maskReg;
+ dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg : &pExaScr->maskReg;
RegionInit(&reg, &box, 1);
RegionUnion(dst, dst, &reg);
@@ -470,19 +463,16 @@ ExaSrcValidate(DrawablePtr pDrawable,
}
static Bool
-ExaPrepareCompositeReg(ScreenPtr pScreen,
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+ExaPrepareCompositeReg(ScreenPtr pScreen,
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
RegionRec region;
RegionPtr dstReg = NULL;
@@ -491,65 +481,57 @@ ExaPrepareCompositeReg(ScreenPtr pScreen,
PixmapPtr pSrcPix = NULL;
PixmapPtr pMaskPix = NULL;
PixmapPtr pDstPix;
+
ExaScreenPriv(pScreen);
Bool ret;
-
RegionNull(&region);
if (pSrc->pDrawable) {
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
- RegionNull(&pExaScr->srcReg);
- srcReg = &pExaScr->srcReg;
- pExaScr->srcPix = pSrcPix;
- if (pSrc != pDst)
- RegionTranslate(pSrc->pCompositeClip,
- -pSrc->pDrawable->x,
- -pSrc->pDrawable->y);
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ RegionNull(&pExaScr->srcReg);
+ srcReg = &pExaScr->srcReg;
+ pExaScr->srcPix = pSrcPix;
+ if (pSrc != pDst)
+ RegionTranslate(pSrc->pCompositeClip,
+ -pSrc->pDrawable->x, -pSrc->pDrawable->y);
}
if (pMask && pMask->pDrawable) {
- pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
- RegionNull(&pExaScr->maskReg);
- maskReg = &pExaScr->maskReg;
- if (pMask != pDst && pMask != pSrc)
- RegionTranslate(pMask->pCompositeClip,
- -pMask->pDrawable->x,
- -pMask->pDrawable->y);
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ RegionNull(&pExaScr->maskReg);
+ maskReg = &pExaScr->maskReg;
+ if (pMask != pDst && pMask != pSrc)
+ RegionTranslate(pMask->pCompositeClip,
+ -pMask->pDrawable->x, -pMask->pDrawable->y);
}
RegionTranslate(pDst->pCompositeClip,
- -pDst->pDrawable->x,
- -pDst->pDrawable->y);
+ -pDst->pDrawable->x, -pDst->pDrawable->y);
pExaScr->SavedSourceValidate = ExaSrcValidate;
swap(pExaScr, pScreen, SourceValidate);
- ret = miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask,
- xDst,
- yDst,
- width, height);
+ ret = miComputeCompositeRegion(&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
swap(pExaScr, pScreen, SourceValidate);
RegionTranslate(pDst->pCompositeClip,
- pDst->pDrawable->x,
- pDst->pDrawable->y);
+ pDst->pDrawable->x, pDst->pDrawable->y);
if (pSrc->pDrawable && pSrc != pDst)
- RegionTranslate(pSrc->pCompositeClip,
- pSrc->pDrawable->x,
- pSrc->pDrawable->y);
+ RegionTranslate(pSrc->pCompositeClip,
+ pSrc->pDrawable->x, pSrc->pDrawable->y);
if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
- RegionTranslate(pMask->pCompositeClip,
- pMask->pDrawable->x,
- pMask->pDrawable->y);
+ RegionTranslate(pMask->pCompositeClip,
+ pMask->pDrawable->x, pMask->pDrawable->y);
if (!ret) {
- if (srcReg)
- RegionUninit(srcReg);
- if (maskReg)
- RegionUninit(maskReg);
+ if (srcReg)
+ RegionUninit(srcReg);
+ if (maskReg)
+ RegionUninit(maskReg);
- return FALSE;
+ return FALSE;
}
/**
@@ -558,44 +540,40 @@ ExaPrepareCompositeReg(ScreenPtr pScreen,
*/
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
- EXA_PREPARE_AUX_SRC,
- NULL);
+ pExaScr->
+ prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_SRC, NULL);
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
- EXA_PREPARE_AUX_MASK,
- NULL);
+ pExaScr->
+ prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_MASK, NULL);
if (pSrcPix)
- pExaScr->prepare_access_reg(pSrcPix,
- EXA_PREPARE_SRC,
- srcReg);
+ pExaScr->prepare_access_reg(pSrcPix, EXA_PREPARE_SRC, srcReg);
if (pMaskPix)
- pExaScr->prepare_access_reg(pMaskPix,
- EXA_PREPARE_MASK,
- maskReg);
+ pExaScr->prepare_access_reg(pMaskPix, EXA_PREPARE_MASK, maskReg);
if (srcReg)
- RegionUninit(srcReg);
+ RegionUninit(srcReg);
if (maskReg)
- RegionUninit(maskReg);
+ RegionUninit(maskReg);
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
if (!exaOpReadsDestination(op)) {
- int xoff;
- int yoff;
+ int xoff;
+ int yoff;
- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
- RegionTranslate(&region, pDst->pDrawable->x + xoff,
- pDst->pDrawable->y + yoff);
- dstReg = &region;
+ exaGetDrawableDeltas(pDst->pDrawable, pDstPix, &xoff, &yoff);
+ RegionTranslate(&region, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = &region;
}
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
- EXA_PREPARE_AUX_DEST,
- dstReg);
+ pExaScr->
+ prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST, dstReg);
pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
RegionUninit(&region);
@@ -603,80 +581,70 @@ ExaPrepareCompositeReg(ScreenPtr pScreen,
}
void
-ExaCheckComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+ExaCheckComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
EXA_PRE_FALLBACK(pScreen);
if (pExaScr->prepare_access_reg) {
- if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
- ySrc, xMask, yMask, xDst, yDst, width,
- height))
- goto out_no_clip;
- } else {
-
- /* We need to prepare access to any separate alpha maps first,
- * in case the driver doesn't support EXA_PREPARE_AUX*,
- * in which case EXA_PREPARE_SRC may be used for moving them out.
- */
-
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
-
- exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
-
- EXA_FALLBACK(("from picts %p/%p to pict %p\n",
- pSrc, pMask, pDst));
-
- if (pSrc->pDrawable != NULL)
- exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- if (pMask && pMask->pDrawable != NULL)
- exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst, width,
+ height))
+ goto out_no_clip;
+ }
+ else {
+
+ /* We need to prepare access to any separate alpha maps first,
+ * in case the driver doesn't support EXA_PREPARE_AUX*,
+ * in which case EXA_PREPARE_SRC may be used for moving them out.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+
+ exaPrepareAccess(pDst->pDrawable, EXA_PREPARE_DEST);
+
+ EXA_FALLBACK(("from picts %p/%p to pict %p\n", pSrc, pMask, pDst));
+
+ if (pSrc->pDrawable != NULL)
+ exaPrepareAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pMask && pMask->pDrawable != NULL)
+ exaPrepareAccess(pMask->pDrawable, EXA_PREPARE_MASK);
}
swap(pExaScr, ps, Composite);
- ps->Composite (op,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height);
+ ps->Composite(op,
+ pSrc,
+ pMask,
+ pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height);
swap(pExaScr, ps, Composite);
if (pMask && pMask->pDrawable != NULL)
- exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ exaFinishAccess(pMask->pDrawable, EXA_PREPARE_MASK);
if (pSrc->pDrawable != NULL)
- exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+ exaFinishAccess(pSrc->pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess(pDst->pDrawable, EXA_PREPARE_DEST);
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+ exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+ exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
-out_no_clip:
+ out_no_clip:
EXA_POST_FALLBACK(pScreen);
}
@@ -684,17 +652,15 @@ out_no_clip:
* Avoid migration ping-pong when using a mask.
*/
void
-ExaCheckGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
+ExaCheckGlyphs(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
+
EXA_PRE_FALLBACK(pScreen);
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
@@ -703,21 +669,19 @@ ExaCheckGlyphs (CARD8 op,
}
void
-ExaCheckAddTraps (PicturePtr pPicture,
- INT16 x_off,
- INT16 y_off,
- int ntrap,
- xTrap *traps)
+ExaCheckAddTraps(PicturePtr pPicture,
+ INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
{
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
EXA_PRE_FALLBACK(pScreen);
EXA_FALLBACK(("to pict %p (%c)\n",
- exaDrawableLocation(pPicture->pDrawable)));
+ exaDrawableLocation(pPicture->pDrawable)));
exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
swap(pExaScr, ps, AddTraps);
- ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
+ ps->AddTraps(pPicture, x_off, y_off, ntrap, traps);
swap(pExaScr, ps, AddTraps);
exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
EXA_POST_FALLBACK(pScreen);
@@ -728,37 +692,37 @@ ExaCheckAddTraps (PicturePtr pPicture,
* that happen to be 1x1. Pixmap must be at least 8bpp.
*/
CARD32
-exaGetPixmapFirstPixel (PixmapPtr pPixmap)
+exaGetPixmapFirstPixel(PixmapPtr pPixmap)
{
switch (pPixmap->drawable.bitsPerPixel) {
case 32:
- {
- CARD32 pixel;
+ {
+ CARD32 pixel;
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char *) &pixel);
+ return pixel;
+ }
case 16:
- {
- CARD16 pixel;
+ {
+ CARD16 pixel;
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char *) &pixel);
+ return pixel;
+ }
case 8:
case 4:
case 1:
- {
- CARD8 pixel;
+ {
+ CARD8 pixel;
- pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
- ZPixmap, ~0, (char*)&pixel);
- return pixel;
- }
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char *) &pixel);
+ return pixel;
+ }
default:
- FatalError("%s called for invalid bpp %d\n", __func__,
- pPixmap->drawable.bitsPerPixel);
+ FatalError("%s called for invalid bpp %d\n", __func__,
+ pPixmap->drawable.bitsPerPixel);
}
}