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%.
This commit is contained in:
Carl Worth 2007-08-02 22:48:32 -07:00
parent a2af34d5a8
commit 0a71e1542a
5 changed files with 27 additions and 49 deletions

View File

@ -896,7 +896,6 @@ exaGlyphs (CARD8 op,
GlyphPtr *glyphs) GlyphPtr *glyphs)
{ {
ExaScreenPriv (pDst->pDrawable->pScreen); ExaScreenPriv (pDst->pDrawable->pScreen);
PixmapPtr pPixmap = NULL;
PicturePtr pPicture; PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL; PixmapPtr pMaskPixmap = NULL;
PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable); PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
@ -1031,18 +1030,8 @@ exaGlyphs (CARD8 op,
(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
goto nextglyph; goto nextglyph;
/* The glyph already has a pixmap waiting for us to use. */ /* The glyph already has a Picture ready for us to use. */
pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; pPicture = GlyphPicture (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;
ValidatePicture(pPicture); ValidatePicture(pPicture);
if (maskFormat) if (maskFormat)
@ -1063,7 +1052,6 @@ exaGlyphs (CARD8 op,
exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width, exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
y1 + glyph->info.height); y1 + glyph->info.height);
} }
FreePicture ((pointer) pPicture, 0);
nextglyph: nextglyph:
x += glyph->info.xOff; x += glyph->info.xOff;

View File

@ -573,7 +573,7 @@ FreeGlyph (GlyphPtr glyph, int format)
{ {
ScreenPtr pScreen = screenInfo.screens[i]; ScreenPtr pScreen = screenInfo.screens[i];
(pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]); FreePicture ((pointer) GlyphPicture (glyph)[i], 0);
ps = GetPictureScreenIfSet (pScreen); ps = GetPictureScreenIfSet (pScreen);
if (ps) if (ps)
@ -669,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
GlyphPtr glyph; GlyphPtr glyph;
int i; int i;
size = screenInfo.numScreens * sizeof (PixmapPtr); size = screenInfo.numScreens * sizeof (PicturePtr);
glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
if (!glyph) if (!glyph)
return 0; return 0;
@ -689,21 +689,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
for (i = 0; i < screenInfo.numScreens; i++) for (i = 0; i < screenInfo.numScreens; i++)
{ {
ScreenPtr pScreen = screenInfo.screens[i]; ps = GetPictureScreenIfSet (screenInfo.screens[i]);
GlyphPixmap (glyph)[i] = (pScreen->CreatePixmap) (pScreen, if (ps)
gi->width, gi->height, {
glyphDepths[fdepth]); if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph))
if (! GlyphPixmap (glyph)[i]) goto bail;
goto bail;
ps = GetPictureScreenIfSet (pScreen);
if (! ps)
continue;
if (!(*ps->RealizeGlyph) (pScreen, glyph)) {
(pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]);
goto bail;
} }
} }

View File

@ -47,7 +47,7 @@ typedef struct _Glyph {
/* per-screen pixmaps follow */ /* per-screen pixmaps follow */
} GlyphRec, *GlyphPtr; } GlyphRec, *GlyphPtr;
#define GlyphPixmap(glyph) ((PixmapPtr *) ((glyph) + 1)) #define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1))
typedef struct _GlyphRef { typedef struct _GlyphRef {
CARD32 signature; CARD32 signature;

View File

@ -174,13 +174,7 @@ miGlyphs (CARD8 op,
while (n--) while (n--)
{ {
glyph = *glyphs++; glyph = *glyphs++;
pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; pPicture = GlyphPicture (glyph)[pScreen->myNum];
component_alpha = NeedsComponent(list->format->format);
pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (!pPicture)
return;
if (maskFormat) if (maskFormat)
{ {
@ -209,7 +203,6 @@ miGlyphs (CARD8 op,
glyph->info.width, glyph->info.width,
glyph->info.height); glyph->info.height);
} }
FreePicture ((pointer) pPicture, 0);
x += glyph->info.xOff; x += glyph->info.xOff;
y += glyph->info.yOff; y += glyph->info.yOff;

View File

@ -1086,6 +1086,8 @@ typedef struct _GlyphNew {
unsigned char sha1[20]; unsigned char sha1[20];
} GlyphNewRec, *GlyphNewPtr; } GlyphNewRec, *GlyphNewPtr;
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
static int static int
ProcRenderAddGlyphs (ClientPtr client) ProcRenderAddGlyphs (ClientPtr client)
{ {
@ -1102,6 +1104,7 @@ ProcRenderAddGlyphs (ClientPtr client)
int i, screen; int i, screen;
PicturePtr pSrc = NULL, pDst = NULL; PicturePtr pSrc = NULL, pDst = NULL;
PixmapPtr pSrcPix = NULL, pDstPix = NULL; PixmapPtr pSrcPix = NULL, pDstPix = NULL;
CARD32 component_alpha;
REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
@ -1118,6 +1121,8 @@ ProcRenderAddGlyphs (ClientPtr client)
if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
return BadAlloc; return BadAlloc;
component_alpha = NeedsComponent (glyphSet->format->format);
if (nglyphs <= NLOCALGLYPH) { if (nglyphs <= NLOCALGLYPH) {
memset (glyphsLocal, 0, sizeof (glyphsLocal)); memset (glyphsLocal, 0, sizeof (glyphsLocal));
glyphsBase = glyphsLocal; glyphsBase = glyphsLocal;
@ -1158,9 +1163,11 @@ ProcRenderAddGlyphs (ClientPtr client)
} }
else else
{ {
GlyphPtr glyph;
glyph_new->found = FALSE; glyph_new->found = FALSE;
glyph_new->glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth);
if (! glyph_new->glyph) if (! glyph)
{ {
err = BadAlloc; err = BadAlloc;
goto bail; goto bail;
@ -1194,11 +1201,14 @@ ProcRenderAddGlyphs (ClientPtr client)
goto bail; goto bail;
} }
pDstPix = GlyphPixmap (glyph_new->glyph)[screen]; pDstPix = (pScreen->CreatePixmap) (pScreen,
width, height, depth);
pDst = CreatePicture (0, &pDstPix->drawable, GlyphPicture (glyph)[screen] = pDst =
glyphSet->format, 0, NULL, CreatePicture (0, &pDstPix->drawable,
serverClient, &error); glyphSet->format,
CPComponentAlpha, &component_alpha,
serverClient, &error);
if (! pDst) if (! pDst)
{ {
err = BadAlloc; err = BadAlloc;
@ -1216,8 +1226,6 @@ ProcRenderAddGlyphs (ClientPtr client)
FreePicture ((pointer) pSrc, 0); FreePicture ((pointer) pSrc, 0);
pSrc = NULL; pSrc = NULL;
FreePicture ((pointer) pDst, 0);
pDst = NULL;
FreeScratchPixmapHeader (pSrcPix); FreeScratchPixmapHeader (pSrcPix);
pSrcPix = NULL; pSrcPix = NULL;
} }
@ -1251,8 +1259,6 @@ ProcRenderAddGlyphs (ClientPtr client)
bail: bail:
if (pSrc) if (pSrc)
FreePicture ((pointer) pSrc, 0); FreePicture ((pointer) pSrc, 0);
if (pDst)
FreePicture ((pointer) pDst, 0);
if (pSrcPix) if (pSrcPix)
FreeScratchPixmapHeader (pSrcPix); FreeScratchPixmapHeader (pSrcPix);
for (i = 0; i < nglyphs; i++) for (i = 0; i < nglyphs; i++)