xserver: Branch 'master' - 12 commits

Eric Anholt anholt at kemper.freedesktop.org
Fri Oct 19 17:52:35 PDT 2007


 configure.ac              |    4 
 exa/exa.c                 |    8 -
 exa/exa_priv.h            |    1 
 exa/exa_render.c          |  353 ----------------------------------------------
 hw/xfree86/loader/misym.c |    3 
 miext/cw/cw.h             |    1 
 miext/cw/cw_render.c      |   30 ---
 render/Makefile.am        |    1 
 render/glyph.c            |  329 ++++++++++++++++++++++++++++++++++++++----
 render/glyphstr.h         |   28 ++-
 render/miglyph.c          |  255 ---------------------------------
 render/mipict.c           |    2 
 render/mipict.h           |    6 
 render/picture.c          |   18 --
 render/picturestr.h       |    2 
 render/render.c           |  156 +++++++++++++++-----
 16 files changed, 442 insertions(+), 755 deletions(-)

New commits:
commit 4b14c9a9cd2033d3839c4ba364d41ab4c4b198ab
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Oct 19 16:34:54 2007 -0700

    Replace calls to Glyphs screen hook with CompositeGlyphs and remove dead code.
    
    Not all of the DDX/miext Glyphs hook implementations have been removed, but
    they should be.

diff --git a/exa/exa.c b/exa/exa.c
index 7ad226f..6d6c054 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -291,7 +291,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
@@ -696,7 +698,6 @@ exaCloseScreen(int i, ScreenPtr pScreen)
 #ifdef RENDER
     if (ps) {
 	ps->Composite = pExaScr->SavedComposite;
-	ps->Glyphs = pExaScr->SavedGlyphs;
 	ps->Trapezoids = pExaScr->SavedTrapezoids;
     }
 #endif
@@ -865,9 +866,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_render.c b/exa/exa_render.c
index 847a361..6a9e53f 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -997,261 +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);
-    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;
-
-	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;
-	}
-
-	while (n--)
-	{
-	    GlyphPtr glyph = *glyphs++;
-	    DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
-
-	    x1 = x - glyph->info.x;
-	    y1 = y - glyph->info.y;
-
-	    if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
-		glyph->info.width == 0 || glyph->info.height == 0 ||
-		(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
-		goto nextglyph;
-
-	    /* The glyph already has a Picture ready for us to use. */
-	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
-	    ValidatePicture(pPicture);
-
-	    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);
-    }
-    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);
-    }
-}
diff --git a/hw/xfree86/loader/misym.c b/hw/xfree86/loader/misym.c
index 78ae10e..025983b 100644
--- a/hw/xfree86/loader/misym.c
+++ b/hw/xfree86/loader/misym.c
@@ -205,9 +205,6 @@ _X_HIDDEN void *miLookupTab[] = {
     SYMVAR(miPointerScreenIndex)
     SYMVAR(miInstalledMaps)
     SYMVAR(miInitVisualsProc)
-#ifdef RENDER
-    SYMFUNC(miGlyphExtents)
-#endif
 #ifdef DAMAGE
     SYMFUNC(DamageDamageRegion)
 #endif
diff --git a/miext/cw/cw.h b/miext/cw/cw.h
index 8e42ac2..a83949d 100644
--- a/miext/cw/cw.h
+++ b/miext/cw/cw.h
@@ -98,7 +98,6 @@ typedef struct {
     ValidatePictureProcPtr	ValidatePicture;
 
     CompositeProcPtr		Composite;
-    GlyphsProcPtr		Glyphs;
     CompositeRectsProcPtr	CompositeRects;
 
     TrapezoidsProcPtr		Trapezoids;
diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c
index 35416be..6e0c727 100644
--- a/miext/cw/cw_render.c
+++ b/miext/cw/cw_render.c
@@ -280,34 +280,6 @@ cwComposite (CARD8	op,
 }
 
 static void
-cwGlyphs (CARD8      op,
-	  PicturePtr pSrcPicture,
-	  PicturePtr pDstPicture,
-	  PictFormatPtr  maskFormat,
-	  INT16      xSrc,
-	  INT16      ySrc,
-	  int	nlists,
-	  GlyphListPtr   lists,
-	  GlyphPtr	*glyphs)
-{
-    ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
-    cwPsDecl(pScreen);
-    cwSrcPictureDecl;
-    cwDstPictureDecl;
-    
-    cwPsUnwrap(Glyphs);
-    if (nlists)
-    {
-	lists->xOff += dst_picture_x_off;
-	lists->yOff += dst_picture_y_off;
-    }
-    (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
-		   xSrc + src_picture_x_off, ySrc + src_picture_y_off,
-		   nlists, lists, glyphs);
-    cwPsWrap(Glyphs, cwGlyphs);
-}
-
-static void
 cwCompositeRects (CARD8		op,
 		  PicturePtr	pDstPicture,
 		  xRenderColor  *color,
@@ -470,7 +442,6 @@ cwInitializeRender (ScreenPtr pScreen)
     cwPsWrap(ChangePicture, cwChangePicture);
     cwPsWrap(ValidatePicture, cwValidatePicture);
     cwPsWrap(Composite, cwComposite);
-    cwPsWrap(Glyphs, cwGlyphs);
     cwPsWrap(CompositeRects, cwCompositeRects);
     cwPsWrap(Trapezoids, cwTrapezoids);
     cwPsWrap(Triangles, cwTriangles);
@@ -491,7 +462,6 @@ cwFiniRender (ScreenPtr pScreen)
     cwPsUnwrap(ChangePicture);
     cwPsUnwrap(ValidatePicture);
     cwPsUnwrap(Composite);
-    cwPsUnwrap(Glyphs);
     cwPsUnwrap(CompositeRects);
     cwPsUnwrap(Trapezoids);
     cwPsUnwrap(Triangles);
diff --git a/render/Makefile.am b/render/Makefile.am
index 830778a..e53c7c7 100644
--- a/render/Makefile.am
+++ b/render/Makefile.am
@@ -6,7 +6,6 @@ librender_la_SOURCES =	\
 	animcur.c	\
 	filter.c	\
 	glyph.c		\
-	miglyph.c	\
 	miindex.c	\
 	mipict.c	\
 	mirect.c	\
diff --git a/render/glyph.c b/render/glyph.c
index 975c62b..5cd7992 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -43,6 +43,7 @@
 #include "servermd.h"
 #include "picturestr.h"
 #include "glyphstr.h"
+#include "mipict.h"
 
 /*
  * From Knuth -- a good choice for hash/rehash values is p, p-2 where
@@ -845,3 +846,215 @@ FreeGlyphSet (pointer	value,
     }
     return Success;
 }
+
+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;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+/* Stub ABI compatibility for mi*Glyph, should go away */
+_X_EXPORT void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list,
+		    glyphs);
+}
+
+Bool
+miRealizeGlyph (ScreenPtr pScreen,
+		GlyphPtr  glyph)
+{
+    return TRUE;
+}
+
+void
+miUnrealizeGlyph (ScreenPtr pScreen,
+		  GlyphPtr  glyph)
+{
+}
+
+_X_EXPORT void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	list,
+		 GlyphPtr	*glyphs)
+{
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents = {0, 0, 0, 0};
+    CARD32	component_alpha;
+
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+
+    if (maskFormat)
+    {
+	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;
+	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;
+	}
+	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
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
+
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+	list++;
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+}
diff --git a/render/miglyph.c b/render/miglyph.c
deleted file mode 100644
index a52ea49..0000000
--- a/render/miglyph.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- *
- * 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 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:  Keith Packard, SuSE, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "picturestr.h"
-#include "mipict.h"
-
-Bool
-miRealizeGlyph (ScreenPtr pScreen,
-		GlyphPtr  glyph)
-{
-    return TRUE;
-}
-
-void
-miUnrealizeGlyph (ScreenPtr pScreen,
-		  GlyphPtr  glyph)
-{
-}
-
-_X_EXPORT void
-miGlyphExtents (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;
-	}
-    }
-}
-
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
-_X_EXPORT void
-miGlyphs (CARD8		op,
-	  PicturePtr	pSrc,
-	  PicturePtr	pDst,
-	  PictFormatPtr	maskFormat,
-	  INT16		xSrc,
-	  INT16		ySrc,
-	  int		nlist,
-	  GlyphListPtr	list,
-	  GlyphPtr	*glyphs)
-{
-    PixmapPtr	pPixmap;
-    PicturePtr	pPicture;
-    PixmapPtr   pMaskPixmap = 0;
-    PicturePtr  pMask;
-    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
-    int		width = 0, height = 0;
-    int		x, y;
-    int		xDst = list->xOff, yDst = list->yOff;
-    int		n;
-    GlyphPtr	glyph;
-    int		error;
-    BoxRec	extents;
-    CARD32	component_alpha;
-    
-    if (maskFormat)
-    {
-	GCPtr	    pGC;
-	xRectangle  rect;
-	
-	miGlyphExtents (nlist, list, glyphs, &extents);
-	
-	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;
-	}
-	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
-    {
-	pMask = pDst;
-	x = 0;
-	y = 0;
-    }
-    while (nlist--)
-    {
-	x += list->xOff;
-	y += list->yOff;
-	n = list->len;
-	while (n--)
-	{
-	    glyph = *glyphs++;
-	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
-
-	    if (maskFormat)
-	    {
-		CompositePicture (PictOpAdd,
-				  pPicture,
-				  None,
-				  pMask,
-				  0, 0,
-				  0, 0,
-				  x - glyph->info.x,
-				  y - glyph->info.y,
-				  glyph->info.width,
-				  glyph->info.height);
-	    }
-	    else
-	    {
-		CompositePicture (op,
-				  pSrc,
-				  pPicture,
-				  pDst,
-				  xSrc + (x - glyph->info.x) - xDst,
-				  ySrc + (y - glyph->info.y) - yDst,
-				  0, 0,
-				  x - glyph->info.x,
-				  y - glyph->info.y,
-				  glyph->info.width,
-				  glyph->info.height);
-	    }
-
-	    x += glyph->info.xOff;
-	    y += glyph->info.yOff;
-	}
-	list++;
-    }
-    if (maskFormat)
-    {
-	x = extents.x1;
-	y = extents.y1;
-	CompositePicture (op,
-			  pSrc,
-			  pMask,
-			  pDst,
-			  xSrc + x - xDst,
-			  ySrc + y - yDst,
-			  0, 0,
-			  x, y,
-			  width, height);
-	FreePicture ((pointer) pMask, (XID) 0);
-	(*pScreen->DestroyPixmap) (pMaskPixmap);
-    }
-}
diff --git a/render/mipict.c b/render/mipict.c
index 87dccbb..5aad676 100644
--- a/render/mipict.c
+++ b/render/mipict.c
@@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
 
     /* MI rendering routines */
     ps->Composite	= 0;			/* requires DDX support */
-    ps->Glyphs		= miGlyphs;
+    ps->Glyphs		= NULL;
     ps->CompositeRects	= miCompositeRects;
     ps->Trapezoids	= miTrapezoids;
     ps->Triangles	= miTriangles;
diff --git a/render/mipict.h b/render/mipict.h
index bd7c23f..60baf7f 100644
--- a/render/mipict.h
+++ b/render/mipict.h
@@ -120,12 +120,6 @@ miUnrealizeGlyph (ScreenPtr pScreen,
 		  GlyphPtr  glyph);
 
 void
-miGlyphExtents (int		nlist,
-		GlyphListPtr	list,
-		GlyphPtr	*glyphs,
-		BoxPtr		extents);
-
-void
 miGlyphs (CARD8		op,
 	  PicturePtr	pSrc,
 	  PicturePtr	pDst,
diff --git a/render/picture.c b/render/picture.c
index ede865f..a7e40f9 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1768,24 +1768,6 @@ CompositePicture (CARD8		op,
 }
 
 void
-CompositeGlyphs (CARD8		op,
-		 PicturePtr	pSrc,
-		 PicturePtr	pDst,
-		 PictFormatPtr	maskFormat,
-		 INT16		xSrc,
-		 INT16		ySrc,
-		 int		nlist,
-		 GlyphListPtr	lists,
-		 GlyphPtr	*glyphs)
-{
-    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
-    
-    ValidatePicture (pSrc);
-    ValidatePicture (pDst);
-    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
-}
-
-void
 CompositeRects (CARD8		op,
 		PicturePtr	pDst,
 		xRenderColor	*color,
diff --git a/render/picturestr.h b/render/picturestr.h
index 09a7131..b2e180f 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -345,7 +345,7 @@ typedef struct _PictureScreen {
     ValidatePictureProcPtr	ValidatePicture;
 
     CompositeProcPtr		Composite;
-    GlyphsProcPtr		Glyphs;
+    GlyphsProcPtr		Glyphs; /* unused */
     CompositeRectsProcPtr	CompositeRects;
 
     DestroyWindowProcPtr	DestroyWindow;
commit a3a95d3475dc91ed2e8a55bf484a6b3f2b5ac32a
Merge: a358b87... 7e1cada...
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Oct 19 15:44:17 2007 -0700

    Merge branch 'master' into glyph-pixmaps
    
    Conflicts:
    
    	configure.ac

diff --cc configure.ac
index ee631b1,fb88773..e7d229c
--- a/configure.ac
+++ b/configure.ac
@@@ -1875,7 -1884,7 +1884,7 @@@ if test "$KDRIVE" = yes; the
      KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
      KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
      KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
-     KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS"
 -    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS $XV_LIBS"
++    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $XV_LIBS"
  
      # check if we can build Xephyr
      PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
commit a358b87f45ce75e5d013fc904a07dfe394f74387
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Oct 2 13:13:51 2007 -0700

    Just link against libcrypto instead of relying on openssl pkg-config.
    
    Also fix incorrect library inclusion by kdrive which broke the build.

diff --git a/configure.ac b/configure.ac
index d7c513e..ee631b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -631,7 +631,7 @@ else
 fi
 
 REQUIRED_MODULES="[randrproto >= 1.2] $RENDERPROTO [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
-REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5] openssl"
+REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5]"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
 dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
@@ -1081,7 +1081,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
 #
 XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
 XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB"
-XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
+XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} -lcrypto"
 AC_SUBST([XSERVER_LIBS])
 AC_SUBST([XSERVER_SYS_LIBS])
 
@@ -1875,7 +1875,7 @@ if test "$KDRIVE" = yes; then
     KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
-    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS"
+    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS"
 
     # check if we can build Xephyr
     PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"])
commit 439edc768eea17667846ce573c843b8377e0dfb4
Merge: c8ccf46... 93ae6fe...
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Oct 2 12:14:04 2007 -0700

    Merge branch 'glyph-pixmaps'
    
    Conflicts:
    
    	configure.ac
    	exa/exa_render.c

diff --cc configure.ac
index a5f1866,89c6b55..d7c513e
--- a/configure.ac
+++ b/configure.ac
@@@ -622,16 -617,11 +622,16 @@@ XEXT_INC='-I$(top_srcdir)/Xext
  XEXT_LIB='$(top_builddir)/Xext/libXext.la'
  XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
  
 -PIXMAN="[pixman >= 0.9.2]"
 -
  dnl Core modules for most extensions, et al.
 -REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
 -REQUIRED_LIBS="xfont xau fontenc $PIXMAN openssl"
 +# Require updated renderproto for ABI sanity if we're 64-bit.
 +if test "$ac_cv_sizeof_unsigned_long" = 8; then
 +	RENDERPROTO="[renderproto >= 0.9.3]"
 +else
 +	RENDERPROTO="renderproto"
 +fi
 +
 +REQUIRED_MODULES="[randrproto >= 1.2] $RENDERPROTO [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
- REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5]"
++REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5] openssl"
  
  dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
  dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
diff --cc exa/exa_render.c
index 2ad5304,24411dd..98fc884
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@@ -1081,9 -896,9 +1081,8 @@@ exaGlyphs (CARD8	op
  	  GlyphPtr	*glyphs)
  {
      ExaScreenPriv (pDst->pDrawable->pScreen);
-     PixmapPtr	pPixmap = NULL;
      PicturePtr	pPicture;
      PixmapPtr   pMaskPixmap = NULL;
 -    PixmapPtr   pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
      PicturePtr  pMask;
      ScreenPtr   pScreen = pDst->pDrawable->pScreen;
      int		width = 0, height = 0;
@@@ -1314,7 -1047,12 +1222,8 @@@
  			      xSrc + x1 - xDst, ySrc + y1 - yDst,
  			      0, 0, x1, y1, glyph->info.width,
  			      glyph->info.height);
 -		x1 += pDst->pDrawable->x + xoff;
 -		y1 += pDst->pDrawable->y + yoff;
 -		exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
 -			       y1 + glyph->info.height);
  	    }
+ 
  nextglyph:
  	    x += glyph->info.xOff;
  	    y += glyph->info.yOff;
commit 93ae6fe18c417a22f1fccb22add4890a20cae713
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Aug 23 16:33:05 2007 -0700

    Avoid leaking a Pixmap for every glyph

diff --git a/render/render.c b/render/render.c
index 300b784..1a1cd7a 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1209,6 +1209,11 @@ ProcRenderAddGlyphs (ClientPtr client)
 				       glyphSet->format,
 				       CPComponentAlpha, &component_alpha,
 				       serverClient, &error);
+
+		/* The picture takes a reference to the pixmap, so we
+		   drop ours. */
+		(pScreen->DestroyPixmap) (pDstPix);
+
 		if (! pDst)
 		{
 		    err = BadAlloc;
commit 0a71e1542a07abc5e32501973a7cf6de3f641317
Author: Carl Worth <cworth at cworth.org>
Date:   Thu Aug 2 22:48:32 2007 -0700

    Create a Picture as well as a Pixmap at the time of AllocateGlyph
    
    This avoids some inefficiency in creating a temporary Picture
    for every glyph at rendering time. My measurements with an i965
    showed the previous patch causing a 10-15% slowdown for NoAccel
    and XAA cases, (while providing an 18% speedup for EXA).
    
    With this change, the NoAccel and XAA performance regression is
    eliminated, and the overall EXA speedup, (before any of the
    glyphs-as-pixmaps work), is now 32%.

diff --git a/exa/exa_render.c b/exa/exa_render.c
index 3326839..24411dd 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -896,7 +896,6 @@ exaGlyphs (CARD8	op,
 	  GlyphPtr	*glyphs)
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
-    PixmapPtr	pPixmap = NULL;
     PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = NULL;
     PixmapPtr   pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
@@ -1031,18 +1030,8 @@ exaGlyphs (CARD8	op,
 		(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
 		goto nextglyph;
 
-	    /* The glyph already has a pixmap waiting for us to use. */
-	    pPixmap = GlyphPixmap (glyph)[pScreen->myNum];
-
-	    /* Create a temporary picture to wrap the 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)
-	      return;
+	    /* The glyph already has a Picture ready for us to use. */
+	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
 	    ValidatePicture(pPicture);
 
 	    if (maskFormat)
@@ -1063,7 +1052,6 @@ exaGlyphs (CARD8	op,
 		exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
 			       y1 + glyph->info.height);
 	    }
-	    FreePicture ((pointer) pPicture, 0);
 
 nextglyph:
 	    x += glyph->info.xOff;
diff --git a/render/glyph.c b/render/glyph.c
index 7fd3705..975c62b 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -573,7 +573,7 @@ FreeGlyph (GlyphPtr glyph, int format)
 	{
 	    ScreenPtr pScreen = screenInfo.screens[i];
 
-	    (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]);
+	    FreePicture ((pointer) GlyphPicture (glyph)[i], 0);
 
 	    ps = GetPictureScreenIfSet (pScreen);
 	    if (ps)
@@ -669,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
     GlyphPtr	     glyph;
     int		     i;
 
-    size = screenInfo.numScreens * sizeof (PixmapPtr);
+    size = screenInfo.numScreens * sizeof (PicturePtr);
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
@@ -689,21 +689,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 
     for (i = 0; i < screenInfo.numScreens; i++)
     {
-	ScreenPtr pScreen = screenInfo.screens[i];
-
-	GlyphPixmap (glyph)[i] = (pScreen->CreatePixmap) (pScreen,
-							  gi->width, gi->height,
-							  glyphDepths[fdepth]);
-	if (! GlyphPixmap (glyph)[i])
-	    goto bail;
-
-	ps = GetPictureScreenIfSet (pScreen);
-	if (! ps)
-	    continue;
+	ps = GetPictureScreenIfSet (screenInfo.screens[i]);
 
-	if (!(*ps->RealizeGlyph) (pScreen, glyph)) {
-	    (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]);
-	    goto bail;
+	if (ps)
+	{
+	    if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
+		goto bail;
 	}
     }
     
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 4f87460..c6ab5aa 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -47,7 +47,7 @@ typedef struct _Glyph {
     /* per-screen pixmaps follow */
 } GlyphRec, *GlyphPtr;
 
-#define GlyphPixmap(glyph) ((PixmapPtr *) ((glyph) + 1))
+#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1))
 
 typedef struct _GlyphRef {
     CARD32	signature;
diff --git a/render/miglyph.c b/render/miglyph.c
index 2aa94bd..a52ea49 100644
--- a/render/miglyph.c
+++ b/render/miglyph.c
@@ -174,13 +174,7 @@ miGlyphs (CARD8		op,
 	while (n--)
 	{
 	    glyph = *glyphs++;
-	    pPixmap = GlyphPixmap (glyph)[pScreen->myNum];
-	    component_alpha = NeedsComponent(list->format->format);
-	    pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
-				      CPComponentAlpha, &component_alpha, 
-				      serverClient, &error);
-	    if (!pPicture)
-	      return;
+	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
 
 	    if (maskFormat)
 	    {
@@ -209,7 +203,6 @@ miGlyphs (CARD8		op,
 				  glyph->info.width,
 				  glyph->info.height);
 	    }
-	    FreePicture ((pointer) pPicture, 0);
 
 	    x += glyph->info.xOff;
 	    y += glyph->info.yOff;
diff --git a/render/render.c b/render/render.c
index 4bad379..300b784 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1086,6 +1086,8 @@ typedef struct _GlyphNew {
     unsigned char   sha1[20];
 } GlyphNewRec, *GlyphNewPtr;
 
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
 static int
 ProcRenderAddGlyphs (ClientPtr client)
 {
@@ -1102,6 +1104,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     int		    i, screen;
     PicturePtr	    pSrc = NULL, pDst = NULL;
     PixmapPtr	    pSrcPix = NULL, pDstPix = NULL;
+    CARD32	    component_alpha;
 
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
@@ -1118,6 +1121,8 @@ ProcRenderAddGlyphs (ClientPtr client)
     if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
 	    return BadAlloc;
 
+    component_alpha = NeedsComponent (glyphSet->format->format);
+
     if (nglyphs <= NLOCALGLYPH) {
 	memset (glyphsLocal, 0, sizeof (glyphsLocal));
 	glyphsBase = glyphsLocal;
@@ -1158,9 +1163,11 @@ ProcRenderAddGlyphs (ClientPtr client)
 	}
 	else
 	{
+	    GlyphPtr glyph;
+
 	    glyph_new->found = FALSE;
-	    glyph_new->glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
-	    if (! glyph_new->glyph)
+	    glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
+	    if (! glyph)
 	    {
 		err = BadAlloc;
 		goto bail;
@@ -1194,11 +1201,14 @@ ProcRenderAddGlyphs (ClientPtr client)
 		    goto bail;
 		}
 
-		pDstPix = GlyphPixmap (glyph_new->glyph)[screen];
+		pDstPix = (pScreen->CreatePixmap) (pScreen,
+						   width, height, depth);
 
-		pDst = CreatePicture (0, &pDstPix->drawable,
-				      glyphSet->format, 0, NULL,
-				      serverClient, &error);
+		GlyphPicture (glyph)[screen] = pDst =
+			CreatePicture (0, &pDstPix->drawable,
+				       glyphSet->format,
+				       CPComponentAlpha, &component_alpha,
+				       serverClient, &error);
 		if (! pDst)
 		{
 		    err = BadAlloc;
@@ -1216,8 +1226,6 @@ ProcRenderAddGlyphs (ClientPtr client)
 
 		FreePicture ((pointer) pSrc, 0);
 		pSrc = NULL;
-		FreePicture ((pointer) pDst, 0);
-		pDst = NULL;
 		FreeScratchPixmapHeader (pSrcPix);
 		pSrcPix = NULL;
 	    }
@@ -1251,8 +1259,6 @@ ProcRenderAddGlyphs (ClientPtr client)
 bail:
     if (pSrc)
 	FreePicture ((pointer) pSrc, 0);
-    if (pDst)
-	FreePicture ((pointer) pDst, 0);
     if (pSrcPix)
 	FreeScratchPixmapHeader (pSrcPix);
     for (i = 0; i < nglyphs; i++)
commit a2af34d5a861982a03afad8e586bb0181b72bbd0
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Aug 1 15:48:30 2007 -0700

    Use per-screen Pixmaps for glyphs
    
    Instead of system-memory data which prevents accelerated
    compositing of glyphs, (at least without forcing an upload
    of the glyph data before compositing).

diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a6d98cd..a80704a 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -50,6 +50,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 5e7c67f..3326839 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -996,8 +996,6 @@ exaGlyphs (CARD8	op,
     {
 	GCPtr pGC = NULL;
 	int maxwidth = 0, maxheight = 0, i;
-	ExaMigrationRec pixmaps[1];
-	PixmapPtr pScratchPixmap = NULL;
 
 	x += list->xOff;
 	y += list->yOff;
@@ -1021,37 +1019,9 @@ exaGlyphs (CARD8	op,
 	    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 = TRUE;
-	pixmaps[0].pPix = pPixmap;
-	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;
@@ -1061,60 +1031,19 @@ exaGlyphs (CARD8	op,
 		(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);
+	    /* The glyph already has a pixmap waiting for us to use. */
+	    pPixmap = GlyphPixmap (glyph)[pScreen->myNum];
 
-	    /* 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.
+	    /* Create a temporary picture to wrap the pixmap, so it can be
+	     * used as a source for Composite.
 	     */
-	    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;
-		}
-
-		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);
+	    component_alpha = NeedsComponent(list->format->format);
+	    pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+				      CPComponentAlpha, &component_alpha, 
+				      serverClient, &error);
+	    if (!pPicture)
+	      return;
+	    ValidatePicture(pPicture);
 
 	    if (maskFormat)
 	    {
@@ -1134,6 +1063,8 @@ exaGlyphs (CARD8	op,
 		exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
 			       y1 + glyph->info.height);
 	    }
+	    FreePicture ((pointer) pPicture, 0);
+
 nextglyph:
 	    x += glyph->info.xOff;
 	    y += glyph->info.yOff;
@@ -1141,10 +1072,6 @@ nextglyph:
 	list++;
 	if (pGC != NULL)
 	    FreeScratchGC (pGC);
-	FreePicture ((pointer) pPicture, 0);
-	(*pScreen->DestroyPixmap) (pPixmap);
-	if (pScratchPixmap != NULL)
-	    FreeScratchPixmapHeader (pScratchPixmap);
     }
     if (maskFormat)
     {
diff --git a/render/glyph.c b/render/glyph.c
index 7dbdda2..7fd3705 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -571,9 +571,13 @@ FreeGlyph (GlyphPtr glyph, int format)
 
 	for (i = 0; i < screenInfo.numScreens; i++)
 	{
-	    ps = GetPictureScreenIfSet (screenInfo.screens[i]);
+	    ScreenPtr pScreen = screenInfo.screens[i];
+
+	    (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]);
+
+	    ps = GetPictureScreenIfSet (pScreen);
 	    if (ps)
-		(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
+		(*ps->UnrealizeGlyph) (pScreen, glyph);
 	}
 	
 	if (glyph->devPrivates)
@@ -665,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
     GlyphPtr	     glyph;
     int		     i;
 
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size = screenInfo.numScreens * sizeof (PixmapPtr);
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
@@ -685,27 +689,38 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 
     for (i = 0; i < screenInfo.numScreens; i++)
     {
-	ps = GetPictureScreenIfSet (screenInfo.screens[i]);
-	if (ps)
-	{
-	    if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
-	    {
-		while (i--)
-		{
-		    ps = GetPictureScreenIfSet (screenInfo.screens[i]);
-		    if (ps)
-			(*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
-		}
-		
-		if (glyph->devPrivates)
-		    xfree (glyph->devPrivates);
-		xfree (glyph);
-		return 0;
-	    }
+	ScreenPtr pScreen = screenInfo.screens[i];
+
+	GlyphPixmap (glyph)[i] = (pScreen->CreatePixmap) (pScreen,
+							  gi->width, gi->height,
+							  glyphDepths[fdepth]);
+	if (! GlyphPixmap (glyph)[i])
+	    goto bail;
+
+	ps = GetPictureScreenIfSet (pScreen);
+	if (! ps)
+	    continue;
+
+	if (!(*ps->RealizeGlyph) (pScreen, glyph)) {
+	    (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]);
+	    goto bail;
 	}
     }
     
     return glyph;
+
+bail:
+    while (i--)
+    {
+	ps = GetPictureScreenIfSet (screenInfo.screens[i]);
+	if (ps)
+	    (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph);
+    }
+		
+    if (glyph->devPrivates)
+	xfree (glyph->devPrivates);
+    xfree (glyph);
+    return 0;
 }
     
 Bool
diff --git a/render/glyphstr.h b/render/glyphstr.h
index d47dfec..4f87460 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -44,9 +44,11 @@ typedef struct _Glyph {
     unsigned char   sha1[20];
     CARD32	    size; /* info + bitmap */
     xGlyphInfo	    info;
-    /* bits follow */
+    /* per-screen pixmaps follow */
 } GlyphRec, *GlyphPtr;
 
+#define GlyphPixmap(glyph) ((PixmapPtr *) ((glyph) + 1))
+
 typedef struct _GlyphRef {
     CARD32	signature;
     GlyphPtr	glyph;
diff --git a/render/miglyph.c b/render/miglyph.c
index 7968c90..2aa94bd 100644
--- a/render/miglyph.c
+++ b/render/miglyph.c
@@ -112,7 +112,7 @@ miGlyphs (CARD8		op,
 	  GlyphListPtr	list,
 	  GlyphPtr	*glyphs)
 {
-    PixmapPtr	pPixmap = 0;
+    PixmapPtr	pPixmap;
     PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = 0;
     PicturePtr  pMask;
@@ -166,7 +166,6 @@ miGlyphs (CARD8		op,
 	x = 0;
 	y = 0;
     }
-    pPicture = 0;
     while (nlist--)
     {
 	x += list->xOff;
@@ -175,28 +174,14 @@ miGlyphs (CARD8		op,
 	while (n--)
 	{
 	    glyph = *glyphs++;
+	    pPixmap = GlyphPixmap (glyph)[pScreen->myNum];
+	    component_alpha = NeedsComponent(list->format->format);
+	    pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+				      CPComponentAlpha, &component_alpha, 
+				      serverClient, &error);
 	    if (!pPicture)
-	    {
-		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
-						  list->format->depth,
-						  list->format->depth, 
-						  0, (pointer) (glyph + 1));
-		if (!pPixmap)
-		    return;
-		component_alpha = NeedsComponent(list->format->format);
-		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
-					  CPComponentAlpha, &component_alpha, 
-					  serverClient, &error);
-		if (!pPicture)
-		{
-		    FreeScratchPixmapHeader (pPixmap);
-		    return;
-		}
-	    }
-	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
-					    glyph->info.width, glyph->info.height,
-					    0, 0, -1, (pointer) (glyph + 1));
-	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	      return;
+
 	    if (maskFormat)
 	    {
 		CompositePicture (PictOpAdd,
@@ -224,17 +209,12 @@ miGlyphs (CARD8		op,
 				  glyph->info.width,
 				  glyph->info.height);
 	    }
+	    FreePicture ((pointer) pPicture, 0);
+
 	    x += glyph->info.xOff;
 	    y += glyph->info.yOff;
 	}
 	list++;
-	if (pPicture)
-	{
-	    FreeScratchPixmapHeader (pPixmap);
-	    FreePicture ((pointer) pPicture, 0);
-	    pPicture = 0;
-	    pPixmap = 0;
-	}
     }
     if (maskFormat)
     {
diff --git a/render/render.c b/render/render.c
index c7a6dcb..4bad379 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1099,7 +1099,9 @@ ProcRenderAddGlyphs (ClientPtr client)
     CARD8	    *bits;
     int		    size;
     int		    err = BadAlloc;
-    int		    i;
+    int		    i, screen;
+    PicturePtr	    pSrc = NULL, pDst = NULL;
+    PixmapPtr	    pSrcPix = NULL, pDstPix = NULL;
 
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
@@ -1164,7 +1166,62 @@ ProcRenderAddGlyphs (ClientPtr client)
 		goto bail;
 	    }
 
-	    memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size);
+	    for (screen = 0; screen < screenInfo.numScreens; screen++)
+	    {
+		int	    width = gi[i].width;
+		int	    height = gi[i].height;
+		int	    depth = glyphSet->format->depth;
+		ScreenPtr   pScreen;
+		int	    error;
+
+		pScreen = screenInfo.screens[screen];
+		pSrcPix = GetScratchPixmapHeader (pScreen,
+						  width, height,
+						  depth, depth,
+						  -1, bits);
+		if (! pSrcPix)
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+
+		pSrc = CreatePicture (0, &pSrcPix->drawable,
+				      glyphSet->format, 0, NULL,
+				      serverClient, &error);
+		if (! pSrc)
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+
+		pDstPix = GlyphPixmap (glyph_new->glyph)[screen];
+
+		pDst = CreatePicture (0, &pDstPix->drawable,
+				      glyphSet->format, 0, NULL,
+				      serverClient, &error);
+		if (! pDst)
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+
+		CompositePicture (PictOpSrc,
+				  pSrc,
+				  None,
+				  pDst,
+				  0, 0,
+				  0, 0,
+				  0, 0,
+				  width, height);
+
+		FreePicture ((pointer) pSrc, 0);
+		pSrc = NULL;
+		FreePicture ((pointer) pDst, 0);
+		pDst = NULL;
+		FreeScratchPixmapHeader (pSrcPix);
+		pSrcPix = NULL;
+	    }
+
 	    memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
 	}
 
@@ -1192,6 +1249,12 @@ ProcRenderAddGlyphs (ClientPtr client)
 	Xfree (glyphsBase);
     return client->noClientException;
 bail:
+    if (pSrc)
+	FreePicture ((pointer) pSrc, 0);
+    if (pDst)
+	FreePicture ((pointer) pDst, 0);
+    if (pSrcPix)
+	FreeScratchPixmapHeader (pSrcPix);
     for (i = 0; i < nglyphs; i++)
 	if (glyphs[i].glyph && ! glyphs[i].found)
 	    xfree (glyphs[i].glyph);
commit 19b3b1fd8feb343a690331cafe88ef10b34b9d98
Author: Carl Worth <cworth at cworth.org>
Date:   Tue Jul 31 17:04:13 2007 -0700

    Use strong hash (SHA1) for glyphs
    
    Using a cryptographically strong hash means that comparing the
    hash alone is sufficient for determining glyph equality (no need
    to compare the glyph bits directly). This will allow us to replace
    system-memory copies of the glyph bits, (which we've only been
    holding onto for comparisons), with Pixmaps.

diff --git a/configure.ac b/configure.ac
index 518f332..89c6b55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -621,7 +621,7 @@ PIXMAN="[pixman >= 0.9.2]"
 
 dnl Core modules for most extensions, et al.
 REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
-REQUIRED_LIBS="xfont xau fontenc $PIXMAN"
+REQUIRED_LIBS="xfont xau fontenc $PIXMAN openssl"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
 dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
diff --git a/render/glyph.c b/render/glyph.c
index 1204c3b..7dbdda2 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -26,6 +26,8 @@
 #include <dix-config.h>
 #endif
 
+#include <openssl/sha.h>
+
 #include "misc.h"
 #include "scrnintstr.h"
 #include "os.h"
@@ -412,7 +414,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
 }
 
 GlyphRefPtr
-FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+FindGlyphRef (GlyphHashPtr	hash,
+	      CARD32		signature,
+	      Bool		match,
+	      unsigned char	sha1[20])
 {
     CARD32	elt, step, s;
     GlyphPtr	glyph;
@@ -443,7 +448,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
 	}
 	else if (s == signature &&
 		 (!match || 
-		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+		  memcmp (glyph->sha1, sha1, 20) == 0))
 	{
 	    break;
 	}
@@ -460,54 +465,42 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
     return gr;
 }
 
-CARD32
-HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size)
+int
+HashGlyph (xGlyphInfo    *gi,
+	   CARD8	 *bits,
+	   unsigned long size,
+	   unsigned char sha1[20])
 {
-    CARD32  *bits;
-    CARD32  hash;
-    int	    n;
+    SHA_CTX ctx;
+    int success;
 
-    hash = 0;
+    success = SHA1_Init (&ctx);
+    if (! success)
+	return BadAlloc;
 
-    bits = (CARD32 *) gi;
-    n = sizeof (xGlyphInfo) / sizeof (CARD32);
-    while (n--)
-	hash ^= *bits++;
+    success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo));
+    if (! success)
+	return BadAlloc;
 
-    bits = (CARD32 *) data;
-    n = size / sizeof (CARD32);
-    while (n--)
-	hash ^= *bits++;
+    success = SHA1_Update (&ctx, bits, size);
+    if (! success)
+	return BadAlloc;
 
-    return hash;
-}
+    success = SHA1_Final (sha1, &ctx);
+    if (! success)
+	return BadAlloc;
 
-CARD32
-HashGlyph (GlyphPtr glyph)
-{
-    return HashGlyphInfoAndBits (&glyph->info,
-				 (CARD8 *) (&glyph->info + 1),
-				 glyph->size - sizeof (xGlyphInfo));
+    return Success;
 }
 
 GlyphPtr
-FindGlyphByHash (CARD32	    hash,
-		 xGlyphInfo *gi,
-		 CARD8	    *bits,
-		 int	    format)
+FindGlyphByHash (unsigned char sha1[20], int format)
 {
     GlyphRefPtr gr;
-    GlyphPtr template;
-
-    /* XXX: Should handle out-of-memory here */
-    template = AllocateGlyph (gi, format);
-    memcpy ((CARD8 *) (template + 1), bits,
-	    template->size - sizeof (xGlyphInfo));
+    CARD32 signature = *(CARD32 *) sha1;
 
     gr = FindGlyphRef (&globalGlyphs[format],
-		       hash, TRUE, template);
-
-    xfree (template);
+		       signature, TRUE, sha1);
 
     if (gr->glyph && gr->glyph != DeletedGlyph)
 	return gr->glyph;
@@ -553,6 +546,7 @@ FreeGlyph (GlyphPtr glyph, int format)
 	GlyphRefPtr      gr;
 	int	         i;
 	int	         first;
+	CARD32		 signature;
 
 	first = -1;
 	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
@@ -563,8 +557,9 @@ FreeGlyph (GlyphPtr glyph, int format)
 		first = i;
 	    }
 
-	gr = FindGlyphRef (&globalGlyphs[format],
-			   HashGlyph (glyph), TRUE, glyph);
+	signature = *(CARD32 *) glyph->sha1;
+	gr = FindGlyphRef (&globalGlyphs[format], signature,
+			   TRUE, glyph->sha1);
 	if (gr - globalGlyphs[format].table != first)
 	    DuplicateRef (glyph, "Found wrong one");
 	if (gr->glyph && gr->glyph != DeletedGlyph)
@@ -591,12 +586,13 @@ void
 AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
 {
     GlyphRefPtr	    gr;
-    CARD32	    hash;
+    CARD32	    signature;
 
     CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
     /* Locate existing matching glyph */
-    hash = HashGlyph (glyph);
-    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    signature = *(CARD32 *) glyph->sha1;
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature,
+		       TRUE, glyph->sha1);
     if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph)
     {
 	PictureScreenPtr ps;
@@ -616,7 +612,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
     else if (gr->glyph != glyph)
     {
 	gr->glyph = glyph;
-	gr->signature = hash;
+	gr->signature = signature;
 	globalGlyphs[glyphSet->fdepth].tableEntries++;
     }
     
@@ -753,7 +749,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
 	    if (glyph && glyph != DeletedGlyph)
 	    {
 		s = hash->table[i].signature;
-		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr = FindGlyphRef (&newHash, s, global, glyph->sha1);
 		gr->signature = s;
 		gr->glyph = glyph;
 		++newHash.tableEntries;
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 37462f7..d47dfec 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -39,10 +39,11 @@
 #define GlyphFormatNum	5
 
 typedef struct _Glyph {
-    CARD32	refcnt;
-    DevUnion	*devPrivates;
-    CARD32	size;	/* info + bitmap */
-    xGlyphInfo	info;
+    CARD32	    refcnt;
+    DevUnion	    *devPrivates;
+    unsigned char   sha1[20];
+    CARD32	    size; /* info + bitmap */
+    xGlyphInfo	    info;
     /* bits follow */
 } GlyphRec, *GlyphPtr;
 
@@ -127,19 +128,19 @@ GlyphHashSetPtr
 FindGlyphHashSet (CARD32 filled);
 
 GlyphRefPtr
-FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+FindGlyphRef (GlyphHashPtr	hash,
+	      CARD32		signature,
+	      Bool		match,
+	      unsigned char	sha1[20]);
 
 GlyphPtr
-FindGlyphByHash (CARD32	    hash,
-		 xGlyphInfo *gi,
-		 CARD8	    *bits,
-		 int	    format);
-
-CARD32
-HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size);
+FindGlyphByHash (unsigned char sha1[20], int format);
 
-CARD32
-HashGlyph (GlyphPtr glyph);
+int
+HashGlyph (xGlyphInfo    *gi,
+	   CARD8	 *bits,
+	   unsigned long size,
+	   unsigned char sha1[20]);
 
 void
 FreeGlyph (GlyphPtr glyph, int format);
diff --git a/render/render.c b/render/render.c
index 831c984..c7a6dcb 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1080,10 +1080,10 @@ ProcRenderFreeGlyphSet (ClientPtr client)
 }
 
 typedef struct _GlyphNew {
-    Glyph	id;
-    GlyphPtr    glyph;
-    Bool	found;
-    CARD32	hash;
+    Glyph	    id;
+    GlyphPtr        glyph;
+    Bool	    found;
+    unsigned char   sha1[20];
 } GlyphNewRec, *GlyphNewPtr;
 
 static int
@@ -1143,10 +1143,11 @@ ProcRenderAddGlyphs (ClientPtr client)
 	if (remain < size)
 	    break;
 
-	glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size);
+	err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
+	if (err)
+	    goto bail;
 
-	glyph_new->glyph = FindGlyphByHash (glyph_new->hash,
-					    &gi[i], bits,
+	glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
 					    glyphSet->fdepth);
 
 	if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
@@ -1164,6 +1165,7 @@ ProcRenderAddGlyphs (ClientPtr client)
 	    }
 
 	    memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size);
+	    memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
 	}
 
 	glyph_new->id = gids[i];
commit 516b96387b0e57b524a37a96da22dbeeeb041712
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 30 17:31:47 2007 -0700

    ProcRenderAddGlyphs: Avoid allocating a glyph just to find it cached
    
    This is a cleanup without any real savings (yet). Previously, the
    implementation would allocate a new glyph, then (often) find it in
    the cache, and immediately discard the allocated object. This
    re-organization first uses a new FindGlyphByHash function and only
    allocates the glyph if nothing is found.
    
    This isn't a real savings yet, since FindGlyphByHash currently still
    does a temporary glyph allocation, but this is expected to be replaced
    immediately as we switch to an alternate hashing mechanism (SHA1).

diff --git a/render/glyph.c b/render/glyph.c
index 53c00b3..1204c3b 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -490,6 +490,31 @@ HashGlyph (GlyphPtr glyph)
 				 glyph->size - sizeof (xGlyphInfo));
 }
 
+GlyphPtr
+FindGlyphByHash (CARD32	    hash,
+		 xGlyphInfo *gi,
+		 CARD8	    *bits,
+		 int	    format)
+{
+    GlyphRefPtr gr;
+    GlyphPtr template;
+
+    /* XXX: Should handle out-of-memory here */
+    template = AllocateGlyph (gi, format);
+    memcpy ((CARD8 *) (template + 1), bits,
+	    template->size - sizeof (xGlyphInfo));
+
+    gr = FindGlyphRef (&globalGlyphs[format],
+		       hash, TRUE, template);
+
+    xfree (template);
+
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	return gr->glyph;
+    else
+	return NULL;
+}
+
 #ifdef CHECK_DUPLICATES
 void
 DuplicateRef (GlyphPtr glyph, char *where)
@@ -572,7 +597,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
     /* Locate existing matching glyph */
     hash = HashGlyph (glyph);
     gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
-    if (gr->glyph && gr->glyph != DeletedGlyph)
+    if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph)
     {
 	PictureScreenPtr ps;
 	int              i;
@@ -588,7 +613,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
 	xfree (glyph);
 	glyph = gr->glyph;
     }
-    else
+    else if (gr->glyph != glyph)
     {
 	gr->glyph = glyph;
 	gr->signature = hash;
diff --git a/render/glyphstr.h b/render/glyphstr.h
index b941dab..37462f7 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -129,6 +129,12 @@ FindGlyphHashSet (CARD32 filled);
 GlyphRefPtr
 FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
 
+GlyphPtr
+FindGlyphByHash (CARD32	    hash,
+		 xGlyphInfo *gi,
+		 CARD8	    *bits,
+		 int	    format);
+
 CARD32
 HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size);
 
diff --git a/render/render.c b/render/render.c
index 10a5b80..831c984 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1082,6 +1082,8 @@ ProcRenderFreeGlyphSet (ClientPtr client)
 typedef struct _GlyphNew {
     Glyph	id;
     GlyphPtr    glyph;
+    Bool	found;
+    CARD32	hash;
 } GlyphNewRec, *GlyphNewPtr;
 
 static int
@@ -1090,8 +1092,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     GlyphSetPtr     glyphSet;
     REQUEST(xRenderAddGlyphsReq);
     GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
-    GlyphNewPtr	    glyphsBase, glyphs;
-    GlyphPtr	    glyph;
+    GlyphNewPtr	    glyphsBase, glyphs, glyph_new;
     int		    remain, nglyphs;
     CARD32	    *gids;
     xGlyphInfo	    *gi;
@@ -1115,11 +1116,13 @@ ProcRenderAddGlyphs (ClientPtr client)
     if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
 	    return BadAlloc;
 
-    if (nglyphs <= NLOCALGLYPH)
+    if (nglyphs <= NLOCALGLYPH) {
+	memset (glyphsLocal, 0, sizeof (glyphsLocal));
 	glyphsBase = glyphsLocal;
+    }
     else
     {
-	glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+	glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec));
 	if (!glyphsBase)
 	    return BadAlloc;
     }
@@ -1134,26 +1137,41 @@ ProcRenderAddGlyphs (ClientPtr client)
     remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
     for (i = 0; i < nglyphs; i++)
     {
-	glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
-	if (!glyph)
-	{
-	    err = BadAlloc;
-	    goto bail;
-	}
-	
-	glyphs->glyph = glyph;
-	glyphs->id = gids[i];	
-	
-	size = glyph->size - sizeof (xGlyphInfo);
+	glyph_new = &glyphs[i];
+	size = gi[i].height * PixmapBytePad (gi[i].width,
+					     glyphSet->format->depth);
 	if (remain < size)
 	    break;
-	memcpy ((CARD8 *) (glyph + 1), bits, size);
+
+	glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size);
+
+	glyph_new->glyph = FindGlyphByHash (glyph_new->hash,
+					    &gi[i], bits,
+					    glyphSet->fdepth);
+
+	if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
+	{
+	    glyph_new->found = TRUE;
+	}
+	else
+	{
+	    glyph_new->found = FALSE;
+	    glyph_new->glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
+	    if (! glyph_new->glyph)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+
+	    memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size);
+	}
+
+	glyph_new->id = gids[i];
 	
 	if (size & 3)
 	    size += 4 - (size & 3);
 	bits += size;
 	remain -= size;
-	glyphs++;
     }
     if (remain || i < nglyphs)
     {
@@ -1165,7 +1183,6 @@ ProcRenderAddGlyphs (ClientPtr client)
 	err = BadAlloc;
 	goto bail;
     }
-    glyphs = glyphsBase;
     for (i = 0; i < nglyphs; i++)
 	AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
 
@@ -1173,11 +1190,9 @@ ProcRenderAddGlyphs (ClientPtr client)
 	Xfree (glyphsBase);
     return client->noClientException;
 bail:
-    while (glyphs != glyphsBase)
-    {
-	--glyphs;
-	xfree (glyphs->glyph);
-    }
+    for (i = 0; i < nglyphs; i++)
+	if (glyphs[i].glyph && ! glyphs[i].found)
+	    xfree (glyphs[i].glyph);
     if (glyphsBase != glyphsLocal)
 	Xfree (glyphsBase);
     return err;
commit 4c6abe1c7c8abcf203572bbf86b21d97ea4e756f
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 30 21:43:20 2007 -0700

    Split HashGlyph functionality out into HashGlyphInfoAndBits
    
    This is in preparation for a future change that will take advantage
    of being able to compute a hash for a separate xGlyphInfo and chunk
    of bits without a combined Glyph object.

diff --git a/render/glyph.c b/render/glyph.c
index 583a52b..53c00b3 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -461,18 +461,35 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
 }
 
 CARD32
-HashGlyph (GlyphPtr glyph)
+HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size)
 {
-    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  *bits;
     CARD32  hash;
-    int	    n = glyph->size / sizeof (CARD32);
+    int	    n;
 
     hash = 0;
+
+    bits = (CARD32 *) gi;
+    n = sizeof (xGlyphInfo) / sizeof (CARD32);
+    while (n--)
+	hash ^= *bits++;
+
+    bits = (CARD32 *) data;
+    n = size / sizeof (CARD32);
     while (n--)
 	hash ^= *bits++;
+
     return hash;
 }
 
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    return HashGlyphInfoAndBits (&glyph->info,
+				 (CARD8 *) (&glyph->info + 1),
+				 glyph->size - sizeof (xGlyphInfo));
+}
+
 #ifdef CHECK_DUPLICATES
 void
 DuplicateRef (GlyphPtr glyph, char *where)
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 22150de..b941dab 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -130,6 +130,9 @@ GlyphRefPtr
 FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
 
 CARD32
+HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size);
+
+CARD32
 HashGlyph (GlyphPtr glyph);
 
 void
commit 363d764ea32b938f3dff35df7cf3370363c04d5c
Author: Carl Worth <cworth at cworth.org>
Date:   Mon Jul 30 15:10:11 2007 -0700

    ProcRenderAddGlyphs: Take advantage of the for loops to simplify the code a bit

diff --git a/render/render.c b/render/render.c
index d311fb3..10a5b80 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1134,7 +1134,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
     for (i = 0; i < nglyphs; i++)
     {
-	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
 	if (!glyph)
 	{
 	    err = BadAlloc;
@@ -1142,7 +1142,7 @@ ProcRenderAddGlyphs (ClientPtr client)
 	}
 	
 	glyphs->glyph = glyph;
-	glyphs->id = *gids;	
+	glyphs->id = gids[i];	
 	
 	size = glyph->size - sizeof (xGlyphInfo);
 	if (remain < size)
@@ -1153,8 +1153,6 @@ ProcRenderAddGlyphs (ClientPtr client)
 	    size += 4 - (size & 3);
 	bits += size;
 	remain -= size;
-	gi++;
-	gids++;
 	glyphs++;
     }
     if (remain || i < nglyphs)
@@ -1168,10 +1166,8 @@ ProcRenderAddGlyphs (ClientPtr client)
 	goto bail;
     }
     glyphs = glyphsBase;
-    for (i = 0; i < nglyphs; i++) {
-	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
-	glyphs++;
-    }
+    for (i = 0; i < nglyphs; i++)
+	AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id);
 
     if (glyphsBase != glyphsLocal)
 	Xfree (glyphsBase);
commit dc8a528cd6b9a4da3e60fa31428c37f5b34a897f
Author: Carl Worth <cworth at cworth.org>
Date:   Wed Jul 25 14:57:13 2007 -0700

    ProcRenderAddGlyphs: Convert while loops to for loops where more natural

diff --git a/render/render.c b/render/render.c
index caaa278..d311fb3 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1098,6 +1098,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     CARD8	    *bits;
     int		    size;
     int		    err = BadAlloc;
+    int		    i;
 
     REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
     glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
@@ -1131,7 +1132,7 @@ ProcRenderAddGlyphs (ClientPtr client)
     gi = (xGlyphInfo *) (gids + nglyphs);
     bits = (CARD8 *) (gi + nglyphs);
     remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
-    while (remain >= 0 && nglyphs)
+    for (i = 0; i < nglyphs; i++)
     {
 	glyph = AllocateGlyph (gi, glyphSet->fdepth);
 	if (!glyph)
@@ -1155,21 +1156,19 @@ ProcRenderAddGlyphs (ClientPtr client)
 	gi++;
 	gids++;
 	glyphs++;
-	nglyphs--;
     }
-    if (nglyphs || remain)
+    if (remain || i < nglyphs)
     {
 	err = BadLength;
 	goto bail;
     }
-    nglyphs = stuff->nglyphs;
     if (!ResizeGlyphSet (glyphSet, nglyphs))
     {
 	err = BadAlloc;
 	goto bail;
     }
     glyphs = glyphsBase;
-    while (nglyphs--) {
+    for (i = 0; i < nglyphs; i++) {
 	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
 	glyphs++;
     }


More information about the xorg-commit mailing list