aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console/bitblit.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2005-11-09 00:39:09 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:34 -0500
commite4fc27618b75234b721c4a13d0e0d9d07e75e641 (patch)
tree793c15bd27a7cf150d27e209d537486e8439fe46 /drivers/video/console/bitblit.c
parent1dfcdfae5783fc10d7f8fcc336de838a44e7636c (diff)
[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation
This patch series implements generic code to rotate the console at 90, 180, and 270 degrees. The implementation is completely done in the framebuffer console level, thus no changes to the framebuffer layer or to the drivers are needed. Console rotation is required by some Sharp-based devices where the natural orientation of the display is not at 0 degrees. Also, users that have displays that can pivot will benefit by having a console in portrait mode if they so desire. The choice to implement the code in the console layer rather than in the framebuffer layer is due to the following reasons: - it's fast - it does not require driver changes - it can coexist with devices that can rotate the display at the hardware level - it complements graphics applications that can do display rotation The changes to core fbcon are minimal-- recognition of the console rotation angle so it can swap directions, origins and axes (xres vs yres, xpanstep vs ypanstep, xoffset vs yoffset, etc) and storage of the rotation angle per display. The bulk of the code that does the actual drawing to the screen are placed in separate files. Each angle of rotation has separate methods (bmove, clear, putcs, cursor, update_start which is derived from update_var, and clear_margins). To mimimize processing time, the fontdata are pre-rotated at each console switch (only if the font or the angle has changed). The option can be compiled out (CONFIG_FRAMEBUFFER_CONSOLE_ROTATION = n) if rotation is not needed. Choosing the rotation angle can be done in several ways: 1. boot option fbcon=rotate:n, where n = 0 - normal n = 1 - 90 degrees (clockwise) n = 2 - 180 degrees (upside down) n = 3 - 270 degrees (counterclockwise) 2. echo n > /sys/class/graphics/fb[num]/con_rotate where n is the same as described above. It sets the angle of rotation of the current console 3 echo n > /sys/class/graphics/fb[num]/con_rotate_all where n is the same as described above. Globally sets the angle of rotation. GOTCHAS: The option, especially at angles of 90 and 270 degrees, will exercise the least used code of drivers. Namely, at these angles, panning is done in the x-axis, so it can reveal bugs in the driver if xpanstep is set incorrectly. A workaround is to set xpanstep = 0. Secondly, at these angles, the framebuffer memory access can be unaligned if (fontheight * bpp) % 32 ~= 0 which can reveal bugs in the drivers imageblit, fillrect and copyarea functions. (I think cfbfillrect may have this buglet). A workaround is to use a standard 8x16 font. Speed: The scrolling speed difference between 0 and 180 degrees is minimal, somewhere areound 1-2%. At 90 or 270 degress, speed drops down to a vicinity of 30-40%. This is understandable because the blit direction is across the framebuffer "direction." Scrolling will be helped at these angles if xpanstep is not equal to zero, use of 8x16 fonts, and setting xres_virtual >= xres * 2. Note: The code is tested on little-endian only, so I don't know if it will work in big-endian. Please let me know, it will take only less than a minute of your time. This patch prepares fbcon for console rotation and contains the following changes: - add rotate field in struct fbcon_ops to keep fbcon's current rotation angle - add con_rotate field in struct display to store per-display rotation angle - create a private copy of the current var to fbcon. This will prevent fbcon from directly manipulating info->var, especially the fields xoffset, yoffset and vmode. - add ability to swap pertinent axes (xres, yres; xpanstep, ypanstep; etc) depending on the rotation angle - change global update_var() (function that sets the screen start address) as an fbcon method update_start. This is required because the axes, start offset, and/or direction can be reversed depending on the rotation angle. - add fbcon method rotate_font() which will rotate each character bitmap to the correct angle of rotation. - add fbcon boot option 'rotate' to select the angle of rotation at bootime. Currently does nothing until all patches are applied. Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/console/bitblit.c')
-rw-r--r--drivers/video/console/bitblit.c46
1 files changed, 17 insertions, 29 deletions
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 67857b3cfc8b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25#define FBCON_ATTRIBUTE_UNDERLINE 1
26#define FBCON_ATTRIBUTE_REVERSE 2
27#define FBCON_ATTRIBUTE_BOLD 4
28
29static inline int real_y(struct display *p, int ypos)
30{
31 int rows = p->vrows;
32
33 ypos += p->yscroll;
34 return ypos < rows ? ypos : ypos - rows;
35}
36
37
38static inline int get_attribute(struct fb_info *info, u16 c)
39{
40 int attribute = 0;
41
42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c))
46 attribute |= FBCON_ATTRIBUTE_REVERSE;
47 if (attr_bold(c))
48 attribute |= FBCON_ATTRIBUTE_BOLD;
49 }
50
51 return attribute;
52}
53
54static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static inline void update_attr(u8 *dst, u8 *src, int attribute,
55 struct vc_data *vc) 26 struct vc_data *vc)
56{ 27{
@@ -418,6 +389,18 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
418 ops->cursor_reset = 0; 389 ops->cursor_reset = 0;
419} 390}
420 391
392static int bit_update_start(struct fb_info *info)
393{
394 struct fbcon_ops *ops = info->fbcon_par;
395 int err;
396
397 err = fb_pan_display(info, &ops->var);
398 ops->var.xoffset = info->var.xoffset;
399 ops->var.yoffset = info->var.yoffset;
400 ops->var.vmode = info->var.vmode;
401 return err;
402}
403
421void fbcon_set_bitops(struct fbcon_ops *ops) 404void fbcon_set_bitops(struct fbcon_ops *ops)
422{ 405{
423 ops->bmove = bit_bmove; 406 ops->bmove = bit_bmove;
@@ -425,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
425 ops->putcs = bit_putcs; 408 ops->putcs = bit_putcs;
426 ops->clear_margins = bit_clear_margins; 409 ops->clear_margins = bit_clear_margins;
427 ops->cursor = bit_cursor; 410 ops->cursor = bit_cursor;
411 ops->update_start = bit_update_start;
412 ops->rotate_font = NULL;
413
414 if (ops->rotate)
415 fbcon_set_rotate(ops);
428} 416}
429 417
430EXPORT_SYMBOL(fbcon_set_bitops); 418EXPORT_SYMBOL(fbcon_set_bitops);