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)
|
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;
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
Loading…
Reference in New Issue