Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757501Ab2FPWHK (ORCPT ); Sat, 16 Jun 2012 18:07:10 -0400 Received: from mail-wg0-f42.google.com ([74.125.82.42]:55078 "EHLO mail-wg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757258Ab2FPWEy (ORCPT ); Sat, 16 Jun 2012 18:04:54 -0400 From: David Herrmann To: linux-serial@vger.kernel.org Cc: Florian Tobias Schandinat , linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org, Greg Kroah-Hartman , David Herrmann Subject: [PATCH 04/10] fblog: implement fblog_redraw() Date: Sun, 17 Jun 2012 00:04:20 +0200 Message-Id: <1339884266-9201-5-git-send-email-dh.herrmann@googlemail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1339884266-9201-1-git-send-email-dh.herrmann@googlemail.com> References: <1339884266-9201-1-git-send-email-dh.herrmann@googlemail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4605 Lines: 163 This mostly copies the functionality from drivers/video/console/bitblit.c so we can draw the console content on all available framebuffers. All speed optimizations have been removed for simplicity. The original code depends heavily on CONFIG_VT so we cannot share the codebase here. Signed-off-by: David Herrmann --- drivers/video/console/fblog.c | 126 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/drivers/video/console/fblog.c b/drivers/video/console/fblog.c index 8038dcc..e790971 100644 --- a/drivers/video/console/fblog.c +++ b/drivers/video/console/fblog.c @@ -197,6 +197,131 @@ static void fblog_buf_write(struct fblog_buf *buf, const char *str, size_t len) } } +static void fblog_redraw_aligned(struct fblog_fb *fb, const char *s, u32 cnt, + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *dst) +{ + struct fb_info *info = fb->info; + const struct font_desc *font = fb->font; + u32 idx = font->width >> 3; + u8 *src; + + while (cnt--) { + src = (void*)(font->data + (*s++ & 0xff) * cellsize); + fb_pad_aligned_buffer(dst, d_pitch, src, idx, image->height); + dst += s_pitch; + } + + info->fbops->fb_imageblit(info, image); +} + +static void fblog_redraw_unaligned(struct fblog_fb *fb, const char *s, u32 cnt, + u32 d_pitch, u32 s_pitch, u32 cellsize, + struct fb_image *image, u8 *dst) +{ + struct fb_info *info = fb->info; + const struct font_desc *font = fb->font; + u32 shift_low = 0, mod = font->width % 8; + u32 shift_high = 8; + u32 idx = font->width >> 3; + u8 *src; + + while (cnt--) { + src = (void*)(font->data + (*s++ & 0xff) * cellsize); + fb_pad_unaligned_buffer(dst, d_pitch, src, idx, + image->height, shift_high, + shift_low, mod); + shift_low += mod; + dst += (shift_low >= 8) ? s_pitch : s_pitch - 1; + shift_low &= 7; + shift_high = 8 - shift_low; + } + + info->fbops->fb_imageblit(info, image); +} + +static void fblog_redraw_line(struct fblog_fb *fb, size_t line, + const char *str, size_t len) +{ + struct fb_info *info = fb->info; + const struct font_desc *font = fb->font; + struct fb_image image; + u32 width = DIV_ROUND_UP(font->width, 8); + u32 cellsize = width * font->height; + u32 maxcnt = info->pixmap.size / cellsize; + u32 scan_align = info->pixmap.scan_align - 1; + u32 buf_align = info->pixmap.buf_align - 1; + u32 mod = font->width % 8; + u32 cnt, pitch, size; + u8 *dst; + + image.fg_color = 7; + image.bg_color = 0; + image.dx = 0; + image.dy = line * font->height; + image.height = font->height; + image.depth = 1; + + while (len) { + if (len > maxcnt) + cnt = maxcnt; + else + cnt = len; + + image.width = font->width * cnt; + pitch = DIV_ROUND_UP(image.width, 8) + scan_align; + pitch &= ~scan_align; + size = pitch * image.height + buf_align; + size &= ~buf_align; + dst = fb_get_buffer_offset(info, &info->pixmap, size); + image.data = dst; + + if (!mod) + fblog_redraw_aligned(fb, str, cnt, pitch, width, + cellsize, &image, dst); + else + fblog_redraw_unaligned(fb, str, cnt, pitch, width, + cellsize, &image, dst); + + image.dx += cnt * font->width; + len -= cnt; + str += cnt; + } +} + +static void fblog_redraw_clear(struct fblog_fb *fb) +{ + struct fb_fillrect region; + struct fb_info *info = fb->info; + + region.color = 0; + region.dx = 0; + region.dy = 0; + region.width = info->var.xres; + region.height = info->var.yres; + region.rop = ROP_COPY; + + info->fbops->fb_fillrect(info, ®ion); +} + +static void fblog_redraw(struct fblog_fb *fb) +{ + size_t i, len; + + if (!fb || !fb->font || test_bit(FBLOG_KILLED, &fb->flags) || + test_bit(FBLOG_SUSPENDED, &fb->flags) || + test_bit(FBLOG_BLANKED, &fb->flags)) + return; + + fblog_redraw_clear(fb); + + for (i = 0; i < fb->buf.height; ++i) { + len = strnlen(fb->buf.lines[i], fb->buf.width); + if (len) + fblog_redraw_line(fb, i, fb->buf.lines[i], len); + } +} + static struct fblog_fb *fblog_info2fb(struct fb_info *info) { if (!info || info->node < 0 || info->node >= FB_MAX || @@ -244,6 +369,7 @@ static void fblog_register(struct fb_info *info) width = info->var.xres / fb->font->width; height = info->var.yres / fb->font->height; fblog_buf_resize(&fb->buf, width, height); + fblog_redraw(fb); } return; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/