|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 3/7] xen: introduce a generic framebuffer driver
On Wed, 9 Jan 2013, Mats Petersson wrote:
> On 09/01/13 14:45, Mats Petersson wrote:
> > 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@xxxxxxxxxxxxx> 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".
> No, it isn't! I started out with
>
> lfb.lfbp.font->height * lfb.lfbp.bytes_per_line
>
> being calculated twice. Then mistakenly thought that it was MORE of the same,
> missing out that the second calculation is different. Sorry for that. But the
> font->hight * bytes_per_line calculation is definitely the same in both
> places.
Thanks for the review!
lfb_scroll_puts and lfb_show_line are just vesa_scroll_puts and
vesa_show_line renamed and with some basic variable name changes.
I would be reticent to change them in this patch unless necessary.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |