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:
parent
a2af34d5a8
commit
0a71e1542a
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++)
|
||||
|
|
Loading…
Reference in New Issue
Block a user