Re: [PATCH] [RFC] fbcon: Add option to enable legacy hardware acceleration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 1/25/22 20:17, Helge Deller wrote:
> 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...

This patch is not complete, for example there are more changes necessary
in fbcon_cw.c, bcon_ccw.c and fbcon_ccw.c.

Anyway, for the first round I'm interested in general feedback, if this is
the direction which is acceptable for you.

In addition I think fb_scrollmode() should be renamed to fbcon_scrollmode()
to make it clear that it's a fbcon-related function.

If you want to test this patch you will need to first apply the revert-patches
I sent earlier.
Alternatively for testing it's possible to pull from the "fbcon-accel" branch from:
https://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev.git  fbcon-accel

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
>>
>





[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux