summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2007-10-25 12:19:30 -0400
committerEamon Walsh <ewalsh@moss-charon.epoch.ncsc.mil>2007-10-25 12:19:30 -0400
commitb633d54b94d746d26e13014634d9f63bbb7e8f7d (patch)
tree4832d035672164284ff8698d5875e9d5435f494a /exa
parent4b05f19cb9e42d8c8eff5ca4e463f5bc2a05433d (diff)
parent48ca5961caee62f2980017a6bdc96a1b4c747727 (diff)
Merge branch 'master' into XACE-SELINUX
Conflicts: GL/glx/glxscreens.c hw/xnest/Screen.c render/glyph.c render/glyphstr.h render/render.c
Diffstat (limited to 'exa')
-rw-r--r--exa/exa.c8
-rw-r--r--exa/exa_accel.c5
-rw-r--r--exa/exa_migration.c3
-rw-r--r--exa/exa_priv.h1
-rw-r--r--exa/exa_render.c368
5 files changed, 25 insertions, 360 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 3f724e64e..038dbec6d 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -290,7 +290,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
pExaPixmap->fb_ptr = NULL;
} else {
pExaPixmap->driverPriv = NULL;
- /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */
+ /* Scratch pixmaps may have w/h equal to zero, and may not be
+ * migrated.
+ */
if (!w || !h)
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
else
@@ -695,7 +697,6 @@ exaCloseScreen(int i, ScreenPtr pScreen)
#ifdef RENDER
if (ps) {
ps->Composite = pExaScr->SavedComposite;
- ps->Glyphs = pExaScr->SavedGlyphs;
ps->Trapezoids = pExaScr->SavedTrapezoids;
}
#endif
@@ -858,9 +859,6 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedTriangles = ps->Triangles;
ps->Triangles = exaTriangles;
- pExaScr->SavedGlyphs = ps->Glyphs;
- ps->Glyphs = exaGlyphs;
-
pExaScr->SavedTrapezoids = ps->Trapezoids;
ps->Trapezoids = exaTrapezoids;
}
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 8bbf036e4..5fb72d71b 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -152,6 +152,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int bpp = pDrawable->bitsPerPixel;
Bool access_prepared = FALSE;
+ if (pExaPixmap->accel_blocked)
+ return FALSE;
+
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
return FALSE;
@@ -655,7 +658,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
x1 = ppt[0].x;
y1 = ppt[0].y;
/* If we have any non-horizontal/vertical, fall back. */
- for (i = 0; i < npt; i++) {
+ for (i = 0; i < npt - 1; i++) {
if (mode == CoordModePrevious) {
x2 = x1 + ppt[i + 1].x;
y2 = y1 + ppt[i + 1].y;
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 7968521c5..d69526b7f 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -299,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
if (pPixmap->drawable.bitsPerPixel < 8)
return;
+ if (pExaPixmap->accel_blocked)
+ return;
+
if (pExaPixmap->area == NULL) {
pExaPixmap->area =
exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 582ddcaa6..6439954d6 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -53,6 +53,7 @@
#include "fboverlay.h"
#ifdef RENDER
#include "fbpict.h"
+#include "glyphstr.h"
#endif
#include "damage.h"
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 2ad53041a..6a9e53f3e 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -247,10 +247,24 @@ exaTryDriverSolidFill(PicturePtr pSrc,
int nbox;
int dst_off_x, dst_off_y;
PixmapPtr pSrcPix, pDstPix;
+ ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
CARD32 pixel;
CARD16 red, green, blue, alpha;
ExaMigrationRec pixmaps[1];
+ pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
+ pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
+
+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+ pDstExaPix = ExaGetPixmapPriv(pDstPix);
+
+ /* Check whether the accelerator can use these pixmaps.
+ */
+ if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked)
+ {
+ return -1;
+ }
+
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
@@ -261,12 +275,10 @@ exaTryDriverSolidFill(PicturePtr pSrc,
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);
- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
pixel = exaGetPixmapFirstPixel (pSrcPix);
pixmaps[0].as_dst = TRUE;
@@ -985,355 +997,3 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
}
}
-
-/**
- * Returns TRUE if the glyphs in the lists intersect. Only checks based on
- * bounding box, which appears to be good enough to catch most cases at least.
- */
-static Bool
-exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
- int x1, x2, y1, y2;
- int n;
- GlyphPtr glyph;
- int x, y;
- BoxRec extents;
- Bool first = TRUE;
-
- x = 0;
- y = 0;
- while (nlist--) {
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- list++;
- while (n--) {
- glyph = *glyphs++;
-
- if (glyph->info.width == 0 || glyph->info.height == 0) {
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- continue;
- }
-
- 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 (first) {
- extents.x1 = x1;
- extents.y1 = y1;
- extents.x2 = x2;
- extents.y2 = y2;
- first = FALSE;
- } else {
- if (x1 < extents.x2 && x2 > extents.x1 &&
- y1 < extents.y2 && y2 > extents.y1)
- {
- return TRUE;
- }
-
- 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;
- }
- }
-
- return FALSE;
-}
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
-/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
- * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
- * migrate these pixmaps. So, instead we create a pixmap at the beginning of
- * the loop and upload each glyph into the pixmap before compositing.
- *
- * This is now used even when Composite can't be accelerated for better
- * migration control.
- */
-void
-exaGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- ExaScreenPriv (pDst->pDrawable->pScreen);
- PixmapPtr pPixmap = NULL;
- PicturePtr pPicture;
- PixmapPtr pMaskPixmap = NULL;
- PicturePtr pMask;
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- int width = 0, height = 0;
- int x, y, x1, y1;
- int xDst = list->xOff, yDst = list->yOff;
- int n;
- int error;
- BoxRec extents;
- CARD32 component_alpha;
-
- /* If we have a mask format but it's the same as all the glyphs and
- * the glyphs don't intersect, we can avoid accumulating the glyphs in the
- * temporary picture.
- */
- if (maskFormat != NULL) {
- Bool sameFormat = TRUE;
- int i;
-
- for (i = 0; i < nlist; i++) {
- if (maskFormat->format != list[i].format->format) {
- sameFormat = FALSE;
- break;
- }
- }
- if (sameFormat) {
- if (!exaGlyphsIntersect(nlist, list, glyphs)) {
- maskFormat = NULL;
- }
- }
- }
-
- if (maskFormat)
- {
- GCPtr pGC;
- xRectangle rect;
-
- miGlyphExtents (nlist, list, glyphs, &extents);
-
- extents.x1 = max(extents.x1, 0);
- extents.y1 = max(extents.y1, 0);
- extents.x2 = min(extents.x2, pDst->pDrawable->width);
- extents.y2 = min(extents.y2, pDst->pDrawable->height);
-
- if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
- return;
- width = extents.x2 - extents.x1;
- height = extents.y2 - extents.y1;
- pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
- maskFormat->depth);
- if (!pMaskPixmap)
- return;
- component_alpha = NeedsComponent(maskFormat->format);
- pMask = CreatePicture (0, &pMaskPixmap->drawable,
- maskFormat, CPComponentAlpha, &component_alpha,
- serverClient, &error);
- if (!pMask)
- {
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- return;
- }
- ValidatePicture(pMask);
- pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
- ValidateGC (&pMaskPixmap->drawable, pGC);
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect);
- if (pExaScr->info->PrepareComposite)
- (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
- else
- exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
- FreeScratchGC (pGC);
- x = -extents.x1;
- y = -extents.y1;
- }
- else
- {
- pMask = pDst;
- x = 0;
- y = 0;
- }
-
- while (nlist--)
- {
- GCPtr pGC = NULL;
- int maxwidth = 0, maxheight = 0, i;
- ExaMigrationRec pixmaps[1];
- PixmapPtr pScratchPixmap = NULL;
-
- x += list->xOff;
- y += list->yOff;
- n = list->len;
- for (i = 0; i < n; i++) {
- if (glyphs[i]->info.width > maxwidth)
- maxwidth = glyphs[i]->info.width;
- if (glyphs[i]->info.height > maxheight)
- maxheight = glyphs[i]->info.height;
- }
- if (maxwidth == 0 || maxheight == 0) {
- while (n--)
- {
- GlyphPtr glyph;
-
- glyph = *glyphs++;
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- continue;
- }
-
- /* Create the (real) temporary pixmap to store the current glyph in */
- pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight,
- list->format->depth);
- if (!pPixmap)
- return;
-
- /* Create a temporary picture to wrap the temporary pixmap, so it can be
- * used as a source for Composite.
- */
- component_alpha = NeedsComponent(list->format->format);
- pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
- CPComponentAlpha, &component_alpha,
- serverClient, &error);
- if (!pPicture) {
- (*pScreen->DestroyPixmap) (pPixmap);
- return;
- }
- ValidatePicture(pPicture);
-
- /* Give the temporary pixmap an initial kick towards the screen, so
- * it'll stick there.
- */
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
- exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
-
- while (n--)
- {
- GlyphPtr glyph = *glyphs++;
- pointer glyphdata = (pointer) (glyph + 1);
- DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
-
- x1 = x - glyph->info.x;
- y1 = y - glyph->info.y;
-
- if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
- (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
- goto nextglyph;
-
- (*pScreen->ModifyPixmapHeader) (pScratchPixmap,
- glyph->info.width,
- glyph->info.height,
- 0, 0, -1, glyphdata);
-
- /* Copy the glyph data into the proper pixmap instead of a fake.
- * First we try to use UploadToScreen, if we can, then we fall back
- * to a plain exaCopyArea in case of failure.
- */
- if (pExaScr->info->UploadToScreen &&
- exaPixmapIsOffscreen(pPixmap) &&
- (*pExaScr->info->UploadToScreen) (pPixmap, 0, 0,
- glyph->info.width,
- glyph->info.height,
- glyphdata,
- PixmapBytePad(glyph->info.width,
- list->format->depth)))
- {
- exaMarkSync (pScreen);
- } else {
- /* Set up the scratch pixmap/GC for doing a CopyArea. */
- if (pScratchPixmap == NULL) {
- /* Get a scratch pixmap to wrap the original glyph data */
- pScratchPixmap = GetScratchPixmapHeader (pScreen,
- glyph->info.width,
- glyph->info.height,
- list->format->depth,
- list->format->depth,
- -1, glyphdata);
- if (!pScratchPixmap) {
- FreePicture(pPicture, 0);
- (*pScreen->DestroyPixmap) (pPixmap);
- return;
- }
-
- /* Get a scratch GC with which to copy the glyph data from
- * scratch to temporary
- */
- pGC = GetScratchGC (list->format->depth, pScreen);
- ValidateGC (&pPixmap->drawable, pGC);
- } else {
- (*pScreen->ModifyPixmapHeader) (pScratchPixmap,
- glyph->info.width,
- glyph->info.height,
- 0, 0, -1, glyphdata);
- pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
-
-#ifdef MITSHM
- if (pExaScr->info->PrepareComposite)
- exaShmPutImage(&pPixmap->drawable, pGC,
- pPixmap->drawable.depth, ZPixmap,
- glyph->info.width, glyph->info.height, 0, 0,
- glyph->info.width, glyph->info.height, 0, 0,
- glyphdata);
- else
-#endif
- exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
- 0, 0, glyph->info.width, glyph->info.height, 0, 0);
- }
-
- exaPixmapDirty (pPixmap, 0, 0,
- glyph->info.width, glyph->info.height);
-
- if (maskFormat)
- {
- exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
- x1, y1, glyph->info.width, glyph->info.height);
- exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
- y1 + glyph->info.height);
- }
- else
- {
- exaComposite (op, pSrc, pPicture, pDst,
- xSrc + x1 - xDst, ySrc + y1 - yDst,
- 0, 0, x1, y1, glyph->info.width,
- glyph->info.height);
- }
-nextglyph:
- x += glyph->info.xOff;
- y += glyph->info.yOff;
- }
- list++;
- if (pGC != NULL)
- FreeScratchGC (pGC);
- FreePicture ((pointer) pPicture, 0);
- (*pScreen->DestroyPixmap) (pPixmap);
- if (pScratchPixmap != NULL)
- FreeScratchPixmapHeader (pScratchPixmap);
- }
- if (maskFormat)
- {
- x = extents.x1;
- y = extents.y1;
- exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst,
- 0, 0, x, y, width, height);
- FreePicture ((pointer) pMask, (XID) 0);
- (*pScreen->DestroyPixmap) (pMaskPixmap);
- }
-}