On 1/25/22 20:12, Helge Deller wrote:
> Add a config option CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION to
> enable bitblt and fillrect hardware acceleration in the framebuffer
> console. If disabled, such acceleration will not be used, even if it is
> supported by the graphics hardware driver.
>
> If you plan to use DRM as your main graphics output system, you should
> disable this option since it will prevent compiling in code which isn't
> used later on when DRM takes over.
>
> For all other configurations, e.g. if none of your graphic cards support
> DRM (yet), DRM isn't available for your architecture, or you can't be
> sure that the graphic card in the target system will support DRM, you
> most likely want to enable this option.
>
>
> This patch is the first RFC.

I forgot to mention that by using the static fb_scrollmode() function
I expect the compiler to optimize-out all code which seems problematic
from DRM's POV...

Helge

> Independed of this patch I did some timing experiments with a qemu
> virtual machine running a PA-RISC Debian Linux installation with a
> screen resolution of 2048x1024 with 8bpp. In that case qemu emulated the
> graphics hardware bitblt and fillrect acceleration by using the native
> (x86) CPU.
>
> It was a simple testcase which was to run "time dmesg", where the syslog
> had 284 lines. The results showed a huge speedup:
> a) time dmesg (without acceleration):
>    -> 19.0 seconds
> b) time dmesg (with acceleration):
>    ->  2.6 seconds
>
> Signed-off-by: Helge Deller <del...@gmx.de>
>
> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> index 840d9813b0bc..da84d1c21c21 100644
> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -78,6 +78,17 @@ config FRAMEBUFFER_CONSOLE
>       help
>         Low-level framebuffer-based console driver.
>
> +config FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
> +     bool "Framebuffer Console hardware acceleration support"
> +     depends on FRAMEBUFFER_CONSOLE
> +     default y if !DRM
> +     default y if !(X86 || ARM)
> +     help
> +       If you use a system on which DRM is fully supported you usually want 
> to say N,
> +       otherwise you probably want to enable this option.
> +       If enabled the framebuffer console will utilize the hardware 
> acceleration
> +       of your graphics card by using hardware bitblt and fillrect features.
> +
>  config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
>         bool "Map the console to the primary display device"
>         depends on FRAMEBUFFER_CONSOLE
> diff --git a/drivers/video/fbdev/core/fbcon.c 
> b/drivers/video/fbdev/core/fbcon.c
> index b813985f1403..f7b7d35953e8 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -1136,11 +1136,13 @@ static void fbcon_init(struct vc_data *vc, int init)
>
>       ops->graphics = 0;
>
> +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
>       if ((cap & FBINFO_HWACCEL_COPYAREA) &&
>           !(cap & FBINFO_HWACCEL_DISABLED))
>               p->scrollmode = SCROLL_MOVE;
>       else /* default to something safe */
>               p->scrollmode = SCROLL_REDRAW;
> +#endif
>
>       /*
>        *  ++guenther: console.c:vc_allocate() relies on initializing
> @@ -1705,7 +1707,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned 
> int t, unsigned int b,
>                       count = vc->vc_rows;
>               if (logo_shown >= 0)
>                       goto redraw_up;
> -             switch (p->scrollmode) {
> +             switch (fb_scrollmode(p)) {
>               case SCROLL_MOVE:
>                       fbcon_redraw_blit(vc, info, p, t, b - t - count,
>                                    count);
> @@ -1795,7 +1797,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned 
> int t, unsigned int b,
>                       count = vc->vc_rows;
>               if (logo_shown >= 0)
>                       goto redraw_down;
> -             switch (p->scrollmode) {
> +             switch (fb_scrollmode(p)) {
>               case SCROLL_MOVE:
>                       fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
>                                    -count);
> @@ -1946,12 +1948,12 @@ static void fbcon_bmove_rec(struct vc_data *vc, 
> struct fbcon_display *p, int sy,
>                  height, width);
>  }
>
> -static void updatescrollmode(struct fbcon_display *p,
> +static void updatescrollmode_accel(struct fbcon_display *p,
>                                       struct fb_info *info,
>                                       struct vc_data *vc)
>  {
> +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
>       struct fbcon_ops *ops = info->fbcon_par;
> -     int fh = vc->vc_font.height;
>       int cap = info->flags;
>       u16 t = 0;
>       int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
> @@ -1972,12 +1974,6 @@ static void updatescrollmode(struct fbcon_display *p,
>       int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
>               !(cap & FBINFO_HWACCEL_DISABLED);
>
> -     p->vrows = vyres/fh;
> -     if (yres > (fh * (vc->vc_rows + 1)))
> -             p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
> -     if ((yres % fh) && (vyres % fh < yres % fh))
> -             p->vrows--;
> -
>       if (good_wrap || good_pan) {
>               if (reading_fast || fast_copyarea)
>                       p->scrollmode = good_wrap ?
> @@ -1991,6 +1987,27 @@ static void updatescrollmode(struct fbcon_display *p,
>               else
>                       p->scrollmode = SCROLL_REDRAW;
>       }
> +#endif
> +}
> +
> +static void updatescrollmode(struct fbcon_display *p,
> +                                     struct fb_info *info,
> +                                     struct vc_data *vc)
> +{
> +     struct fbcon_ops *ops = info->fbcon_par;
> +     int fh = vc->vc_font.height;
> +     int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
> +     int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
> +                                info->var.xres_virtual);
> +
> +     p->vrows = vyres/fh;
> +     if (yres > (fh * (vc->vc_rows + 1)))
> +             p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
> +     if ((yres % fh) && (vyres % fh < yres % fh))
> +             p->vrows--;
> +
> +     /* update scrollmode in case hardware acceleration is used */
> +     updatescrollmode_accel(p, info, vc);
>  }
>
>  #define PITCH(w) (((w) + 7) >> 3)
> @@ -2148,7 +2165,7 @@ static int fbcon_switch(struct vc_data *vc)
>
>       updatescrollmode(p, info, vc);
>
> -     switch (p->scrollmode) {
> +     switch (fb_scrollmode(p)) {
>       case SCROLL_WRAP_MOVE:
>               scrollback_phys_max = p->vrows - vc->vc_rows;
>               break;
> diff --git a/drivers/video/fbdev/core/fbcon.h 
> b/drivers/video/fbdev/core/fbcon.h
> index 9315b360c898..c5c043f38162 100644
> --- a/drivers/video/fbdev/core/fbcon.h
> +++ b/drivers/video/fbdev/core/fbcon.h
> @@ -29,7 +29,9 @@ struct fbcon_display {
>      /* Filled in by the low-level console driver */
>      const u_char *fontdata;
>      int userfont;                   /* != 0 if fontdata kmalloc()ed */
> +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
>      u_short scrollmode;             /* Scroll Method */
> +#endif
>      u_short inverse;                /* != 0 text black on white as default */
>      short yscroll;                  /* Hardware scrolling */
>      int vrows;                      /* number of virtual rows */
> @@ -208,6 +210,17 @@ static inline int attr_col_ec(int shift, struct vc_data 
> *vc,
>  #define SCROLL_REDRAW           0x004
>  #define SCROLL_PAN_REDRAW  0x005
>
> +static inline u_short fb_scrollmode(struct fbcon_display *fb)
> +{
> +#ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
> +     return fb->scrollmode;
> +#else
> +     /* hardcoded to SCROLL_REDRAW if acceleration was disabled. */
> +     return SCROLL_REDRAW;
> +#endif
> +}
> +
> +
>  #ifdef CONFIG_FB_TILEBLITTING
>  extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
>  #endif
>

Reply via email to