summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2007-09-26 07:47:29 -0400
committerEamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil>2007-09-26 07:47:29 -0400
commit27612748e0ec20f3a23839f0a12e39f598dd722c (patch)
treef7780ffd4d1284e76a17166f28211cfb88796de7 /exa
parentb61461425eb15fcff2a58330d74fe5a5a1f226fc (diff)
parent3b114f2603fc2adeec7f5f8f20fe4870afb8dff1 (diff)
Merge branch 'master' into XACE-SELINUX
Conflicts: dix/devices.c
Diffstat (limited to 'exa')
-rw-r--r--exa/exa.c67
-rw-r--r--exa/exa.h33
-rw-r--r--exa/exa_accel.c45
-rw-r--r--exa/exa_priv.h15
-rw-r--r--exa/exa_render.c29
5 files changed, 146 insertions, 43 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 8f219fbdf..56996c436 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -277,6 +277,26 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
REGION_NULL(pScreen, &pExaPixmap->validSys);
REGION_NULL(pScreen, &pExaPixmap->validFB);
+ /* Check whether this pixmap can be used for acceleration. */
+ pExaPixmap->accel_blocked = 0;
+
+ if (pExaScr->info->maxPitchPixels) {
+ int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8;
+
+ if (pExaPixmap->fb_pitch > max_pitch)
+ pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
+ }
+
+ if (pExaScr->info->maxPitchBytes &&
+ pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes)
+ pExaPixmap->accel_blocked |= EXA_RANGE_PITCH;
+
+ if (w > pExaScr->info->maxX)
+ pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH;
+
+ if (h > pExaScr->info->maxY)
+ pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT;
+
return pPixmap;
}
@@ -659,6 +679,17 @@ exaDriverInit (ScreenPtr pScreen,
if (!pScreenInfo)
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;
+ }
+
if (!pScreenInfo->memoryBase) {
LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be "
"non-zero\n", pScreen->myNum);
@@ -695,14 +726,36 @@ exaDriverInit (ScreenPtr pScreen,
return FALSE;
}
- if (pScreenInfo->exa_major != EXA_VERSION_MAJOR ||
- pScreenInfo->exa_minor > EXA_VERSION_MINOR)
+ /* If the driver doesn't set any max pitch values, we'll just assume
+ * that there's a limitation by pixels, and that it's the same as
+ * maxX.
+ */
+ if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
{
- 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);
+ pScreenInfo->maxPitchPixels = pScreenInfo->maxX;
+ }
+
+ /* If set, maxPitchPixels must not be smaller than maxX. */
+ if (pScreenInfo->maxPitchPixels &&
+ pScreenInfo->maxPitchPixels < pScreenInfo->maxX)
+ {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchPixels "
+ "is smaller than ExaDriverRec::maxX\n",
+ pScreen->myNum);
+ return FALSE;
+ }
+
+ /* If set, maxPitchBytes must not be smaller than maxX * 4.
+ * This is to ensure that a 32bpp pixmap with the maximum width
+ * can be handled wrt the pitch.
+ */
+ if (pScreenInfo->maxPitchBytes &&
+ pScreenInfo->maxPitchBytes < (pScreenInfo->maxX * 4))
+ {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::maxPitchBytes "
+ "doesn't allow a 32bpp pixmap with width equal to "
+ "ExaDriverRec::maxX\n",
+ pScreen->myNum);
return FALSE;
}
diff --git a/exa/exa.h b/exa/exa.h
index 9ea593381..491e6b16b 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -39,7 +39,7 @@
#include "fb.h"
#define EXA_VERSION_MAJOR 2
-#define EXA_VERSION_MINOR 2
+#define EXA_VERSION_MINOR 3
#define EXA_VERSION_RELEASE 0
typedef struct _ExaOffscreenArea ExaOffscreenArea;
@@ -671,6 +671,37 @@ typedef struct _ExaDriver {
*/
#define EXA_PREPARE_MASK 2
/** @} */
+
+ /**
+ * 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;
+
/** @} */
} ExaDriverRec, *ExaDriverPtr;
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 2acade263..028d93644 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -43,7 +43,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap;
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv (pPixmap);
BoxPtr pextent, pbox;
int nbox;
int extentX1, extentX2, extentY1, extentY2;
@@ -54,13 +55,12 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pPix = pPixmap;
pixmaps[0].pReg = NULL;
if (pExaScr->swappedOut ||
pGC->fillStyle != FillSolid ||
- pPixmap->drawable.width > pExaScr->info->maxX ||
- pPixmap->drawable.height > pExaScr->info->maxY)
+ pExaPixmap->accel_blocked)
{
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return;
@@ -480,6 +480,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
{
ExaScreenPriv (pDstDrawable->pScreen);
PixmapPtr pSrcPixmap, pDstPixmap;
+ ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
int src_off_x, src_off_y;
int dst_off_x, dst_off_y;
ExaMigrationRec pixmaps[2];
@@ -527,14 +528,14 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
pixmaps[1].pPix = pSrcPixmap;
pixmaps[1].pReg = NULL;
- /* Respect maxX/maxY in a trivial way: don't set up drawing when we might
- * violate the limits. The proper solution would be a temporary pixmap
- * adjusted so that the drawing happened within limits.
+ pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
+ pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
+
+ /* Check whether the accelerator can use this pixmap.
+ * FIXME: If it cannot, use temporary pixmaps so that the drawing
+ * happens within limits.
*/
- if (pSrcPixmap->drawable.width > pExaScr->info->maxX ||
- pSrcPixmap->drawable.height > pExaScr->info->maxY ||
- pDstPixmap->drawable.width > pExaScr->info->maxX ||
- pDstPixmap->drawable.height > pExaScr->info->maxY)
+ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked)
{
goto fallback;
} else {
@@ -760,6 +761,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
ExaScreenPriv (pDrawable->pScreen);
RegionPtr pClip = fbGetCompositeClip(pGC);
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv (pPixmap);
register BoxPtr pbox;
BoxPtr pextent;
int extentX1, extentX2, extentY1, extentY2;
@@ -786,9 +788,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
- if (pExaScr->swappedOut ||
- pPixmap->drawable.width > pExaScr->info->maxX ||
- pPixmap->drawable.height > pExaScr->info->maxY)
+ if (pExaScr->swappedOut || pExaPixmap->accel_blocked)
{
goto fallback;
}
@@ -1102,21 +1102,21 @@ exaFillRegionSolid (DrawablePtr pDrawable,
CARD32 alu)
{
ExaScreenPriv(pDrawable->pScreen);
- PixmapPtr pPixmap;
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv (pPixmap);
int xoff, yoff;
ExaMigrationRec pixmaps[1];
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pPix = pPixmap;
pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
alu) ? NULL : pRegion;
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
- if (pPixmap->drawable.width > pExaScr->info->maxX ||
- pPixmap->drawable.height > pExaScr->info->maxY)
+ if (pExaPixmap->accel_blocked)
{
goto fallback;
} else {
@@ -1193,6 +1193,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
{
ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap;
+ ExaPixmapPrivPtr pExaPixmap;
+ ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
int xoff, yoff, tileXoff, tileYoff;
int tileWidth, tileHeight;
ExaMigrationRec pixmaps[2];
@@ -1223,10 +1225,9 @@ exaFillRegionTiled (DrawablePtr pDrawable,
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
- if (pPixmap->drawable.width > pExaScr->info->maxX ||
- pPixmap->drawable.height > pExaScr->info->maxY ||
- tileWidth > pExaScr->info->maxX ||
- tileHeight > pExaScr->info->maxY)
+ pExaPixmap = ExaGetPixmapPriv (pPixmap);
+
+ if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked)
{
goto fallback;
} else {
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 27749d7c4..b1023a67e 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -154,6 +154,10 @@ extern DevPrivateKey exaPixmapPrivateKey;
#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a)
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
+#define EXA_RANGE_PITCH (1 << 0)
+#define EXA_RANGE_WIDTH (1 << 1)
+#define EXA_RANGE_HEIGHT (1 << 2)
+
typedef struct {
ExaOffscreenArea *area;
int score; /**< score for the move-in vs move-out heuristic */
@@ -167,6 +171,17 @@ typedef struct {
unsigned int fb_size; /**< size of pixmap in framebuffer memory */
/**
+ * Holds information about whether this pixmap can be used for
+ * acceleration (== 0) or not (> 0).
+ *
+ * Contains a OR'ed combination of the following values:
+ * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range
+ * 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;
+
+ /**
* The damage record contains the areas of the pixmap's current location
* (framebuffer or system) that have been damaged compared to the other
* location.
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 943a4c8f6..2ad53041a 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -336,24 +336,28 @@ exaTryDriverComposite(CARD8 op,
int nbox;
int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
+ ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
struct _Pixmap scratch;
ExaMigrationRec pixmaps[3];
pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+
pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- if (pMask)
+ pDstExaPix = ExaGetPixmapPriv(pDstPix);
+
+ if (pMask) {
pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
+ }
- /* Bail if we might exceed coord limits by rendering from/to these. We
- * should really be making some scratch pixmaps with offsets and coords
- * adjusted to deal with this, but it hasn't been done yet.
+ /* Check whether the accelerator can use these pixmaps.
+ * FIXME: If it cannot, use temporary pixmaps so that the drawing
+ * happens within limits.
*/
- if (pSrcPix->drawable.width > pExaScr->info->maxX ||
- pSrcPix->drawable.height > pExaScr->info->maxY ||
- pDstPix->drawable.width > pExaScr->info->maxX ||
- pDstPix->drawable.height > pExaScr->info->maxY ||
- (pMask && (pMaskPix->drawable.width > pExaScr->info->maxX ||
- pMaskPix->drawable.height > pExaScr->info->maxY)))
+ if (pSrcExaPix->accel_blocked ||
+ pDstExaPix->accel_blocked ||
+ (pMask && (pMaskExaPix->accel_blocked)))
{
return -1;
}
@@ -380,7 +384,6 @@ exaTryDriverComposite(CARD8 op,
width, height))
return 1;
- pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
@@ -391,12 +394,12 @@ exaTryDriverComposite(CARD8 op,
pixmaps[0].pReg = pixmaps[0].as_src ? NULL : &region;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
+ pixmaps[1].pPix = pSrcPix;
pixmaps[1].pReg = NULL;
if (pMask) {
pixmaps[2].as_dst = FALSE;
pixmaps[2].as_src = TRUE;
- pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
+ pixmaps[2].pPix = pMaskPix;
pixmaps[2].pReg = NULL;
exaDoMigration(pixmaps, 3, TRUE);
} else {