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