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 <deller@xxxxxx> > > 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 >