diff options
Diffstat (limited to 'xorg-server/exa/exa_glyphs.c')
-rw-r--r-- | xorg-server/exa/exa_glyphs.c | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/xorg-server/exa/exa_glyphs.c b/xorg-server/exa/exa_glyphs.c index bf097c32f..5a370047e 100644 --- a/xorg-server/exa/exa_glyphs.c +++ b/xorg-server/exa/exa_glyphs.c @@ -62,15 +62,10 @@ */ #define CACHE_PICTURE_WIDTH 1024 -/* Maximum number of glyphs we buffer on the stack before flushing - * rendering to the mask or destination surface. - */ -#define GLYPH_BUFFER_SIZE 256 - typedef struct { PicturePtr mask; - ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE]; int count; + ExaCompositeRectRec rects[0]; } ExaGlyphBuffer, *ExaGlyphBufferPtr; typedef enum { @@ -364,7 +359,8 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, static void exaGlyphCacheUploadGlyph(ScreenPtr pScreen, ExaGlyphCachePtr cache, - int pos, + int x, + int y, GlyphPtr pGlyph) { ExaScreenPriv(pScreen); @@ -399,10 +395,10 @@ exaGlyphCacheUploadGlyph(ScreenPtr pScreen, if (!exaPixmapIsOffscreen(pCachePixmap)) goto composite; - /* CACHE_{X,Y} are in pixmap coordinates, no need for cache{X,Y}off */ + /* x,y are in pixmap coordinates, no need for cache{X,Y}off */ if (pExaScr->info->UploadToScreen(pCachePixmap, - CACHE_X(pos), - CACHE_Y(pos), + x, + y, pGlyph->info.width, pGlyph->info.height, (char *)pExaPixmap->sys_ptr, @@ -416,18 +412,18 @@ composite: cache->picture, 0, 0, 0, 0, - CACHE_X(pos), - CACHE_Y(pos), + x, + y, pGlyph->info.width, pGlyph->info.height); damage: /* The cache pixmap isn't a window, so no need to offset coordinates. */ exaPixmapDirty (pCachePixmap, - CACHE_X(pos), - CACHE_Y(pos), - CACHE_X(pos) + cache->glyphWidth, - CACHE_Y(pos) + cache->glyphHeight); + x, + y, + x + cache->glyphWidth, + y + cache->glyphHeight); } static ExaGlyphCacheResult @@ -446,6 +442,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, { ExaCompositeRectPtr rect; int pos; + int x, y; if (buffer->mask && buffer->mask != cache->picture) return ExaGlyphNeedFlush; @@ -462,10 +459,14 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, pos = exaGlyphCacheHashLookup(cache, pGlyph); if (pos != -1) { DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); + x = CACHE_X(pos); + y = CACHE_Y(pos); } else { if (cache->glyphCount < cache->size) { /* Space remaining; we fill from the start */ pos = cache->glyphCount; + x = CACHE_X(pos); + y = CACHE_Y(pos); cache->glyphCount++; DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); @@ -477,14 +478,12 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, * the cache */ pos = cache->evictionPosition; + x = CACHE_X(pos); + y = CACHE_Y(pos); DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); if (buffer->count) { - int x, y; int i; - x = CACHE_X(pos); - y = CACHE_Y(pos); - for (i = 0; i < buffer->count; i++) { if (pSrc ? (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) : @@ -503,7 +502,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, cache->evictionPosition = rand() % cache->size; } - exaGlyphCacheUploadGlyph(pScreen, cache, pos, pGlyph); + exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph); } buffer->mask = cache->picture; @@ -514,13 +513,13 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, { rect->xSrc = xSrc; rect->ySrc = ySrc; - rect->xMask = CACHE_X(pos); - rect->yMask = CACHE_Y(pos); + rect->xMask = x; + rect->yMask = y; } else { - rect->xSrc = CACHE_X(pos); - rect->ySrc = CACHE_Y(pos); + rect->xSrc = x; + rect->ySrc = y; rect->xMask = 0; rect->yMask = 0; } @@ -553,16 +552,13 @@ exaBufferGlyph(ScreenPtr pScreen, INT16 yDst) { ExaScreenPriv(pScreen); - unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format; + PicturePtr mask = GlyphPicture(pGlyph)[pScreen->myNum]; + unsigned int format = mask->format; int width = pGlyph->info.width; int height = pGlyph->info.height; ExaCompositeRectPtr rect; - PicturePtr mask; int i; - if (buffer->count == GLYPH_BUFFER_SIZE) - return ExaGlyphNeedFlush; - if (PICT_FORMAT_BPP(format) == 1) format = PICT_a8; @@ -593,7 +589,6 @@ exaBufferGlyph(ScreenPtr pScreen, /* Couldn't find the glyph in the cache, use the glyph picture directly */ - mask = GlyphPicture(pGlyph)[pScreen->myNum]; if (buffer->mask && buffer->mask != mask) return ExaGlyphNeedFlush; @@ -707,12 +702,18 @@ exaGlyphs (CARD8 op, int width = 0, height = 0; int x, y; int first_xOff = list->xOff, first_yOff = list->yOff; - int n; + int i, n; GlyphPtr glyph; int error; BoxRec extents = {0, 0, 0, 0}; CARD32 component_alpha; - ExaGlyphBuffer buffer; + ExaGlyphBufferPtr buffer; + + for (i = 0, n = 0; i < nlist; i++) + n += list[i].len; + buffer = alloca(sizeof(ExaGlyphBuffer) + n * sizeof(ExaCompositeRectRec)); + if (!buffer) + return; if (maskFormat) { @@ -792,8 +793,8 @@ exaGlyphs (CARD8 op, x = 0; y = 0; } - buffer.count = 0; - buffer.mask = NULL; + buffer->count = 0; + buffer->mask = NULL; while (nlist--) { x += list->xOff; @@ -808,23 +809,23 @@ exaGlyphs (CARD8 op, /* pGlyph->info.{x,y} compensate for empty space in the glyph. */ if (maskFormat) { - if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, + if (exaBufferGlyph(pScreen, buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { - exaGlyphsToMask(pMask, &buffer); - exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask, + exaGlyphsToMask(pMask, buffer); + exaBufferGlyph(pScreen, buffer, glyph, NULL, pMask, 0, 0, 0, 0, x - glyph->info.x, y - glyph->info.y); } } else { - if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, + if (exaBufferGlyph(pScreen, buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y) == ExaGlyphNeedFlush) { - exaGlyphsToDst(pSrc, pDst, &buffer); - exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst, + exaGlyphsToDst(pSrc, pDst, buffer); + exaBufferGlyph(pScreen, buffer, glyph, pSrc, pDst, xSrc + (x - glyph->info.x) - first_xOff, ySrc + (y - glyph->info.y) - first_yOff, 0, 0, x - glyph->info.x, y - glyph->info.y); } @@ -837,11 +838,11 @@ exaGlyphs (CARD8 op, list++; } - if (buffer.count) { + if (buffer->count) { if (maskFormat) - exaGlyphsToMask(pMask, &buffer); + exaGlyphsToMask(pMask, buffer); else - exaGlyphsToDst(pSrc, pDst, &buffer); + exaGlyphsToDst(pSrc, pDst, buffer); } if (maskFormat) |