xf86-video-intel: 2 commits - src/sna/sna_accel.c src/sna/sna_glyphs.c src/sna/sna_render.h

Chris Wilson ickle at kemper.freedesktop.org
Thu May 31 05:22:10 PDT 2012


 src/sna/sna_accel.c  |   10 +---
 src/sna/sna_glyphs.c |  109 ++++++++++++++++++++++++++++++++++++---------------
 src/sna/sna_render.h |    2 
 3 files changed, 84 insertions(+), 37 deletions(-)

New commits:
commit 660c89e9742bac5ce7cbd480e08b4667e37dee8c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 31 13:18:21 2012 +0100

    sna: Use full 16-bit unsigned values for absolute differences
    
    Beware the overflow implicit in:
      adx = x2 >= x1 ? x2 - x1 : x1 - x2;
    when both x2 and x1 may be large signed 16-bit values
    
    Reported-by: Zdenek Kabelac <zdenek.kabelac at gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50532
    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 ee2f69a..cebfc7e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -5881,9 +5881,8 @@ sna_poly_zero_line_blt(DrawablePtr drawable,
 
 		while (--n) {
 			int16_t sdx, sdy;
-			int16_t adx, ady;
-			int16_t e, e1, e2, e3;
-			int16_t length;
+			uint16_t adx, ady, length;
+			int e, e1, e2, e3;
 			int x1 = x2, x;
 			int y1 = y2, y;
 			int oc1 = oc2;
@@ -7080,9 +7079,8 @@ sna_poly_zero_segment_blt(DrawablePtr drawable,
 		const xSegment *s = _s;
 		do {
 			int16_t sdx, sdy;
-			int16_t adx, ady;
-			int16_t e, e1, e2, e3;
-			int16_t length;
+			uint16_t adx, ady, length;
+			int e, e1, e2, e3;
 			int x1, x2;
 			int y1, y2;
 			int oc1, oc2;
commit 035c2953751f58225bd6b1fcb4c1275ccb5526cb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu May 31 09:29:40 2012 +0100

    sna/glyphs: use add(WHITE, glyph, mask) for channel expansion
    
    If the glyph format does not match the mask format we can not simply add
    the two together, but must first perform a channel expansion (or
    contraction) by multiplying the glyph against a WHITE source.
    
    Normally the glyph and the mask are equivalent formats and so we hit the
    fast path.
    
    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 0a2e042..81e833e 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -130,6 +130,15 @@ static void unrealize_glyph_caches(struct sna *sna)
 		free(cache->glyphs);
 	}
 	memset(render->glyph, 0, sizeof(render->glyph));
+
+	if (render->white_image) {
+		pixman_image_unref(render->white_image);
+		render->white_image = NULL;
+	}
+	if (render->white_picture) {
+		FreePicture(render->white_picture, 0);
+		render->white_picture = NULL;
+	}
 }
 
 /* All caches for a single format share a single pixmap for glyph storage,
@@ -144,11 +153,13 @@ static void unrealize_glyph_caches(struct sna *sna)
 static Bool realize_glyph_caches(struct sna *sna)
 {
 	ScreenPtr screen = sna->scrn->pScreen;
+	pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
 	unsigned int formats[] = {
 		PIXMAN_a8,
 		PIXMAN_a8r8g8b8,
 	};
 	unsigned int i;
+	int error;
 
 	DBG(("%s\n", __FUNCTION__));
 
@@ -163,7 +174,6 @@ static Bool realize_glyph_caches(struct sna *sna)
 		PictFormatPtr pPictFormat;
 		CARD32 component_alpha;
 		int depth = PIXMAN_FORMAT_DEPTH(formats[i]);
-		int error;
 
 		pPictFormat = PictureMatchFormat(screen, depth, formats[i]);
 		if (!pPictFormat)
@@ -205,7 +215,10 @@ static Bool realize_glyph_caches(struct sna *sna)
 		cache->evict = rand() % GLYPH_CACHE_SIZE;
 	}
 
-	return TRUE;
+	sna->render.white_image = pixman_image_create_solid_fill(&white);
+	sna->render.white_picture =
+		CreateSolidPicture(0, (xRenderColor *)&white, &error);
+	return sna->render.white_image && sna->render.white_picture;
 
 bail:
 	unrealize_glyph_caches(sna);
@@ -412,7 +425,6 @@ glyphs_to_dst(struct sna *sna,
 {
 	struct sna_composite_op tmp;
 	ScreenPtr screen = dst->pDrawable->pScreen;
-	int index = screen->myNum;
 	PicturePtr glyph_atlas;
 	BoxPtr rects;
 	int nrect;
@@ -566,7 +578,6 @@ glyphs_slow(struct sna *sna,
 {
 	struct sna_composite_op tmp;
 	ScreenPtr screen = dst->pDrawable->pScreen;
-	int index = screen->myNum;
 	int16_t x, y;
 
 	if (NO_GLYPHS_SLOW)
@@ -705,7 +716,6 @@ glyphs_via_mask(struct sna *sna,
 {
 	ScreenPtr screen = dst->pDrawable->pScreen;
 	struct sna_composite_op tmp;
-	int index = screen->myNum;
 	CARD32 component_alpha;
 	PixmapPtr pixmap;
 	PicturePtr glyph_atlas, mask;
@@ -759,7 +769,6 @@ glyphs_via_mask(struct sna *sna,
 	    ((uint32_t)width * height * format->depth < 8 * 4096 ||
 	     too_large(sna, width, height))) {
 		pixman_image_t *mask_image;
-		int s;
 
 		DBG(("%s: small mask [format=%lx, depth=%d, size=%d], rendering glyphs to upload buffer\n",
 		     __FUNCTION__, (unsigned long)format->format,
@@ -784,7 +793,6 @@ upload:
 		}
 
 		memset(pixmap->devPrivate.ptr, 0, pixmap->devKind*height);
-		s = dst->pDrawable->pScreen->myNum;
 		do {
 			int n = list->len;
 			x += list->xOff;
@@ -833,15 +841,28 @@ upload:
 				     g->info.width,
 				     g->info.height));
 
-				pixman_image_composite(PictOpAdd,
-						       glyph_image,
-						       NULL,
-						       mask_image,
-						       0, 0,
-						       0, 0,
-						       xi, yi,
-						       g->info.width,
-						       g->info.height);
+				if (list->format == format) {
+					assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
+					pixman_image_composite(PictOpAdd,
+							       glyph_image,
+							       NULL,
+							       mask_image,
+							       0, 0,
+							       0, 0,
+							       xi, yi,
+							       g->info.width,
+							       g->info.height);
+				} else {
+					pixman_image_composite(PictOpAdd,
+							       sna->render.white_image,
+							       glyph_image,
+							       mask_image,
+							       0, 0,
+							       0, 0,
+							       xi, yi,
+							       g->info.width,
+							       g->info.height);
+				}
 
 next_image:
 				x += g->info.xOff;
@@ -914,14 +935,25 @@ next_image:
 				}
 
 				if (this_atlas != glyph_atlas) {
+					bool ok;
+
 					if (glyph_atlas)
 						tmp.done(sna, &tmp);
 
-					if (!sna->render.composite(sna, PictOpAdd,
-								   this_atlas, NULL, mask,
-								   0, 0, 0, 0, 0, 0,
-								   width, height,
-								   &tmp)) {
+					if (this_atlas->format == format->format) {
+						ok = sna->render.composite(sna, PictOpAdd,
+									   this_atlas, NULL, mask,
+									   0, 0, 0, 0, 0, 0,
+									   width, height,
+									   &tmp);
+					} else {
+						ok = sna->render.composite(sna, PictOpAdd,
+									   sna->render.white_picture, this_atlas, mask,
+									   0, 0, 0, 0, 0, 0,
+									   width, height,
+									   &tmp);
+					}
+					if (!ok) {
 						FreePicture(mask, 0);
 						return FALSE;
 					}
@@ -1046,6 +1078,7 @@ glyphs_fallback(CARD8 op,
 		GlyphListPtr list,
 		GlyphPtr *glyphs)
 {
+	struct sna *sna = to_sna_from_drawable(dst->pDrawable);
 	pixman_image_t *dst_image, *mask_image, *src_image;
 	int dx, dy, x, y;
 	BoxRec box;
@@ -1178,16 +1211,30 @@ glyphs_fallback(CARD8 op,
 				     g->info.width,
 				     g->info.height));
 
-				pixman_image_composite(PictOpAdd,
-						       glyph_image,
-						       NULL,
-						       mask_image,
-						       dx, dy,
-						       0, 0,
-						       x - g->info.x,
-						       y - g->info.y,
-						       g->info.width,
-						       g->info.height);
+				if (list->format == mask_format) {
+					assert(pixman_image_get_format(glyph_image) == pixman_image_get_format(mask_image));
+					pixman_image_composite(PictOpAdd,
+							       glyph_image,
+							       NULL,
+							       mask_image,
+							       dx, dy,
+							       0, 0,
+							       x - g->info.x,
+							       y - g->info.y,
+							       g->info.width,
+							       g->info.height);
+				} else {
+					pixman_image_composite(PictOpAdd,
+							       sna->render.white_image,
+							       glyph_image,
+							       mask_image,
+							       dx, dy,
+							       0, 0,
+							       x - g->info.x,
+							       y - g->info.y,
+							       g->info.width,
+							       g->info.height);
+				}
 			} else {
 				int xi = x - g->info.x;
 				int yi = y - g->info.y;
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index 8764796..b9360c3 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -274,6 +274,8 @@ struct sna_render {
 		uint16_t count;
 		uint16_t evict;
 	} glyph[2];
+	pixman_image_t *white_image;
+	PicturePtr white_picture;
 
 	uint16_t vertex_start;
 	uint16_t vertex_index;


More information about the xorg-commit mailing list