summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorray <ray@FreeBSD.org>2014-04-04 11:17:49 +0000
committerray <ray@FreeBSD.org>2014-04-04 11:17:49 +0000
commit6c8c52eb6b1e7ebc8876be67f1359c827181a0dc (patch)
treee53415beaaaf13ada37b6ac9dfd51df203de3be4
parentbe0e4274f56ea1159058a51a75ed7b29e5a04f0a (diff)
downloadFreeBSD-src-6c8c52eb6b1e7ebc8876be67f1359c827181a0dc.zip
FreeBSD-src-6c8c52eb6b1e7ebc8876be67f1359c827181a0dc.tar.gz
MFC r263885
o Add new vd_driver method to do bitblt with mask, named vd_maskbitbltchr. o Move vd_bitbltchr vga's driver method to vd_maskbitbltchr. o Implement new vd_bitbltchr method for vga driver. (It do single write for 8 pixels, have to be a bit faster). Sponsored by: The FreeBSD Foundation
-rw-r--r--sys/dev/vt/hw/vga/vga.c30
-rw-r--r--sys/dev/vt/vt.h4
-rw-r--r--sys/dev/vt/vt_core.c4
3 files changed, 37 insertions, 1 deletions
diff --git a/sys/dev/vt/hw/vga/vga.c b/sys/dev/vt/hw/vga/vga.c
index e98918f..13c640a 100644
--- a/sys/dev/vt/hw/vga/vga.c
+++ b/sys/dev/vt/hw/vga/vga.c
@@ -74,6 +74,7 @@ struct vga_softc {
static vd_init_t vga_init;
static vd_blank_t vga_blank;
static vd_bitbltchr_t vga_bitbltchr;
+static vd_maskbitbltchr_t vga_maskbitbltchr;
static vd_drawrect_t vga_drawrect;
static vd_setpixel_t vga_setpixel;
static vd_putchar_t vga_putchar;
@@ -83,6 +84,7 @@ static const struct vt_driver vt_vga_driver = {
.vd_init = vga_init,
.vd_blank = vga_blank,
.vd_bitbltchr = vga_bitbltchr,
+ .vd_maskbitbltchr = vga_maskbitbltchr,
.vd_drawrect = vga_drawrect,
.vd_setpixel = vga_setpixel,
.vd_putchar = vga_putchar,
@@ -204,6 +206,34 @@ vga_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
unsigned int height, term_color_t fg, term_color_t bg)
{
+ u_long dst, ldst;
+ int w;
+
+ /* Don't try to put off screen pixels */
+ if (((left + width) > VT_VGA_WIDTH) || ((top + height) >
+ VT_VGA_HEIGHT))
+ return;
+
+ dst = (VT_VGA_WIDTH * top + left) / 8;
+
+ for (; height > 0; height--) {
+ ldst = dst;
+ for (w = width; w > 0; w -= 8) {
+ vga_bitblt_put(vd, ldst, fg, *src);
+ vga_bitblt_put(vd, ldst, bg, ~*src);
+ ldst++;
+ src++;
+ }
+ dst += VT_VGA_WIDTH / 8;
+ }
+}
+
+/* Bitblt with mask support. Slow. */
+static void
+vga_maskbitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
+ int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+ unsigned int height, term_color_t fg, term_color_t bg)
+{
struct vga_softc *sc = vd->vd_softc;
u_long dst;
uint8_t shift;
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 9f175b8..9445cc9 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -282,6 +282,9 @@ typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
typedef void vd_bitbltchr_t(struct vt_device *vd, const uint8_t *src,
const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left,
unsigned int width, unsigned int height, term_color_t fg, term_color_t bg);
+typedef void vd_maskbitbltchr_t(struct vt_device *vd, const uint8_t *src,
+ const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left,
+ unsigned int width, unsigned int height, term_color_t fg, term_color_t bg);
typedef void vd_putchar_t(struct vt_device *vd, term_char_t,
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg);
typedef int vd_fb_ioctl_t(struct vt_device *, u_long, caddr_t, struct thread *);
@@ -298,6 +301,7 @@ struct vt_driver {
/* Drawing. */
vd_blank_t *vd_blank;
vd_bitbltchr_t *vd_bitbltchr;
+ vd_maskbitbltchr_t *vd_maskbitbltchr;
vd_drawrect_t *vd_drawrect;
vd_setpixel_t *vd_setpixel;
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index b179afd..b21b42e 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -775,7 +775,7 @@ vt_flush(struct vt_device *vd)
if ((vd->vd_my + m->h) > (size.tp_row * vf->vf_height))
h = (size.tp_row * vf->vf_height) - vd->vd_my - 1;
- vd->vd_driver->vd_bitbltchr(vd, m->map, m->mask, bpl,
+ vd->vd_driver->vd_maskbitbltchr(vd, m->map, m->mask, bpl,
vd->vd_offset.tp_row + vd->vd_my,
vd->vd_offset.tp_col + vd->vd_mx,
w, h, TC_WHITE, TC_BLACK);
@@ -1930,6 +1930,8 @@ vt_allocate(struct vt_driver *drv, void *softc)
printf("%s: Replace existing VT driver.\n", __func__);
}
vd = main_vd;
+ if (drv->vd_maskbitbltchr == NULL)
+ drv->vd_maskbitbltchr = drv->vd_bitbltchr;
/* Stop vt_flush periodic task. */
if (vd->vd_curwindow != NULL)
OpenPOWER on IntegriCloud