Merge remote-tracking branch 'sandmann/for-keithp'

This commit is contained in:
Keith Packard 2012-10-26 18:04:34 -07:00
commit 53830281b4
4 changed files with 157 additions and 2 deletions

View File

@ -811,7 +811,7 @@ LIBPCIACCESS="pciaccess >= 0.12.901"
LIBUDEV="libudev >= 143" LIBUDEV="libudev >= 143"
LIBSELINUX="libselinux >= 2.0.86" LIBSELINUX="libselinux >= 2.0.86"
LIBDBUS="dbus-1 >= 1.0" LIBDBUS="dbus-1 >= 1.0"
LIBPIXMAN="pixman-1 >= 0.21.8" LIBPIXMAN="pixman-1 >= 0.27.2"
dnl Pixman is always required, but we separate it out so we can link dnl Pixman is always required, but we separate it out so we can link
dnl specific modules against it dnl specific modules against it

View File

@ -1344,6 +1344,9 @@ extern _X_EXPORT void
extern _X_EXPORT Bool extern _X_EXPORT Bool
fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats); fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats);
extern _X_EXPORT void
fbDestroyGlyphCache(void);
/* /*
* fbpixmap.c * fbpixmap.c
*/ */

View File

@ -70,6 +70,156 @@ fbComposite(CARD8 op,
free_pixman_pict(pDst, dest); free_pixman_pict(pDst, dest);
} }
static pixman_glyph_cache_t *glyphCache;
void
fbDestroyGlyphCache(void)
{
if (glyphCache)
{
pixman_glyph_cache_destroy (glyphCache);
glyphCache = NULL;
}
}
static void
fbUnrealizeGlyph(ScreenPtr pScreen,
GlyphPtr pGlyph)
{
if (glyphCache)
pixman_glyph_cache_remove (glyphCache, pGlyph, NULL);
}
static void
fbGlyphs(CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc, int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
#define N_STACK_GLYPHS 512
ScreenPtr pScreen = pDst->pDrawable->pScreen;
pixman_glyph_t stack_glyphs[N_STACK_GLYPHS];
pixman_glyph_t *pglyphs = stack_glyphs;
pixman_image_t *srcImage, *dstImage;
int srcXoff, srcYoff, dstXoff, dstYoff;
GlyphPtr glyph;
int n_glyphs;
int x, y;
int i, n;
int xDst = list->xOff, yDst = list->yOff;
miCompositeSourceValidate(pSrc);
n_glyphs = 0;
for (i = 0; i < nlist; ++i)
n_glyphs += list[i].len;
if (!glyphCache)
glyphCache = pixman_glyph_cache_create();
pixman_glyph_cache_freeze (glyphCache);
if (n_glyphs > N_STACK_GLYPHS) {
if (!(pglyphs = malloc (n_glyphs * sizeof (pixman_glyph_t))))
goto out;
}
i = 0;
x = y = 0;
while (nlist--) {
x += list->xOff;
y += list->yOff;
n = list->len;
while (n--) {
const void *g;
glyph = *glyphs++;
if (!(g = pixman_glyph_cache_lookup (glyphCache, glyph, NULL))) {
pixman_image_t *glyphImage;
PicturePtr pPicture;
int xoff, yoff;
pPicture = GetGlyphPicture(glyph, pScreen);
if (!pPicture) {
n_glyphs--;
goto next;
}
if (!(glyphImage = image_from_pict(pPicture, FALSE, &xoff, &yoff)))
goto out;
g = pixman_glyph_cache_insert(glyphCache, glyph, NULL,
glyph->info.x,
glyph->info.y,
glyphImage);
free_pixman_pict(pPicture, glyphImage);
if (!g)
goto out;
}
pglyphs[i].x = x;
pglyphs[i].y = y;
pglyphs[i].glyph = g;
i++;
next:
x += glyph->info.xOff;
y += glyph->info.yOff;
}
list++;
}
if (!(srcImage = image_from_pict(pSrc, FALSE, &srcXoff, &srcYoff)))
goto out;
if (!(dstImage = image_from_pict(pDst, TRUE, &dstXoff, &dstYoff)))
goto out_free_src;
if (maskFormat) {
pixman_format_code_t format;
pixman_box32_t extents;
int x, y;
format = maskFormat->format | (maskFormat->depth << 24);
pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
x = extents.x1;
y = extents.y1;
pixman_composite_glyphs(op, srcImage, dstImage, format,
xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
x, y,
x + dstXoff, y + dstYoff,
extents.x2 - extents.x1,
extents.y2 - extents.y1,
glyphCache, n_glyphs, pglyphs);
}
else {
pixman_composite_glyphs_no_mask(op, srcImage, dstImage,
xSrc + srcXoff - xDst, ySrc + srcYoff - yDst,
dstXoff, dstYoff,
glyphCache, n_glyphs, pglyphs);
}
free_pixman_pict(pDst, dstImage);
out_free_src:
free_pixman_pict(pSrc, srcImage);
out:
pixman_glyph_cache_thaw(glyphCache);
if (pglyphs != stack_glyphs)
free(pglyphs);
}
static pixman_image_t * static pixman_image_t *
create_solid_fill_image(PicturePtr pict) create_solid_fill_image(PicturePtr pict)
{ {
@ -357,7 +507,8 @@ fbPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
return FALSE; return FALSE;
ps = GetPictureScreen(pScreen); ps = GetPictureScreen(pScreen);
ps->Composite = fbComposite; ps->Composite = fbComposite;
ps->Glyphs = miGlyphs; ps->Glyphs = fbGlyphs;
ps->UnrealizeGlyph = fbUnrealizeGlyph;
ps->CompositeRects = miCompositeRects; ps->CompositeRects = miCompositeRects;
ps->RasterizeTrapezoid = fbRasterizeTrapezoid; ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
ps->Trapezoids = fbTrapezoids; ps->Trapezoids = fbTrapezoids;

View File

@ -32,6 +32,7 @@ fbCloseScreen(ScreenPtr pScreen)
int d; int d;
DepthPtr depths = pScreen->allowedDepths; DepthPtr depths = pScreen->allowedDepths;
fbDestroyGlyphCache();
for (d = 0; d < pScreen->numDepths; d++) for (d = 0; d < pScreen->numDepths; d++)
free(depths[d].vids); free(depths[d].vids);
free(depths); free(depths);