aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/exa/exa_glyphs.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/exa/exa_glyphs.c')
-rw-r--r--xorg-server/exa/exa_glyphs.c89
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)