xf86-video-intel: src/sna/sna_glyphs.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jul 11 05:19:39 PDT 2012


 src/sna/sna_glyphs.c |   62 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 45 insertions(+), 17 deletions(-)

New commits:
commit b5db90aa52f10897ad2d7795df94c0e3d2878aea
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Jul 11 12:52:24 2012 +0100

    sna: Discard the mask for "non-overlapping" glyphs
    
    If we can acheive the same rasterisation results without the mask,
    rendering the glyphs-to-dst is so much faster that it outweighs the cost
    of checking for overlapping glyphs.
    
    The penalty is then for code that correctly declared that it required
    a mask, who now have an extra ~10% overhead in the processing of their
    glyphs.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index 84ee13c..88e1c9e 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1087,9 +1087,15 @@ glyphs_format(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 				extents.y2 = y2;
 				first = FALSE;
 			} else {
-				/* Potential overlap */
-				if (x1 < extents.x2 && x2 > extents.x1 &&
-				    y1 < extents.y2 && y2 > extents.y1) {
+				/* Potential overlap?
+				 * We cheat and ignore the boundary pixels, as
+				 * the likelihood of an actual overlap of
+				 * inkedk pixels being noticeable in the
+				 * boundary is small, yet glyphs frequently
+				 * overlap on the boundaries.
+				 */
+				if (x1 < extents.x2-1 && x2 > extents.x1+1 &&
+				    y1 < extents.y2-1 && y2 > extents.y1+1) {
 					format = NULL;
 					goto out;
 				}
@@ -1112,10 +1118,10 @@ glyphs_format(int nlist, GlyphListPtr list, GlyphPtr * glyphs)
 		 * of the previous boxes and walk those.
 		 */
 		for (j = 0; j < i; j++) {
-			if (extents.x2 < list_extents[j].x1 &&
-			    extents.x1 > list_extents[j].x2 &&
-			    extents.y2 < list_extents[j].y1 &&
-			    extents.y1 > list_extents[j].y2) {
+			if (extents.x1 < list_extents[j].x2-1 &&
+			    extents.x2 > list_extents[j].x1+1 &&
+			    extents.y1 < list_extents[j].y2-1 &&
+			    extents.y2 > list_extents[j].y1+1) {
 				format = NULL;
 				goto out;
 			}
@@ -1354,6 +1360,19 @@ cleanup_region:
 	RegionUninit(&region);
 }
 
+static bool op_is_bounded(uint8_t op)
+{
+	switch (op) {
+	case PictOpOver:
+	case PictOpOutReverse:
+	case PictOpAdd:
+	case PictOpXor:
+		return true;
+	default:
+		return false;
+	}
+}
+
 void
 sna_glyphs(CARD8 op,
 	   PicturePtr src,
@@ -1365,7 +1384,6 @@ sna_glyphs(CARD8 op,
 	PixmapPtr pixmap = get_drawable_pixmap(dst->pDrawable);
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
-	PictFormatPtr _mask;
 
 	DBG(("%s(op=%d, nlist=%d, src=(%d, %d))\n",
 	     __FUNCTION__, op, nlist, src_x, src_y));
@@ -1399,12 +1417,21 @@ sna_glyphs(CARD8 op,
 		goto fallback;
 	}
 
-	_mask = mask;
-	/* XXX discard the mask for non-overlapping glyphs? */
-
-	if (!_mask ||
+	if (!mask ||
 	    (((nlist == 1 && list->len == 1) || op == PictOpAdd) &&
-	     dst->format == (_mask->depth << 24 | _mask->format))) {
+	     dst->format == (mask->depth << 24 | mask->format))) {
+		if (glyphs_to_dst(sna, op,
+				  src, dst,
+				  src_x, src_y,
+				  nlist, list, glyphs))
+			return;
+	}
+
+	/* Try to discard the mask for non-overlapping glyphs */
+	if (mask &&
+	    op_is_bounded(op) &&
+	    dst->pCompositeClip->data == NULL &&
+	    mask == glyphs_format(nlist, list, glyphs)) {
 		if (glyphs_to_dst(sna, op,
 				  src, dst,
 				  src_x, src_y,
@@ -1412,11 +1439,12 @@ sna_glyphs(CARD8 op,
 			return;
 	}
 
-	if (!_mask)
-		_mask = glyphs_format(nlist, list, glyphs);
-	if (_mask) {
+	/* Otherwise see if we can substitute a mask */
+	if (!mask)
+		mask = glyphs_format(nlist, list, glyphs);
+	if (mask) {
 		if (glyphs_via_mask(sna, op,
-				    src, dst, _mask,
+				    src, dst, mask,
 				    src_x, src_y,
 				    nlist, list, glyphs))
 			return;


More information about the xorg-commit mailing list