xf86-video-intel: 2 commits - src/sna/sna_accel.c uxa/uxa-glyphs.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Oct 30 10:51:35 PDT 2011


 src/sna/sna_accel.c |  195 ++++++++++++++++++++++++++++------------------------
 uxa/uxa-glyphs.c    |   17 ++++
 2 files changed, 121 insertions(+), 91 deletions(-)

New commits:
commit 5c45622b889ba66b6476241601e1458d219c45ba
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Oct 30 17:49:19 2011 +0000

    uxa/glyphs: Fallback rather than fail to render with a non-solid Source
    
    Reported-by: Uli Schlachter <psychon at znc.in>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31819
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index 7b2edea..6c9ea0d 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -1033,6 +1033,19 @@ next_glyph:
 	return 0;
 }
 
+static Bool
+is_solid(PicturePtr picture)
+{
+	if (picture->pSourcePict) {
+		SourcePict *source = picture->pSourcePict;
+		return source->type == SourcePictTypeSolidFill;
+	} else {
+		return (picture->repeat &&
+			picture->pDrawable->width  == 1 &&
+			picture->pDrawable->height == 1);
+	}
+}
+
 void
 uxa_glyphs(CARD8 op,
 	   PicturePtr pSrc,
@@ -1053,7 +1066,9 @@ uxa_glyphs(CARD8 op,
 	    uxa_screen->swappedOut ||
 	    uxa_screen->force_fallback ||
 	    !uxa_drawable_is_offscreen(pDst->pDrawable) ||
-	    pDst->alphaMap || pSrc->alphaMap) {
+	    pDst->alphaMap || pSrc->alphaMap ||
+	    /* XXX we fail to handle (rare) non-solid sources correctly. */
+	    !is_solid(pSrc)) {
 fallback:
 	    uxa_check_glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
 	    return;
commit e6eb803cb44b01e300fb4b08304227a430912beb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Oct 30 17:44:26 2011 +0000

    sna: Loop over all clip rects for glyph blt rather than fallback
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index eb8295c..6f0275b 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;


More information about the xorg-commit mailing list