From: "Antonino A. Daplas" <adaplas@gmail.com>
To: linux-fbdev-devel@lists.sourceforge.net
Subject: Re: [PATCH] smart blitter usage for scrolling
Date: Wed, 09 May 2007 22:19:18 +0800 [thread overview]
Message-ID: <1178720358.4861.27.camel@daplas> (raw)
In-Reply-To: <464172cc491d5@wp.pl>
On Wed, 2007-05-09 at 09:05 +0200, Krzysztof Helt wrote:
> From: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> This patch adds option to uses blitter only to move characters
> which have to be moved instead of current brute force approach
> (move whole screen).
>
> Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
>
> ---
>
> This patch uses the same logic as the fbcon_redraw() but uses
> bmove() instead of putcs(). On my system (dual P3 866MHz and
> Permedia 2 with 83MHz clock) this gives the SCROLL_MOVE up to 5%
> slower than non accelerated SCROLL_REDRAW. Previously, the
> SCROLL_MOVE was few times (up to 10) slower. I tested it with
> "time dmesg" at 1024x768 and 1600x1200 resolutions.
This sounds quite logical to me. However, I would rather that you
create a new scrolling mode (ie SCROLL_MOVE_REDRAW and
SCROLL_WRAP_REDRAW). Then create a new FBINFO_HWACCEL flag that will
enable SCROLL_PAN/WRAP_MOVE_REDRAW and perhaps another one that will
enable MERGE_BLIT.
To illustrate, see further comments below.
>
> I think that this new approach can completely replace the brute
> force SCROLL_MOVE method used currently. It should help all
> drivers which uses SCROLL_MOVE method (probably not many), reduce
> difference between SCROLL_REDRAW and SCROLL_MOVE and do nothing
> to drivers useng SCROLL_REDRAW method.
>
> There is additional possibility to improve performance by
> enabling MERGE_BLIT definition. In this case, the first matching
> character to scroll (in source and destination location) is
> ignored. This produces about half of blits requests (in my test
> case - around 100 instead of around 200) but blits are larger
> (each one is one character larger). This may help on cards where
> the blitter is fast but slow to start (any known card?). If it is
> not a case it can be dropped completely (to simplify the code).
> In my case it has not produced any speed improvement (and even
> slower scrolling by 1-2%).
>
> This patch is indented for your review and tests on different
> hardware. I will also test it on hardware I have (I can borrow
> slower machine and I have few other GFX cards to tests).
>
> Kind regards,
> Krzysztof
>
> diff -urp linux-2.6.21/drivers/video/Kconfig
> linux-2.6.21.mod/drivers/video/Kconfig
> --- linux-2.6.21/drivers/video/Kconfig 2007-05-08
> 23:38:34.055228990 +0200
> +++ linux-2.6.21.mod/drivers/video/Kconfig 2007-05-09
> 00:13:34.910949935 +0200
> @@ -139,6 +139,23 @@ config FB_TILEBLITTING
> This is particularly important to one driver, matroxfb. If
> unsure, say N.
>
> +config FB_SMALL_BLITS
> + bool "Enable Enhanced Blitting Support (EXPERIMENTAL)"
> + depends on FB && EXPERIMENTAL
> + default n
> + ---help---
> + This enables smart usage of blitter to sroll screen. A
> standard
> + way is to use blitter to move almost whole screen. The enhanced
> + blitting moves only characters which have to be moved. The same
> + logic is used for redrawing characters during scroll if the
> + blitting is not used to scroll.
> + It may or may not speed up scrolling of your framebuffer. It
> + depends on relative speed of your CPU and GPU. If you have
> + fast CPU and slow GPU this option may slow down scrolling.
> + If the opposite is true this may speed up scrolling for you.
> +
> + If unsure, say N.
> +
> comment "Frame buffer hardware drivers"
> depends on FB
>
> diff -urp linux-2.6.21/drivers/video/console/fbcon.c
> linux-2.6.21.mod/drivers/video/console/fbcon.c
> --- linux-2.6.21/drivers/video/console/fbcon.c 2007-04-26
> 05:08:32.000000000 +0200
> +++ linux-2.6.21.mod/drivers/video/console/fbcon.c 2007-05-09
> 00:15:37.501935997 +0200
> @@ -1663,6 +1663,81 @@ static void fbcon_redraw_move(struct vc_
> }
> }
>
> +static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info
> *info,
> + struct display *p, int line, int count, int ycount)
> +{
> + int offset = ycount * vc->vc_cols;
> + unsigned short *d = (unsigned short *)
> + (vc->vc_origin + vc->vc_size_row * line);
> + unsigned short *s = d + offset;
> + struct fbcon_ops *ops = info->fbcon_par;
> +
> + while (count--) {
> + unsigned short *start = s;
> + unsigned short *le = advance_row(s, 1);
> + unsigned short c;
> + int x = 0;
> + unsigned short attr = 1;
> +#ifdef MERGE_BLITS
> + int was_blit = 1;
> +#endif
> +
> + do {
> + c = scr_readw(s);
> + if (attr != (c & 0xff00)) {
> + attr = c & 0xff00;
> + if (s > start) {
> + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start);
> +#ifdef MERGE_BLITS
> + was_blit = 1;
> +#endif
You can remove those #ifdef's (they're ugly anyway if used within a
function).
So something like:
if (info->flags & FBINFO_HWACCEL_MERGEBLIT)
was_blit = 1;
> + x += s - start;
> + start = s;
> + }
> + }
> + if (c == scr_readw(d)) {
> + if (s > start) {
> +#ifdef MERGE_BLITS
> + if (!was_blit) {
> +#endif
and,
if (info->flags & FBINFO_HWACCEL_MERGEBLIT || !was_blit)
or something to that effect.
> + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start);
> + x += s - start + 1;
> + start = s + 1;
> +#ifdef MERGE_BLITS
> + }
> + was_blit = !was_blit;
> +#endif
> + } else {
> +#ifdef MERGE_BLITS
> + if (was_blit) {
> +#endif
> + x++;
> + start++;
> +#ifdef MERGE_BLITS
> + }
> +#endif
> + }
> + }
> + scr_writew(c, d);
> + console_conditional_schedule();
> + s++;
> + d++;
> + } while (s < le);
> + if (s > start) {
> + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start);
> + }
> + console_conditional_schedule();
> + if (ycount > 0)
> + line++;
> + else {
> + line--;
> + /* NOTE: We subtract two lines from these pointers */
> + s -= vc->vc_size_row;
> + d -= vc->vc_size_row;
> + }
> + }
> +}
> +
> static void fbcon_redraw(struct vc_data *vc, struct display *p,
> int line, int count, int offset)
> {
> @@ -1748,7 +1823,9 @@ static int fbcon_scroll(struct vc_data *
> {
> struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
> struct display *p = &fb_display[vc->vc_num];
> +#ifndef CONFIG_FB_SMALL_BLITS
> struct fbcon_ops *ops = info->fbcon_par;
> +#endif
> int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
>
> if (fbcon_is_inactive(vc, info))
> @@ -1772,10 +1849,22 @@ static int fbcon_scroll(struct vc_data *
> goto redraw_up;
> switch (p->scrollmode) {
> case SCROLL_MOVE:
> +#ifndef CONFIG_FB_SMALL_BLITS
> ops->bmove(vc, info, t + count, 0, t, 0,
> b - t - count, vc->vc_cols);
> ops->clear(vc, info, b - count, 0, count,
> vc->vc_cols);
> +#else
Again, you can remove the #ifdef and just do:
case SCROLL_MOVE_REDRAW:
> + fbcon_redraw_blit(vc, info, p, t, b - t - count,
> + count);
> + fbcon_clear(vc, b - count, 0, count, vc->vc_cols);
> + scr_memsetw((unsigned short *) (vc->vc_origin +
> + vc->vc_size_row *
> + (b - count)),
> + vc->vc_video_erase_char,
> + vc->vc_size_row * count);
> + return 1;
> +#endif
> break;
>
> case SCROLL_WRAP_MOVE:
> @@ -1858,9 +1947,21 @@ static int fbcon_scroll(struct vc_data *
> goto redraw_down;
> switch (p->scrollmode) {
> case SCROLL_MOVE:
> +#ifndef CONFIG_FB_SMALL_BLITS
> ops->bmove(vc, info, t, 0, t + count, 0,
> b - t - count, vc->vc_cols);
> ops->clear(vc, info, t, 0, count, vc->vc_cols);
> +#else
Same here.
> + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
> + -count);
> + fbcon_clear(vc, t, 0, count, vc->vc_cols);
> + scr_memsetw((unsigned short *) (vc->vc_origin +
> + vc->vc_size_row *
> + t),
> + vc->vc_video_erase_char,
> + vc->vc_size_row * count);
> + return 1;
> +#endif
> break;
>
> case SCROLL_WRAP_MOVE:
And all those selection magic you can do in update_scrollmode().
Hopefully, you get what I'm trying to illustrate. Choose the most
effective method you want (not necessarily my example), but let's
eliminate the ugly #ifdefs and make this a new scrolling mode selectable
by the driver by setting certain bits in info->flags.
Tony
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
next prev parent reply other threads:[~2007-05-09 14:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-09 7:05 [PATCH] smart blitter usage for scrolling Krzysztof Helt
2007-05-09 14:19 ` Antonino A. Daplas [this message]
2007-05-10 5:40 ` Krzysztof Helt
2007-05-10 5:49 ` Antonino A. Daplas
2007-05-10 5:56 ` Antonino A. Daplas
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=1178720358.4861.27.camel@daplas \
--to=adaplas@gmail.com \
--cc=linux-fbdev-devel@lists.sourceforge.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.