From 0a71e1542a07abc5e32501973a7cf6de3f641317 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 2 Aug 2007 22:48:32 -0700 Subject: [PATCH] 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%. --- exa/exa_render.c | 16 ++-------------- render/glyph.c | 23 +++++++---------------- render/glyphstr.h | 2 +- render/miglyph.c | 9 +-------- render/render.c | 26 ++++++++++++++++---------- 5 files changed, 27 insertions(+), 49 deletions(-) diff --git a/exa/exa_render.c b/exa/exa_render.c index 332683949..24411dda7 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 7fd3705df..975c62b77 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]; + ps = GetPictureScreenIfSet (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; + if (ps) + { + if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) + goto bail; } } diff --git a/render/glyphstr.h b/render/glyphstr.h index 4f8746003..c6ab5aa11 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 2aa94bd09..a52ea49d6 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 4bad379f6..300b78488 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++)