Skip to content

Commit 87ab9f6

Browse files
hdellerdanvet
authored andcommitted
Revert "fbcon: Disable accelerated scrolling"
This reverts commit 39aead8. Revert the first (of 2) commits which disabled scrolling acceleration in fbcon/fbdev. It introduced a regression for fbdev-supported graphic cards because of the performance penalty by doing screen scrolling by software instead of using the existing graphic card 2D hardware acceleration. Console scrolling acceleration was disabled by dropping code which checked at runtime the driver hardware capabilities for the BINFO_HWACCEL_COPYAREA or FBINFO_HWACCEL_FILLRECT flags and if set, it enabled scrollmode SCROLL_MOVE which uses hardware acceleration to move screen contents. After dropping those checks scrollmode was hard-wired to SCROLL_REDRAW instead, which forces all graphic cards to redraw every character at the new screen position when scrolling. This change effectively disabled all hardware-based scrolling acceleration for ALL drivers, because now all kind of 2D hardware acceleration (bitblt, fillrect) in the drivers isn't used any longer. The original commit message mentions that only 3 DRM drivers (nouveau, omapdrm and gma500) used hardware acceleration in the past and thus code for checking and using scrolling acceleration is obsolete. This statement is NOT TRUE, because beside the DRM drivers there are around 35 other fbdev drivers which depend on fbdev/fbcon and still provide hardware acceleration for fbdev/fbcon. The original commit message also states that syzbot found lots of bugs in fbcon and thus it's "often the solution to just delete code and remove features". This is true, and the bugs - which actually affected all users of fbcon, including DRM - were fixed, or code was dropped like e.g. the support for software scrollback in vgacon (commit 973c096). So to further analyze which bugs were found by syzbot, I've looked through all patches in drivers/video which were tagged with syzbot or syzkaller back to year 2005. The vast majority fixed the reported issues on a higher level, e.g. when screen is to be resized, or when font size is to be changed. The few ones which touched driver code fixed a real driver bug, e.g. by adding a check. But NONE of those patches touched code of either the SCROLL_MOVE or the SCROLL_REDRAW case. That means, there was no real reason why SCROLL_MOVE had to be ripped-out and just SCROLL_REDRAW had to be used instead. The only reason I can imagine so far was that SCROLL_MOVE wasn't used by DRM and as such it was assumed that it could go away. That argument completely missed the fact that SCROLL_MOVE is still heavily used by fbdev (non-DRM) drivers. Some people mention that using memcpy() instead of the hardware acceleration is pretty much the same speed. But that's not true, at least not for older graphic cards and machines where we see speed decreases by factor 10 and more and thus this change leads to console responsiveness way worse than before. That's why the original commit is to be reverted. By reverting we reintroduce hardware-based scrolling acceleration and fix the performance regression for fbdev drivers. There isn't any impact on DRM when reverting those patches. Signed-off-by: Helge Deller <[email protected]> Acked-by: Geert Uytterhoeven <[email protected]> Acked-by: Sven Schnelle <[email protected]> Cc: [email protected] # v5.10+ Signed-off-by: Helge Deller <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 1148836 commit 87ab9f6

File tree

2 files changed

+37
-29
lines changed

2 files changed

+37
-29
lines changed

Documentation/gpu/todo.rst

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -300,27 +300,6 @@ Contact: Daniel Vetter, Noralf Tronnes
300300

301301
Level: Advanced
302302

303-
Garbage collect fbdev scrolling acceleration
304-
--------------------------------------------
305-
306-
Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode =
307-
SCROLL_REDRAW. There's a ton of code this will allow us to remove:
308-
309-
- lots of code in fbcon.c
310-
311-
- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called
312-
directly instead of the function table (with a switch on p->rotate)
313-
314-
- fb_copyarea is unused after this, and can be deleted from all drivers
315-
316-
Note that not all acceleration code can be deleted, since clearing and cursor
317-
support is still accelerated, which might be good candidates for further
318-
deletion projects.
319-
320-
Contact: Daniel Vetter
321-
322-
Level: Intermediate
323-
324303
idr_init_base()
325304
---------------
326305

drivers/video/fbdev/core/fbcon.c

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ static void fbcon_init(struct vc_data *vc, int init)
10251025
struct vc_data *svc = *default_mode;
10261026
struct fbcon_display *t, *p = &fb_display[vc->vc_num];
10271027
int logo = 1, new_rows, new_cols, rows, cols;
1028-
int ret;
1028+
int cap, ret;
10291029

10301030
if (WARN_ON(info_idx == -1))
10311031
return;
@@ -1034,6 +1034,7 @@ static void fbcon_init(struct vc_data *vc, int init)
10341034
con2fb_map[vc->vc_num] = info_idx;
10351035

10361036
info = registered_fb[con2fb_map[vc->vc_num]];
1037+
cap = info->flags;
10371038

10381039
if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
10391040
logo_shown = FBCON_LOGO_DONTSHOW;
@@ -1135,13 +1136,11 @@ static void fbcon_init(struct vc_data *vc, int init)
11351136

11361137
ops->graphics = 0;
11371138

1138-
/*
1139-
* No more hw acceleration for fbcon.
1140-
*
1141-
* FIXME: Garbage collect all the now dead code after sufficient time
1142-
* has passed.
1143-
*/
1144-
p->scrollmode = SCROLL_REDRAW;
1139+
if ((cap & FBINFO_HWACCEL_COPYAREA) &&
1140+
!(cap & FBINFO_HWACCEL_DISABLED))
1141+
p->scrollmode = SCROLL_MOVE;
1142+
else /* default to something safe */
1143+
p->scrollmode = SCROLL_REDRAW;
11451144

11461145
/*
11471146
* ++guenther: console.c:vc_allocate() relies on initializing
@@ -1953,15 +1952,45 @@ static void updatescrollmode(struct fbcon_display *p,
19531952
{
19541953
struct fbcon_ops *ops = info->fbcon_par;
19551954
int fh = vc->vc_font.height;
1955+
int cap = info->flags;
1956+
u16 t = 0;
1957+
int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1958+
info->fix.xpanstep);
1959+
int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
19561960
int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
19571961
int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
19581962
info->var.xres_virtual);
1963+
int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1964+
divides(ypan, vc->vc_font.height) && vyres > yres;
1965+
int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1966+
divides(ywrap, vc->vc_font.height) &&
1967+
divides(vc->vc_font.height, vyres) &&
1968+
divides(vc->vc_font.height, yres);
1969+
int reading_fast = cap & FBINFO_READS_FAST;
1970+
int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1971+
!(cap & FBINFO_HWACCEL_DISABLED);
1972+
int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1973+
!(cap & FBINFO_HWACCEL_DISABLED);
19591974

19601975
p->vrows = vyres/fh;
19611976
if (yres > (fh * (vc->vc_rows + 1)))
19621977
p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
19631978
if ((yres % fh) && (vyres % fh < yres % fh))
19641979
p->vrows--;
1980+
1981+
if (good_wrap || good_pan) {
1982+
if (reading_fast || fast_copyarea)
1983+
p->scrollmode = good_wrap ?
1984+
SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1985+
else
1986+
p->scrollmode = good_wrap ? SCROLL_REDRAW :
1987+
SCROLL_PAN_REDRAW;
1988+
} else {
1989+
if (reading_fast || (fast_copyarea && !fast_imageblit))
1990+
p->scrollmode = SCROLL_MOVE;
1991+
else
1992+
p->scrollmode = SCROLL_REDRAW;
1993+
}
19651994
}
19661995

19671996
#define PITCH(w) (((w) + 7) >> 3)

0 commit comments

Comments
 (0)