From: Mats Petersson <mats.petersson@citrix.com>
To: xen-devel@lists.xen.org
Subject: Re: [PATCH v4 3/7] xen: introduce a generic framebuffer driver
Date: Wed, 9 Jan 2013 14:45:21 +0000 [thread overview]
Message-ID: <50ED8281.9070609@citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1301091249030.4981@kaball.uk.xensource.com>
On 09/01/13 14:05, Stefano Stabellini wrote:
> On Wed, 9 Jan 2013, Jan Beulich wrote:
>>>>> On 08.01.13 at 21:03, Stefano Stabellini <stefano.stabellini@eu.citrix.com> wrote:
>>> --- /dev/null
>>> +++ b/xen/drivers/video/lfb.c
>>> @@ -0,0 +1,206 @@
>>> +/******************************************************************************
>>> + * lfb.c
>>> + *
>>> + * linear frame buffer handling.
>>> + */
>>> +
>>> +#include <xen/config.h>
>>> +#include <xen/kernel.h>
>>> +#include <xen/lib.h>
>>> +#include <xen/errno.h>
>>> +#include "lfb.h"
>>> +#include "font.h"
>>> +
>>> +#define MAX_XRES 1900
>>> +#define MAX_YRES 1200
>>> +#define MAX_BPP 4
>>> +#define MAX_FONT_W 8
>>> +#define MAX_FONT_H 16
>>> +static __initdata unsigned int line_len[MAX_XRES / MAX_FONT_W];
>>> +static __initdata unsigned char lbuf[MAX_XRES * MAX_BPP];
>>> +static __initdata unsigned char text_buf[(MAX_XRES / MAX_FONT_W) * \
>>> + (MAX_YRES / MAX_FONT_H)];
>> Imo it would be better to move all these __initdata definitions
>> do to where the using __init functions actually live, to make
>> sure unintended use of them in non-__init ones is noticed.
> OK
>
>
>>> +
>>> +struct lfb_status {
>>> + struct lfb_prop lfbp;
>>> +
>>> + unsigned char *lbuf, *text_buf;
>>> + unsigned int *line_len;
>>> + unsigned int xpos, ypos;
>>> +};
>>> +static struct lfb_status lfb;
>>> +
>>> +static void lfb_show_line(
>>> + const unsigned char *text_line,
>>> + unsigned char *video_line,
>>> + unsigned int nr_chars,
>>> + unsigned int nr_cells)
>>> +{
>>> + unsigned int i, j, b, bpp, pixel;
>>> +
>>> + bpp = (lfb.lfbp.bits_per_pixel + 7) >> 3;
>>> +
>>> + for ( i = 0; i < lfb.lfbp.font->height; i++ )
>>> + {
>>> + unsigned char *ptr = lfb.lbuf;
>>> +
>>> + for ( j = 0; j < nr_chars; j++ )
>>> + {
>>> + const unsigned char *bits = lfb.lfbp.font->data;
>>> + bits += ((text_line[j] * lfb.lfbp.font->height + i) *
>>> + ((lfb.lfbp.font->width + 7) >> 3));
>>> + for ( b = lfb.lfbp.font->width; b--; )
>>> + {
>>> + pixel = (*bits & (1u<<b)) ? lfb.lfbp.pixel_on : 0;
>>> + memcpy(ptr, &pixel, bpp);
>>> + ptr += bpp;
>>> + }
>>> + }
>>> +
>>> + memset(ptr, 0, (lfb.lfbp.width - nr_chars * lfb.lfbp.font->width) * bpp);
>>> + memcpy(video_line, lfb.lbuf, nr_cells * lfb.lfbp.font->width * bpp);
>>> + video_line += lfb.lfbp.bytes_per_line;
>>> + }
>>> +}
>>> +
>>> +/* Fast mode which redraws all modified parts of a 2D text buffer. */
>>> +void lfb_redraw_puts(const char *s)
>>> +{
>>> + unsigned int i, min_redraw_y = lfb.ypos;
>>> + char c;
>>> +
>>> + /* Paste characters into text buffer. */
>>> + while ( (c = *s++) != '\0' )
>>> + {
>>> + if ( (c == '\n') || (lfb.xpos >= lfb.lfbp.text_columns) )
>>> + {
>>> + if ( ++lfb.ypos >= lfb.lfbp.text_rows )
>>> + {
>>> + min_redraw_y = 0;
>>> + lfb.ypos = lfb.lfbp.text_rows - 1;
>>> + memmove(lfb.text_buf, lfb.text_buf + lfb.lfbp.text_columns,
>>> + lfb.ypos * lfb.lfbp.text_columns);
>>> + memset(lfb.text_buf + lfb.ypos * lfb.lfbp.text_columns, 0, lfb.xpos);
>>> + }
>>> + lfb.xpos = 0;
>>> + }
>>> +
>>> + if ( c != '\n' )
>>> + lfb.text_buf[lfb.xpos++ + lfb.ypos * lfb.lfbp.text_columns] = c;
>>> + }
>>> +
>>> + /* Render modified section of text buffer to VESA linear framebuffer. */
>>> + for ( i = min_redraw_y; i <= lfb.ypos; i++ )
>>> + {
>>> + const unsigned char *line = lfb.text_buf + i * lfb.lfbp.text_columns;
>>> + unsigned int width;
>>> +
>>> + for ( width = lfb.lfbp.text_columns; width; --width )
>>> + if ( line[width - 1] )
>>> + break;
>>> + lfb_show_line(line,
>>> + lfb.lfbp.lfb + i * lfb.lfbp.font->height * lfb.lfbp.bytes_per_line,
>>> + width, max(lfb.line_len[i], width));
>>> + lfb.line_len[i] = width;
>>> + }
>>> +
>>> + lfb.lfbp.flush();
>>> +}
>>> +
>>> +/* Slower line-based scroll mode which interacts better with dom0. */
>>> +void lfb_scroll_puts(const char *s)
>>> +{
>>> + unsigned int i;
>>> + char c;
>>> +
>>> + while ( (c = *s++) != '\0' )
>>> + {
>>> + if ( (c == '\n') || (lfb.xpos >= lfb.lfbp.text_columns) )
>>> + {
>>> + unsigned int bytes = (lfb.lfbp.width *
>>> + ((lfb.lfbp.bits_per_pixel + 7) >> 3));
>>> + unsigned char *src = lfb.lfbp.lfb + lfb.lfbp.font->height * lfb.lfbp.bytes_per_line;
>>> + unsigned char *dst = lfb.lfbp.lfb;
>>> +
>>> + /* New line: scroll all previous rows up one line. */
>>> + for ( i = lfb.lfbp.font->height; i < lfb.lfbp.height; i++ )
>>> + {
>>> + memcpy(dst, src, bytes);
>>> + src += lfb.lfbp.bytes_per_line;
>>> + dst += lfb.lfbp.bytes_per_line;
>>> + }
>>> +
>>> + /* Render new line. */
>>> + lfb_show_line(
>>> + lfb.text_buf,
>>> + lfb.lfbp.lfb + (lfb.lfbp.text_rows-1) * lfb.lfbp.font->height * lfb.lfbp.bytes_per_line,
>> Long line?
> Right
>
The calculation of
lfb.lfbp.lfb + lfb.lfbp.font->height * lfb.lfbp.bytes_per_line;
is done twice in the above section - surely that's constant over time, so could be stored in another local variable - thus making the line shorter and at the same time more obvious that "it's the same thing".
--
Mats
next prev parent reply other threads:[~2013-01-09 14:45 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-08 20:02 [PATCH v4 0/7] xen: ARM HDLCD video driver Stefano Stabellini
2013-01-08 20:03 ` [PATCH v4 1/7] xen/arm: introduce early_ioremap Stefano Stabellini
2013-01-10 15:48 ` Ian Campbell
2013-01-14 17:46 ` Stefano Stabellini
2013-01-08 20:03 ` [PATCH v4 2/7] xen: infrastructure to have cross-platform video drivers Stefano Stabellini
2013-01-10 15:49 ` Ian Campbell
2013-01-10 16:08 ` Jan Beulich
2013-01-10 16:16 ` Ian Campbell
2013-01-10 16:28 ` Keir Fraser
2013-01-21 11:38 ` Ian Campbell
2013-01-10 16:16 ` Ian Campbell
2013-01-08 20:03 ` [PATCH v4 3/7] xen: introduce a generic framebuffer driver Stefano Stabellini
2013-01-09 10:53 ` Jan Beulich
2013-01-09 14:05 ` Stefano Stabellini
2013-01-09 14:45 ` Mats Petersson [this message]
2013-01-09 14:51 ` Mats Petersson
2013-01-09 17:17 ` Stefano Stabellini
2013-01-08 20:03 ` [PATCH v4 4/7] xen/arm: move setup_mm right after setup_pagetables Stefano Stabellini
2013-01-10 15:55 ` Ian Campbell
2013-01-14 17:18 ` Stefano Stabellini
2013-01-15 10:29 ` Ian Campbell
2013-01-08 20:03 ` [PATCH v4 5/7] xen/device_tree: introduce find_compatible_node Stefano Stabellini
2013-01-08 20:03 ` [PATCH v4 6/7] xen/arm: introduce vexpress_syscfg Stefano Stabellini
2013-01-10 15:58 ` Ian Campbell
2013-01-14 17:11 ` Stefano Stabellini
2013-01-08 20:03 ` [PATCH v4 7/7] xen/arm: introduce a driver for the ARM HDLCD controller Stefano Stabellini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50ED8281.9070609@citrix.com \
--to=mats.petersson@citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).