Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Apr 2015 20:30:11 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282247 - head/sys/dev/vt/hw/fb
Message-ID:  <201504292030.t3TKUBOv016564@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Wed Apr 29 20:30:11 2015
New Revision: 282247
URL: https://svnweb.freebsd.org/changeset/base/282247

Log:
  vt: fix vt_fb_bitblt_bitmap mask corruption
  
  Previously the mask wrapped when one or more of the mask bytes extended
  past the right edge of the window. Simplify the logic and use the same
  byte offset and bit in both the pattern and mask.
  
  PR:		199648
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D2360

Modified:
  head/sys/dev/vt/hw/fb/vt_fb.c

Modified: head/sys/dev/vt/hw/fb/vt_fb.c
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_fb.c	Wed Apr 29 20:08:03 2015	(r282246)
+++ head/sys/dev/vt/hw/fb/vt_fb.c	Wed Apr 29 20:30:11 2015	(r282247)
@@ -264,46 +264,40 @@ vt_fb_bitblt_bitmap(struct vt_device *vd
 {
 	struct fb_info *info;
 	uint32_t fgc, bgc, cc, o;
-	int c, l, bpp, bpl;
-	u_long line;
-	uint8_t b, m;
-	const uint8_t *ch;
+	int bpp, bpl, xi, yi;
+	int bit, byte;
 
 	info = vd->vd_softc;
 	bpp = FBTYPE_GET_BYTESPP(info);
 	fgc = info->fb_cmap[fg];
 	bgc = info->fb_cmap[bg];
-	b = m = 0;
-	bpl = (width + 7) >> 3; /* Bytes per source line. */
+	bpl = (width + 7) / 8; /* Bytes per source line. */
 
 	if (info->fb_flags & FB_FLAG_NOWRITE)
 		return;
 
 	KASSERT((info->fb_vbase != 0), ("Unmapped framebuffer"));
 
-	line = (info->fb_stride * y) + (x * bpp);
-	for (l = 0;
-	    l < height && y + l < vw->vw_draw_area.tr_end.tp_row;
-	    l++) {
-		ch = pattern;
-		for (c = 0;
-		    c < width && x + c < vw->vw_draw_area.tr_end.tp_col;
-		    c++) {
-			if (c % 8 == 0)
-				b = *ch++;
-			else
-				b <<= 1;
-			if (mask != NULL) {
-				if (c % 8 == 0)
-					m = *mask++;
-				else
-					m <<= 1;
-				/* Skip pixel write, if mask has no bit set. */
-				if ((m & 0x80) == 0)
-					continue;
-			}
-			o = line + (c * bpp);
-			cc = b & 0x80 ? fgc : bgc;
+	/* Bound by right and bottom edges. */
+	if (y + height > vw->vw_draw_area.tr_end.tp_row) {
+		if (y >= vw->vw_draw_area.tr_end.tp_row)
+			return;
+		height = vw->vw_draw_area.tr_end.tp_row - y;
+	}
+	if (x + width > vw->vw_draw_area.tr_end.tp_col) {
+		if (x >= vw->vw_draw_area.tr_end.tp_col)
+			return;
+		width = vw->vw_draw_area.tr_end.tp_col - x;
+	}
+	for (yi = 0; yi < height; yi++) {
+		for (xi = 0; xi < width; xi++) {
+			byte = yi * bpl + xi / 8;
+			bit = 0x80 >> (xi % 8);
+			/* Skip pixel write, if mask bit not set. */
+			if (mask != NULL && (mask[byte] & bit) == 0)
+				continue;
+			o = (y + yi) * info->fb_stride + (x + xi) * bpp;
+			cc = pattern[byte] & bit ? fgc : bgc;
 
 			switch(bpp) {
 			case 1:
@@ -326,8 +320,6 @@ vt_fb_bitblt_bitmap(struct vt_device *vd
 				break;
 			}
 		}
-		line += info->fb_stride;
-		pattern += bpl;
 	}
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504292030.t3TKUBOv016564>