summaryrefslogtreecommitdiff
path: root/exa/exa.c
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2007-10-17 15:00:54 -0400
committerEamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil>2007-10-17 15:00:54 -0400
commitc3f7b862550fa8f46633162f83db8c27e46fc672 (patch)
treea8427c93c96af2bbf2133b07f2510ff31560e54d /exa/exa.c
parentaf4dde0ac19ecec1d0ad988eb25b15401e7c6b36 (diff)
parentfeac0759522cbdc3e61ccfa373df735903c5cb27 (diff)
Merge branch 'master' into XACE-SELINUX
Conflicts: os/access.c
Diffstat (limited to 'exa/exa.c')
-rw-r--r--exa/exa.c218
1 files changed, 136 insertions, 82 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 56996c436..3f724e64e 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -73,6 +73,14 @@ exaGetPixmapOffset(PixmapPtr pPix)
(unsigned long)pExaScr->info->memoryBase);
}
+void *
+exaGetPixmapDriverPrivate(PixmapPtr pPix)
+{
+ ExaPixmapPriv(pPix);
+
+ return pExaPixmap->driverPriv;
+}
+
/**
* exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
*
@@ -174,9 +182,18 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
static Bool
exaDestroyPixmap (PixmapPtr pPixmap)
{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ExaScreenPriv(pScreen);
+
if (pPixmap->refcnt == 1)
{
ExaPixmapPriv (pPixmap);
+
+ if (pExaPixmap->driverPriv) {
+ pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv);
+ pExaPixmap->driverPriv = NULL;
+ }
+
if (pExaPixmap->area)
{
DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n",
@@ -220,46 +237,87 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
PixmapPtr pPixmap;
ExaPixmapPrivPtr pExaPixmap;
+ int driver_alloc = 0;
int bpp;
ExaScreenPriv(pScreen);
if (w > 32767 || h > 32767)
return NullPixmap;
- pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+ if (!pExaScr->info->CreatePixmap) {
+ pPixmap = fbCreatePixmap (pScreen, w, h, depth);
+ } else {
+ driver_alloc = 1;
+ pPixmap = fbCreatePixmap(pScreen, 0, 0, depth);
+ }
+
if (!pPixmap)
- return NULL;
+ return NULL;
+
pExaPixmap = ExaGetPixmapPriv(pPixmap);
bpp = pPixmap->drawable.bitsPerPixel;
- /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
- if (!w || !h)
- pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
- else
- pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
-
- pExaPixmap->area = NULL;
-
- pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
- pExaPixmap->sys_pitch = pPixmap->devKind;
-
- pPixmap->devPrivate.ptr = NULL;
- pExaPixmap->offscreen = FALSE;
-
- pExaPixmap->fb_ptr = NULL;
- if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
- pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
- else
- pExaPixmap->fb_pitch = w * bpp / 8;
- pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
- pExaScr->info->pixmapPitchAlign);
- pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+ if (driver_alloc) {
+ size_t paddedWidth, datasize;
+ void *driver_priv;
+
+ paddedWidth = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ if (paddedWidth / 4 > 32767 || h > 32767)
+ return NullPixmap;
+
+ if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+ pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+ else
+ pExaPixmap->fb_pitch = w * bpp / 8;
+ pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+ pExaScr->info->pixmapPitchAlign);
+ if (paddedWidth < pExaPixmap->fb_pitch)
+ paddedWidth = pExaPixmap->fb_pitch;
+
+ datasize = h * paddedWidth;
+
+ driver_priv = pExaScr->info->CreatePixmap(pScreen, datasize, 0);
+ if (!driver_priv) {
+ fbDestroyPixmap(pPixmap);
+ return NULL;
+ }
- if (pExaPixmap->fb_pitch > 131071) {
- fbDestroyPixmap(pPixmap);
- return NULL;
+ (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0,
+ paddedWidth, NULL);
+ pExaPixmap->driverPriv = driver_priv;
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ pExaPixmap->fb_ptr = NULL;
+ } else {
+ pExaPixmap->driverPriv = NULL;
+ /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
+ if (!w || !h)
+ pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
+ else
+ pExaPixmap->score = EXA_PIXMAP_SCORE_INIT;
+
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
+
+ pPixmap->devPrivate.ptr = NULL;
+ pExaPixmap->offscreen = FALSE;
+
+ pExaPixmap->fb_ptr = NULL;
+ if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
+ pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
+ else
+ pExaPixmap->fb_pitch = w * bpp / 8;
+ pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch,
+ pExaScr->info->pixmapPitchAlign);
+ pExaPixmap->fb_size = pExaPixmap->fb_pitch * h;
+
+ if (pExaPixmap->fb_pitch > 131071) {
+ fbDestroyPixmap(pPixmap);
+ return NULL;
+ }
}
+
+ pExaPixmap->area = NULL;
/* Set up damage tracking */
pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE,
@@ -306,6 +364,7 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
{
ExaScreenPrivPtr pExaScr;
ExaPixmapPrivPtr pExaPixmap;
+ Bool ret;
if (!pPixmap)
return FALSE;
@@ -317,6 +376,12 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
+ if (pExaScr->info->ModifyPixmapHeader) {
+ ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData);
+ if (ret == TRUE)
+ return ret;
+ }
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData);
}
@@ -344,7 +409,7 @@ exaPixmapIsOffscreen(PixmapPtr p)
save_ptr = p->devPrivate.ptr;
- if (!save_ptr && pExaPixmap)
+ if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
p->devPrivate.ptr = ExaGetPixmapAddress(p);
if (pExaScr->info->PixmapIsOffscreen)
@@ -394,7 +459,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
/* Unhide pixmap pointer */
- if (pPixmap->devPrivate.ptr == NULL) {
+ if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
}
@@ -455,8 +520,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
ExaPixmapPriv (pPixmap);
/* Rehide pixmap pointer if we're doing that. */
- if (pExaPixmap)
- {
+ if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
pPixmap->devPrivate.ptr = NULL;
}
@@ -690,22 +754,24 @@ exaDriverInit (ScreenPtr pScreen,
return FALSE;
}
- if (!pScreenInfo->memoryBase) {
- LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be "
- "non-zero\n", pScreen->myNum);
- return FALSE;
- }
+ if (!pScreenInfo->CreatePixmap) {
+ 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->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->offScreenBase > pScreenInfo->memorySize) {
+ LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must "
+ "be <= ExaDriverRec::memorySize\n", pScreen->myNum);
+ return FALSE;
+ }
}
if (!pScreenInfo->PrepareSolid) {
@@ -729,36 +795,17 @@ exaDriverInit (ScreenPtr pScreen,
/* 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.
+ *
+ * We want maxPitchPixels or maxPitchBytes to be set so we can check
+ * pixmaps against the max pitch in exaCreatePixmap() -- it matters
+ * whether a pixmap is rejected because of its pitch or
+ * because of its width.
*/
if (!pScreenInfo->maxPitchPixels && !pScreenInfo->maxPitchBytes)
{
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;
- }
-
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
#endif
@@ -829,8 +876,7 @@ exaDriverInit (ScreenPtr pScreen,
/*
* Hookup offscreen pixmaps
*/
- if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- pExaScr->info->offScreenBase < pExaScr->info->memorySize)
+ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
{
if (!dixRequestPrivate(exaPixmapPrivateKey, sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
@@ -846,21 +892,29 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
- LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
- pScreen->myNum,
- pExaScr->info->memorySize - pExaScr->info->offScreenBase);
+ if (!pExaScr->info->CreatePixmap) {
+ 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);
- 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 (!pExaScr->info->CreatePixmap) {
+ 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;
+ }
+ }
}
LogMessage(X_INFO, "EXA(%d): Driver registered support for the following"