xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
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:51:33 +0000	[thread overview]
Message-ID: <50ED83F5.8070302@citrix.com> (raw)
In-Reply-To: <50ED8281.9070609@citrix.com>

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@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".
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.

--
Mats

>
> --
> Mats
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
>
>

  reply	other threads:[~2013-01-09 14:51 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
2013-01-09 14:51         ` Mats Petersson [this message]
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=50ED83F5.8070302@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).