diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-30 17:44:26 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-10-30 17:44:26 +0000 |
commit | e6eb803cb44b01e300fb4b08304227a430912beb (patch) | |
tree | 760dd59cafa784bec94bd11d7cce1933db067714 | |
parent | 1eefb75c91fb769551b485f1b2c6b59023c69906 (diff) |
sna: Loop over all clip rects for glyph blt rather than fallback
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna_accel.c | 195 |
1 files changed, 105 insertions, 90 deletions
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c index eb8295c4..6f0275b8 100644 --- a/src/sna/sna_accel.c +++ b/src/sna/sna_accel.c @@ -5375,8 +5375,8 @@ static uint8_t blt_depth(int depth) static bool sna_glyph_blt(DrawablePtr drawable, GCPtr gc, - int x, int y, unsigned int n, - CharInfoPtr *info, pointer base, + int _x, int _y, unsigned int _n, + CharInfoPtr *_info, pointer _base, bool transparent, const BoxRec *extents) { @@ -5384,6 +5384,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, PixmapPtr pixmap = get_drawable_pixmap(drawable); struct sna_pixmap *priv = sna_pixmap(pixmap); struct sna_damage **damage; + const BoxRec *last_extents; uint32_t *b; int16_t dx, dy; @@ -5419,25 +5420,16 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, if (!RegionNotEmpty(&clip)) return true; - /* XXX loop over clips using SETUP_CLIP? */ - if (clip.data != NULL) { - DBG(("%s -- fallback too many clip rects [%d]\n", - __FUNCTION__, REGION_NUM_RECTS(&clip))); - RegionUninit(&clip); - return false; - } - damage = priv->gpu_only ? NULL : reduce_damage(drawable, &priv->gpu_damage, extents), get_drawable_deltas(drawable, pixmap, &dx, &dy); - x += drawable->x + dx; - y += drawable->y + dy; + _x += drawable->x + dx; + _y += drawable->y + dy; - clip.extents.x1 += dx; - clip.extents.x2 += dx; - clip.extents.y1 += dy; - clip.extents.y2 += dy; + RegionTranslate(&clip, dx, dy); + extents = REGION_RECTS(&clip); + last_extents = extents + REGION_NUM_RECTS(&clip); kgem_set_mode(&sna->kgem, KGEM_BLT); if (!kgem_check_batch(&sna->kgem, 16) || @@ -5455,8 +5447,8 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, b[1] >>= 2; } b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; - b[2] = clip.extents.y1 << 16 | clip.extents.x1; - b[3] = clip.extents.y2 << 16 | clip.extents.x2; + b[2] = extents->y1 << 16 | extents->x1; + b[3] = extents->y2 << 16 | extents->x2; b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, priv->gpu_bo, I915_GEM_DOMAIN_RENDER << 16 | @@ -5468,87 +5460,110 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc, b[7] = 0; sna->kgem.nbatch += 8; - while (n--) { - CharInfoPtr c = *info++; - uint8_t *glyph = FONTGLYPHBITS(base, c); - int w = GLYPHWIDTHPIXELS(c); - int h = GLYPHHEIGHTPIXELS(c); - int stride = GLYPHWIDTHBYTESPADDED(c); - int w8 = (w + 7) >> 3; - int x1, y1, len, i; - uint8_t *byte; + do { + CharInfoPtr *info = _info; + int x = _x, y = _y, n = _n; - if (w == 0 || h == 0) - goto skip; + do { + CharInfoPtr c = *info++; + uint8_t *glyph = FONTGLYPHBITS(base, c); + int w = GLYPHWIDTHPIXELS(c); + int h = GLYPHHEIGHTPIXELS(c); + int stride = GLYPHWIDTHBYTESPADDED(c); + int w8 = (w + 7) >> 3; + int x1, y1, len, i; + uint8_t *byte; + + if (w == 0 || h == 0) + goto skip; + + len = (w8 * h + 7) >> 3 << 1; + DBG(("%s glyph: (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__, + x,y, w, w8, h, len)); + + x1 = x + c->metrics.leftSideBearing; + y1 = y - c->metrics.ascent; + + if (x1 >= extents->x2 || y1 >= extents->y2) + goto skip; + if (x1 + w <= extents->x1 || y1 + h <= extents->y1) + goto skip; + + if (!kgem_check_batch(&sna->kgem, 3+len)) { + _kgem_submit(&sna->kgem); + _kgem_set_mode(&sna->kgem, KGEM_BLT); + + b = sna->kgem.batch + sna->kgem.nbatch; + b[0] = XY_SETUP_BLT | 1 << 20; + b[1] = priv->gpu_bo->pitch; + if (sna->kgem.gen >= 40) { + if (priv->gpu_bo->tiling) + b[0] |= 1 << 11; + b[1] >>= 2; + } + b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; + b[2] = extents->y1 << 16 | extents->x1; + b[3] = extents->y2 << 16 | extents->x2; + b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, + priv->gpu_bo, + I915_GEM_DOMAIN_RENDER << 16 | + I915_GEM_DOMAIN_RENDER | + KGEM_RELOC_FENCED, + 0); + b[5] = gc->bgPixel; + b[6] = gc->fgPixel; + b[7] = 0; + sna->kgem.nbatch += 8; + } - len = (w8 * h + 7) >> 3 << 1; - DBG(("%s glyph: (%d, %d) x (%d[%d], %d), len=%d\n" ,__FUNCTION__, - x,y, w, w8, h, len)); + b = sna->kgem.batch + sna->kgem.nbatch; + sna->kgem.nbatch += 3 + len; - x1 = x + c->metrics.leftSideBearing; - y1 = y - c->metrics.ascent; + b[0] = XY_TEXT_IMMEDIATE_BLT | (1 + len); + if (priv->gpu_bo->tiling && sna->kgem.gen >= 40) + b[0] |= 1 << 11; + b[1] = (uint16_t)y1 << 16 | (uint16_t)x1; + b[2] = (uint16_t)(y1+h) << 16 | (uint16_t)(x1+w); - if (!kgem_check_batch(&sna->kgem, 3+len)) { - _kgem_submit(&sna->kgem); - _kgem_set_mode(&sna->kgem, KGEM_BLT); + byte = (uint8_t *)&b[3]; + stride -= w8; + do { + i = w8; + do { + *byte++ = byte_reverse(*glyph++); + } while (--i); + glyph += stride; + } while (--h); + while ((byte - (uint8_t *)&b[3]) & 7) + *byte++ = 0; + assert((uint32_t *)byte == sna->kgem.batch + sna->kgem.nbatch); + + if (damage) { + BoxRec r; - b = sna->kgem.batch + sna->kgem.nbatch; - b[0] = XY_SETUP_BLT | 1 << 20; - b[1] = priv->gpu_bo->pitch; - if (sna->kgem.gen >= 40) { - if (priv->gpu_bo->tiling) - b[0] |= 1 << 11; - b[1] >>= 2; + r.x1 = x1; + r.y1 = y1; + r.x2 = x1 + w; + r.y2 = y1 + h; + if (box_intersect(&r, extents)) + sna_damage_add_box(damage, &r); } - b[1] |= 1 << 30 | transparent << 29 | blt_depth(drawable->depth) << 24 | rop << 16; - b[2] = clip.extents.y1 << 16 | clip.extents.x1; - b[3] = clip.extents.y2 << 16 | clip.extents.x2; - b[4] = kgem_add_reloc(&sna->kgem, sna->kgem.nbatch + 4, - priv->gpu_bo, - I915_GEM_DOMAIN_RENDER << 16 | - I915_GEM_DOMAIN_RENDER | - KGEM_RELOC_FENCED, - 0); - b[5] = gc->bgPixel; - b[6] = gc->fgPixel; - b[7] = 0; - sna->kgem.nbatch += 8; - } +skip: + x += c->metrics.characterWidth; + } while (--n); - b = sna->kgem.batch + sna->kgem.nbatch; - b[0] = XY_TEXT_IMMEDIATE_BLT | (1 + len); - if (priv->gpu_bo->tiling && sna->kgem.gen >= 40) - b[0] |= 1 << 11; - b[1] = (uint16_t)y1 << 16 | (uint16_t)x1; - b[2] = (uint16_t)(y1+h) << 16 | (uint16_t)(x1+w); + if (++extents == last_extents) + break; - byte = (uint8_t *)&b[3]; - stride -= w8; - do { - i = w8; - do { - *byte++ = byte_reverse(*glyph++); - } while (--i); - glyph += stride; - } while (--h); - while ((byte - (uint8_t *)&b[3]) & 7) - *byte++ = 0; - sna->kgem.nbatch += 3 + len; - assert((uint32_t *)byte == sna->kgem.batch + sna->kgem.nbatch); - - if (damage) { - BoxRec r; - - r.x1 = x1; - r.y1 = y1; - r.x2 = x1 + w; - r.y2 = y1 + h; - if (box_intersect(&r, &clip.extents)) - sna_damage_add_box(damage, &r); + if (kgem_check_batch(&sna->kgem, 3)) { + b = sna->kgem.batch + sna->kgem.nbatch; + sna->kgem.nbatch += 3; + + b[0] = XY_SETUP_CLIP; + b[1] = extents->y1 << 16 | extents->x1; + b[2] = extents->y2 << 16 | extents->x2; } -skip: - x += c->metrics.characterWidth; - } + } while (1); RegionUninit(&clip); sna->blt_state.fill_bo = 0; |