Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci support anti-aliased fonts in 8 bit as well
details: https://anonhg.NetBSD.org/src/rev/ddf31b0f31b5
branches: trunk
changeset: 777665:ddf31b0f31b5
user: macallan <macallan%NetBSD.org@localhost>
date: Tue Feb 28 20:21:16 2012 +0000
description:
support anti-aliased fonts in 8 bit as well
diffstat:
sys/dev/pci/radeonfb.c | 165 +++++++++++++++++++++++++++++++++++++++++++--
sys/dev/pci/radeonfbvar.h | 4 +-
2 files changed, 160 insertions(+), 9 deletions(-)
diffs (255 lines):
diff -r 57c4c3354e37 -r ddf31b0f31b5 sys/dev/pci/radeonfb.c
--- a/sys/dev/pci/radeonfb.c Tue Feb 28 18:14:47 2012 +0000
+++ b/sys/dev/pci/radeonfb.c Tue Feb 28 20:21:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: radeonfb.c,v 1.54 2012/02/16 17:33:28 macallan Exp $ */
+/* $NetBSD: radeonfb.c,v 1.55 2012/02/28 20:21:16 macallan Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.54 2012/02/16 17:33:28 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: radeonfb.c,v 1.55 2012/02/28 20:21:16 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -168,6 +168,7 @@
static void radeonfb_cursor(void *, int, int, int);
static void radeonfb_putchar(void *, int, int, unsigned, long);
static void radeonfb_putchar_aa32(void *, int, int, unsigned, long);
+static void radeonfb_putchar_aa8(void *, int, int, unsigned, long);
static void radeonfb_putchar_wrapper(void *, int, int, unsigned, long);
static int radeonfb_get_backlight(struct radeonfb_display *);
@@ -1219,6 +1220,13 @@
}
void
+radeonfb_put32s(struct radeonfb_softc *sc, uint32_t reg, uint32_t val)
+{
+
+ bus_space_write_stream_4(sc->sc_regt, sc->sc_regh, reg, val);
+}
+
+void
radeonfb_mask32(struct radeonfb_softc *sc, uint32_t reg,
uint32_t andmask, uint32_t ormask)
{
@@ -2172,6 +2180,9 @@
if (ri->ri_depth == 32) {
ri->ri_flg |= RI_ENABLE_ALPHA;
}
+ if (ri->ri_depth == 8) {
+ ri->ri_flg |= RI_ENABLE_ALPHA | RI_8BIT_IS_RGB;
+ }
ri->ri_bits = (void *)dp->rd_fbptr;
#ifdef VCONS_DRAW_INTR
@@ -2227,7 +2238,18 @@
}
} else {
/* got an alpha font */
- ri->ri_ops.putchar = radeonfb_putchar_aa32;
+ switch(ri->ri_depth) {
+ case 32:
+ ri->ri_ops.putchar = radeonfb_putchar_aa32;
+ break;
+ case 8:
+ ri->ri_ops.putchar = radeonfb_putchar_aa8;
+ break;
+ default:
+ /* XXX this should never happen */
+ panic("%s: depth is not 8 or 32 but we got an alpha font?!",
+ __func__);
+ }
}
ri->ri_ops.cursor = radeonfb_cursor;
}
@@ -2360,12 +2382,29 @@
if (sc->sc_displays[crtc].rd_bpp == 8) {
/* ANSI palette */
int j = 0;
+ uint32_t tmp, r, g, b;
for (i = 0; i <= CLUT_WIDTH; ++i) {
- PUT32(sc, RADEON_PALETTE_30_DATA,
- (rasops_cmap[j] << 22) |
- (rasops_cmap[j + 1] << 12) |
- (rasops_cmap[j + 2] << 2));
+ tmp = i & 0xe0;
+ /*
+ * replicate bits so 0xe0 maps to a red value of 0xff
+ * in order to make white look actually white
+ */
+ tmp |= (tmp >> 3) | (tmp >> 6);
+ r = tmp;
+
+ tmp = (i & 0x1c) << 3;
+ tmp |= (tmp >> 3) | (tmp >> 6);
+ g = tmp;
+
+ tmp = (i & 0x03) << 6;
+ tmp |= tmp >> 2;
+ tmp |= tmp >> 4;
+ b = tmp;
+ PUT32(sc, RADEON_PALETTE_30_DATA,
+ (r << 22) |
+ (g << 12) |
+ (b << 2));
j += 3;
}
} else {
@@ -2595,6 +2634,116 @@
glyphcache_add(&dp->rd_gc, c, xd, yd);
}
+static void
+radeonfb_putchar_aa8(void *cookie, int row, int col, u_int c, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct radeonfb_display *dp = scr->scr_cookie;
+ struct radeonfb_softc *sc = dp->rd_softc;
+ struct wsdisplay_font *font = PICK_FONT(ri, c);
+ uint32_t bg, latch = 0, bg8, fg8, pixel, gmc;
+ int i, x, y, wi, he, r, g, b, aval;
+ int r1, g1, b1, r0, g0, b0, fgo, bgo;
+ uint8_t *data8;
+ int rv;
+
+ if (dp->rd_wsmode != WSDISPLAYIO_MODE_EMUL)
+ return;
+
+ if (!CHAR_IN_FONT(c, font))
+ return;
+
+ wi = font->fontwidth;
+ he = font->fontheight;
+
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+
+ x = ri->ri_xorigin + col * wi;
+ y = ri->ri_yorigin + row * he;
+
+ if (c == 0x20) {
+ radeonfb_rectfill(dp, x, y, wi, he, bg);
+ return;
+ }
+ rv = glyphcache_try(&dp->rd_gc, c, x, y, attr);
+ if (rv == GC_OK)
+ return;
+
+ data8 = WSFONT_GLYPH(c, font);
+
+ gmc = dp->rd_format << RADEON_GMC_DST_DATATYPE_SHIFT;
+
+ radeonfb_wait_fifo(sc, 5);
+
+ PUT32(sc, RADEON_DP_GUI_MASTER_CNTL,
+ RADEON_GMC_BRUSH_NONE |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP3_S |
+ RADEON_DP_SRC_SOURCE_HOST_DATA |
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_WR_MSK_DIS |
+ gmc);
+
+ PUT32(sc, RADEON_DP_CNTL,
+ RADEON_DST_X_LEFT_TO_RIGHT |
+ RADEON_DST_Y_TOP_TO_BOTTOM);
+
+ PUT32(sc, RADEON_SRC_X_Y, 0);
+ PUT32(sc, RADEON_DST_X_Y, (x << 16) | y);
+ PUT32(sc, RADEON_DST_WIDTH_HEIGHT, (wi << 16) | he);
+
+ /*
+ * we need the RGB colours here, so get offsets into rasops_cmap
+ */
+ fgo = ((attr >> 24) & 0xf) * 3;
+ bgo = ((attr >> 16) & 0xf) * 3;
+
+ r0 = rasops_cmap[bgo];
+ r1 = rasops_cmap[fgo];
+ g0 = rasops_cmap[bgo + 1];
+ g1 = rasops_cmap[fgo + 1];
+ b0 = rasops_cmap[bgo + 2];
+ b1 = rasops_cmap[fgo + 2];
+#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6))
+ bg8 = R3G3B2(r0, g0, b0);
+ fg8 = R3G3B2(r1, g1, b1);
+ for (i = 0; i < ri->ri_fontscale; i++) {
+ aval = *data8;
+ if (aval == 0) {
+ pixel = bg8;
+ } else if (aval == 255) {
+ pixel = fg8;
+ } else {
+ r = aval * r1 + (255 - aval) * r0;
+ g = aval * g1 + (255 - aval) * g0;
+ b = aval * b1 + (255 - aval) * b0;
+ pixel = ((r & 0xe000) >> 8) |
+ ((g & 0xe000) >> 11) |
+ ((b & 0xc000) >> 14);
+ }
+ latch = (latch << 8) | pixel;
+ /* write in 32bit chunks */
+ if ((i & 3) == 3) {
+ PUT32S(sc, RADEON_HOST_DATA0, latch);
+ /*
+ * not strictly necessary, old data should be shifted
+ * out
+ */
+ latch = 0;
+ }
+ data8++;
+ }
+ /* if we have pixels left in latch write them out */
+ if ((i & 3) != 0) {
+ latch = latch << ((4 - (i & 3)) << 3);
+ PUT32(sc, RADEON_HOST_DATA0, latch);
+ }
+
+ if (rv == GC_ADD)
+ glyphcache_add(&dp->rd_gc, c, x, y);
+}
+
/*
* wrapper for software character drawing
* just sync the engine and call rasops*_putchar()
@@ -2808,7 +2957,7 @@
radeonfb_engine_flush(sc);
}
-static void
+static inline void
radeonfb_wait_fifo(struct radeonfb_softc *sc, int n)
{
int i;
diff -r 57c4c3354e37 -r ddf31b0f31b5 sys/dev/pci/radeonfbvar.h
--- a/sys/dev/pci/radeonfbvar.h Tue Feb 28 18:14:47 2012 +0000
+++ b/sys/dev/pci/radeonfbvar.h Tue Feb 28 20:21:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: radeonfbvar.h,v 1.14 2012/02/16 17:33:28 macallan Exp $ */
+/* $NetBSD: radeonfbvar.h,v 1.15 2012/02/28 20:21:16 macallan Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -317,6 +317,7 @@
#define GET32(sc, r) radeonfb_get32(sc, r)
#define PUT32(sc, r, v) radeonfb_put32(sc, r, v)
+#define PUT32S(sc, r, v) radeonfb_put32s(sc, r, v)
#define SET32(sc, r, v) PUT32(sc, r, GET32(sc, r) | (v))
#define CLR32(sc, r, v) PUT32(sc, r, GET32(sc, r) & ~(v))
#define PATCH32(sc, r, v, m) PUT32(sc, r, (GET32(sc, r) & (m)) | (v))
@@ -349,6 +350,7 @@
uint32_t radeonfb_get32(struct radeonfb_softc *, uint32_t);
void radeonfb_put32(struct radeonfb_softc *, uint32_t, uint32_t);
+void radeonfb_put32s(struct radeonfb_softc *, uint32_t, uint32_t);
void radeonfb_mask32(struct radeonfb_softc *, uint32_t, uint32_t, uint32_t);
uint32_t radeonfb_getindex(struct radeonfb_softc *, uint32_t);
Home |
Main Index |
Thread Index |
Old Index