Commit c76d035d authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbdev: Add Tile Blitting support

Hopefully, this patch fixes one last major regression for one particular
driver, namely matroxfb.  This drier has 2 versions, one for the kernel and
another as a '2.4 backport' patch.

This patch adds a tileblitting extension to fbcon.  This extension, in
summary, is basically a forward-port of the 2.4 fbdev/fbcon framework to 2.6
but without the fbcon dependency.  Tile blitting is similar to bitblit, except
that the basic unit is a tile (a bitmap of x-by-y dimensions).  The display,
instead of being described in terms of pixels and scanlines, are described as
a region further subdivided into rectangular sections.  In fbcon parlance, a
tile is a character.

Besides a possible fix for matroxfb, tileblitting can be advantageous for
hardware that supports some kind of fontcaching mechanism.  Also, in the
unlikely chance that the console begins supporting multicolored fonts,
tileblitting is probably more optimal than bitblitting because bitblitting
will need to push more data through the bus.

To enable support for this extension, a driver needs to:

- enable CONFIG_FB_TILEBLITTING
- set FBINFO_MISC_TILEBLITTING in info->flags
- set the required function pointers in struct fb_tileops.  The required
  operations are:

  - void (*fb_settile)(struct fb_info *info, struct fb_tilemap *map);

    tells driver about the tile characteristics (dimensions, bitdepth) and
    about the tilemap which is an array of bitmaps: display->fontdata

  - void (*fb_tilecopy)(struct fb_info *info, struct fb_tilearea *area);

    move a rectangular section of tiles (bmove)

  - void (*fb_tilefill)(struct fb_info *info, struct fb_tilerect *rect);

    fill a rectangular section with a tile (clear)

  - void (*fb_tileblit)(struct fb_info *info, struct fb_tileblit *blit);

    copy an array of tiles to a rectangular section (putcs)

  - void (*fb_tilecursor)(struct fb_info *info, struct fb_tilecursor *cursor);

    cursor function

Changes:

Addition of this extension necessitates cleanup of fbcon.c.  The basic drawing
functions in fbcon are bmove, clear, putcs and cursor (the fbcon_* set).  The
fbcon_* set are just wrappers to accel_* set.  However, usage is not
consistent, some functions call the fbcon_* set, others call the accel_* set.

With this patch, a new fbcon-specific structure (struct fbcon_ops) is created.
 Depending on the setting of the hardware, this struct contains pointers to
either the tileblitting set or the bitblitting set (formerly the accel_* set).
 The tileblitting set is new in this patch.

The vast majority of functions in fbcon will need to only call the fbcon_*
set.  In turn, it calls functions in struct fbcon_ops.  Knowledge of the
blitting type is not required.

The accel_* set is renamed to bit_* and is moved into a separate file,
bitblit.c.  The tile blitting set is in tileblit.c.

In my case at least, the cleanup did produce an unexpected but beneficial
side effect, a little more speedup.  Not much, < 5%.

Petr, if you have comments, suggestions, or you think this is a bad idea,
let me know.
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 03f779b6
......@@ -49,6 +49,24 @@ config FB_MODE_HELPERS
your driver does not take advantage of this feature, choosing Y will
just increase the kernel size by about 5K.
config FB_TILEBLITTING
bool "Enable Tile Blitting Support"
depends on FB
default n
---help---
This enables tile blitting. Tile blitting is a drawing technique
where the screen is divided into rectangular sections (tiles), whereas
the standard blitting divides the screen into pixels. Because the
default drawing element is a tile, drawing functions will be passed
parameters in terms of number of tiles instead of number of pixels.
For example, to draw a single character, instead of using bitmaps,
an index to an array of bitmaps will be used. To clear or move a
rectangular section of a screen, the rectangle willbe described in
terms of number of tiles in the x- and y-axis.
This is particularly important to one driver, the matroxfb. If
unsure, say N.
config FB_CIRRUS
tristate "Cirrus Logic support"
depends on FB && (ZORRO || PCI)
......
......@@ -24,7 +24,8 @@ obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o
obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o font.o
obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o
obj-$(CONFIG_FB_TILEBLITTING) += tileblit.o
obj-$(CONFIG_FB_STI) += sticore.o
......
/*
* linux/drivers/video/console/bitblit.c -- BitBlitting Operation
*
* Originally from the 'accel_*' routines in drivers/video/console/fbcon.c
*
* Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
/*
* Accelerated handlers.
*/
#define FBCON_ATTRIBUTE_UNDERLINE 1
#define FBCON_ATTRIBUTE_REVERSE 2
#define FBCON_ATTRIBUTE_BOLD 4
static inline int real_y(struct display *p, int ypos)
{
int rows = p->vrows;
ypos += p->yscroll;
return ypos < rows ? ypos : ypos - rows;
}
static inline int get_attribute(struct fb_info *info, u16 c)
{
int attribute = 0;
if (fb_get_color_depth(info) == 1) {
if (attr_underline(c))
attribute |= FBCON_ATTRIBUTE_UNDERLINE;
if (attr_reverse(c))
attribute |= FBCON_ATTRIBUTE_REVERSE;
if (attr_bold(c))
attribute |= FBCON_ATTRIBUTE_BOLD;
}
return attribute;
}
static inline void update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
u8 c;
offset = cellsize - (offset * width);
for (i = 0; i < cellsize; i++) {
c = src[i];
if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i >= offset)
c = 0xff;
if (attribute & FBCON_ATTRIBUTE_BOLD)
c |= c >> 1;
if (attribute & FBCON_ATTRIBUTE_REVERSE)
c = ~c;
dst[i] = c;
}
}
static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fb_copyarea area;
area.sx = sx * vc->vc_font.width;
area.sy = sy * vc->vc_font.height;
area.dx = dx * vc->vc_font.width;
area.dy = dy * vc->vc_font.height;
area.height = height * vc->vc_font.height;
area.width = width * vc->vc_font.width;
info->fbops->fb_copyarea(info, &area);
}
static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
struct fb_fillrect region;
region.color = attr_bgcol_ec(bgshift, vc);
region.dx = sx * vc->vc_font.width;
region.dy = sy * vc->vc_font.height;
region.width = width * vc->vc_font.width;
region.height = height * vc->vc_font.height;
region.rop = ROP_COPY;
info->fbops->fb_fillrect(info, &region);
}
static void bit_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
void (*move_unaligned)(struct fb_info *info, struct fb_pixmap *buf,
u8 *dst, u32 d_pitch, u8 *src, u32 idx,
u32 height, u32 shift_high, u32 shift_low,
u32 mod);
void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
u32 height);
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int width = (vc->vc_font.width + 7) >> 3;
unsigned int cellsize = vc->vc_font.height * width;
unsigned int maxcnt = info->pixmap.size/cellsize;
unsigned int scan_align = info->pixmap.scan_align - 1;
unsigned int buf_align = info->pixmap.buf_align - 1;
unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
unsigned int shift_high = 8, pitch, cnt, size, k;
unsigned int idx = vc->vc_font.width >> 3;
unsigned int attribute = get_attribute(info, scr_readw(s));
struct fb_image image;
u8 *src, *dst, *buf = NULL;
if (attribute) {
buf = kmalloc(cellsize, GFP_KERNEL);
if (!buf)
return;
}
image.fg_color = fg;
image.bg_color = bg;
image.dx = xx * vc->vc_font.width;
image.dy = yy * vc->vc_font.height;
image.height = vc->vc_font.height;
image.depth = 1;
if (info->pixmap.outbuf && info->pixmap.inbuf) {
move_aligned = fb_iomove_buf_aligned;
move_unaligned = fb_iomove_buf_unaligned;
} else {
move_aligned = fb_sysmove_buf_aligned;
move_unaligned = fb_sysmove_buf_unaligned;
}
while (count) {
if (count > maxcnt)
cnt = k = maxcnt;
else
cnt = k = count;
image.width = vc->vc_font.width * cnt;
pitch = ((image.width + 7) >> 3) + scan_align;
pitch &= ~scan_align;
size = pitch * image.height + buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info, &info->pixmap, size);
image.data = dst;
if (mod) {
while (k--) {
src = vc->vc_font.data + (scr_readw(s++)&
charmask)*cellsize;
if (attribute) {
update_attr(buf, src, attribute, vc);
src = buf;
}
move_unaligned(info, &info->pixmap, dst, pitch,
src, idx, image.height,
shift_high, shift_low, mod);
shift_low += mod;
dst += (shift_low >= 8) ? width : width - 1;
shift_low &= 7;
shift_high = 8 - shift_low;
}
} else {
while (k--) {
src = vc->vc_font.data + (scr_readw(s++)&
charmask)*cellsize;
if (attribute) {
update_attr(buf, src, attribute, vc);
src = buf;
}
move_aligned(info, &info->pixmap, dst, pitch,
src, idx, image.height);
dst += width;
}
}
info->fbops->fb_imageblit(info, &image);
image.dx += cnt * vc->vc_font.width;
count -= cnt;
}
if (buf)
kfree(buf);
}
static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
unsigned int cw = vc->vc_font.width;
unsigned int ch = vc->vc_font.height;
unsigned int rw = info->var.xres - (vc->vc_cols*cw);
unsigned int bh = info->var.yres - (vc->vc_rows*ch);
unsigned int rs = info->var.xres - rw;
unsigned int bs = info->var.yres - bh;
struct fb_fillrect region;
region.color = attr_bgcol_ec(bgshift, vc);
region.rop = ROP_COPY;
if (rw && !bottom_only) {
region.dx = info->var.xoffset + rs;
region.dy = 0;
region.width = rw;
region.height = info->var.yres_virtual;
info->fbops->fb_fillrect(info, &region);
}
if (bh) {
region.dx = info->var.xoffset;
region.dy = info->var.yoffset + bs;
region.width = rs;
region.height = bh;
info->fbops->fb_fillrect(info, &region);
}
}
static void bit_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg)
{
struct fb_cursor cursor;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int w = (vc->vc_font.width + 7) >> 3, c;
int y = real_y(p, vc->vc_y);
int attribute;
char *src;
c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
if (attribute) {
u8 *dst;
dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
if (!dst)
return;
if (info->cursor.data)
kfree(info->cursor.data);
info->cursor.data = dst;
update_attr(dst, src, attribute, vc);
src = dst;
}
cursor.image.data = src;
cursor.set = FB_CUR_SETCUR;
cursor.image.depth = 1;
switch (mode) {
case CM_ERASE:
if (info->cursor.rop == ROP_XOR) {
info->cursor.enable = 0;
info->cursor.rop = ROP_COPY;
info->fbops->fb_cursor(info, &cursor);
}
break;
case CM_MOVE:
case CM_DRAW:
info->cursor.enable = 1;
info->cursor.rop = ROP_XOR;
if (info->cursor.image.fg_color != fg ||
info->cursor.image.bg_color != bg) {
cursor.image.fg_color = fg;
cursor.image.bg_color = bg;
cursor.set |= FB_CUR_SETCMAP;
}
if ((info->cursor.image.dx != (vc->vc_font.width * vc->vc_x)) ||
(info->cursor.image.dy != (vc->vc_font.height * y))) {
cursor.image.dx = vc->vc_font.width * vc->vc_x;
cursor.image.dy = vc->vc_font.height * y;
cursor.set |= FB_CUR_SETPOS;
}
if (info->cursor.image.height != vc->vc_font.height ||
info->cursor.image.width != vc->vc_font.width) {
cursor.image.height = vc->vc_font.height;
cursor.image.width = vc->vc_font.width;
cursor.set |= FB_CUR_SETSIZE;
}
if (info->cursor.hot.x || info->cursor.hot.y) {
cursor.hot.x = cursor.hot.y = 0;
cursor.set |= FB_CUR_SETHOT;
}
if ((cursor.set & FB_CUR_SETSIZE) ||
((vc->vc_cursor_type & 0x0f) != p->cursor_shape)
|| info->cursor.mask == NULL) {
char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
int cur_height, size, i = 0;
u8 msk = 0xff;
if (!mask)
return;
if (info->cursor.mask)
kfree(info->cursor.mask);
info->cursor.mask = mask;
p->cursor_shape = vc->vc_cursor_type & 0x0f;
cursor.set |= FB_CUR_SETSHAPE;
switch (vc->vc_cursor_type & 0x0f) {
case CUR_NONE:
cur_height = 0;
break;
case CUR_UNDERLINE:
cur_height = (vc->vc_font.height < 10) ? 1 : 2;
break;
case CUR_LOWER_THIRD:
cur_height = vc->vc_font.height/3;
break;
case CUR_LOWER_HALF:
cur_height = vc->vc_font.height >> 1;
break;
case CUR_TWO_THIRDS:
cur_height = (vc->vc_font.height << 1)/3;
break;
case CUR_BLOCK:
default:
cur_height = vc->vc_font.height;
break;
}
size = (vc->vc_font.height - cur_height) * w;
while (size--)
mask[i++] = ~msk;
size = cur_height * w;
while (size--)
mask[i++] = msk;
}
info->fbops->fb_cursor(info, &cursor);
break;
}
}
void fbcon_set_bitops(struct fbcon_ops *ops)
{
ops->bmove = bit_bmove;
ops->clear = bit_clear;
ops->putcs = bit_putcs;
ops->clear_margins = bit_clear_margins;
ops->cursor = bit_cursor;
}
EXPORT_SYMBOL(fbcon_set_bitops);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Bit Blitting Operation");
MODULE_LICENSE("GPL");
This diff is collapsed.
......@@ -48,6 +48,19 @@ struct display {
struct fb_videomode *mode;
};
struct fbcon_ops {
void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width);
void (*putcs)(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg);
void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
int bottom_only);
void (*cursor)(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg);
};
/*
* Attribute Decoding
*/
......@@ -72,6 +85,13 @@ struct display {
#define attr_blink(s) \
((s) & 0x8000)
/* Font */
#define REFCOUNT(fd) (((int *)(fd))[-1])
#define FNTSIZE(fd) (((int *)(fd))[-2])
#define FNTCHARCNT(fd) (((int *)(fd))[-3])
#define FNTSUM(fd) (((int *)(fd))[-4])
#define FONT_EXTRA_WORDS 4
/*
* Scroll Method
*/
......@@ -129,5 +149,9 @@ struct display {
#define SCROLL_PAN_REDRAW 0x005
extern int fb_console_init(void);
#ifdef CONFIG_FB_TILEBLITTING
extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
struct display *p, struct fbcon_ops *ops);
#endif
extern void fbcon_set_bitops(struct fbcon_ops *ops);
#endif /* _VIDEO_FBCON_H */
/*
* linux/drivers/video/console/tileblit.c -- Tile Blitting Operation
*
* Copyright (C) 2004 Antonino Daplas <adaplas @pol.net>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
#include "fbcon.h"
static void tile_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
struct fb_tilearea area;
area.sx = sx;
area.sy = sy;
area.dx = dx;
area.dy = dy;
area.height = height;
area.width = width;
info->tileops->fb_tilecopy(info, &area);
}
static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
struct fb_tilerect rect;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
rect.index = vc->vc_video_erase_char &
((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
rect.fg = attr_fgcol_ec(fgshift, vc);
rect.bg = attr_bgcol_ec(bgshift, vc);
rect.sx = sx;
rect.sy = sy;
rect.width = width;
rect.height = height;
rect.rop = ROP_COPY;
info->tileops->fb_tilefill(info, &rect);
}
static void tile_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int yy, int xx,
int fg, int bg)
{
struct fb_tileblit blit;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
int size = sizeof(u32) * count, i;
blit.sx = xx;
blit.sy = yy;
blit.width = count;
blit.height = 1;
blit.fg = fg;
blit.bg = bg;
blit.length = count;
blit.indices = (u32 *) fb_get_buffer_offset(info, &info->pixmap, size);
for (i = 0; i < count; i++)
blit.indices[i] = (u32)(scr_readw(s++) & charmask);
info->tileops->fb_tileblit(info, &blit);
}
static void tile_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
return;
}
static void tile_cursor(struct vc_data *vc, struct fb_info *info,
struct display *p, int mode, int fg, int bg)
{
struct fb_tilecursor cursor;
cursor.sx = vc->vc_x;
cursor.sy = vc->vc_y;
cursor.mode = (mode == CM_ERASE) ? 0 : 1;
cursor.fg = fg;
cursor.bg = bg;
switch (vc->vc_cursor_type & 0x0f) {
case CUR_NONE:
cursor.shape = FB_TILE_CURSOR_NONE;
break;
case CUR_UNDERLINE:
cursor.shape = FB_TILE_CURSOR_UNDERLINE;
break;
case CUR_LOWER_THIRD:
cursor.shape = FB_TILE_CURSOR_LOWER_THIRD;
break;
case CUR_LOWER_HALF:
cursor.shape = FB_TILE_CURSOR_LOWER_HALF;
break;
case CUR_TWO_THIRDS:
cursor.shape = FB_TILE_CURSOR_TWO_THIRDS;
break;
case CUR_BLOCK:
default:
cursor.shape = FB_TILE_CURSOR_BLOCK;
break;
}
info->tileops->fb_tilecursor(info, &cursor);
}
void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
struct display *p, struct fbcon_ops *ops)
{
struct fb_tilemap map;
ops->bmove = tile_bmove;
ops->clear = tile_clear;
ops->putcs = tile_putcs;
ops->clear_margins = tile_clear_margins;
ops->cursor = tile_cursor;
if (p) {
map.width = vc->vc_font.width;
map.height = vc->vc_font.height;
map.depth = 1;
map.length = (p->userfont) ?
FNTCHARCNT(p->fontdata) : 256;
map.data = p->fontdata;
info->tileops->fb_settile(info, &map);
}
}
EXPORT_SYMBOL(fbcon_set_tileops);
MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
MODULE_DESCRIPTION("Tile Blitting Operation");
MODULE_LICENSE("GPL");
......@@ -368,6 +368,9 @@ int fb_prepare_logo(struct fb_info *info)
memset(&fb_logo, 0, sizeof(struct logo_data));
if (info->flags & FBINFO_MISC_TILEBLITTING)
return 0;
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
depth = info->var.blue.length;
if (info->var.red.length < depth)
......@@ -679,6 +682,7 @@ fb_cursor(struct fb_info *info, struct fb_cursor_user __user *sprite)
cursor.image.cmap.blue = info->cursor.image.cmap.blue;
cursor.image.cmap.transp = info->cursor.image.cmap.transp;
cursor.data = NULL;
cursor.flash = 0;
if (cursor.set & FB_CUR_SETCUR)
info->cursor.enable = 1;
......
......@@ -318,6 +318,7 @@ struct fb_cursor {
struct fbcurpos hot; /* cursor hot spot */
struct fb_image image; /* Cursor image */
/* all fields below are for fbcon use only */
int flash; /* cursor blink */
char *data; /* copy of bitmap */
};
......@@ -555,6 +556,82 @@ struct fb_ops {
int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
};
#ifdef CONFIG_FB_TILEBLITTING
#define FB_TILE_CURSOR_NONE 0
#define FB_TILE_CURSOR_UNDERLINE 1
#define FB_TILE_CURSOR_LOWER_THIRD 2
#define FB_TILE_CURSOR_LOWER_HALF 3
#define FB_TILE_CURSOR_TWO_THIRDS 4
#define FB_TILE_CURSOR_BLOCK 5
struct fb_tilemap {
__u32 width; /* width of each tile in pixels */
__u32 height; /* height of each tile in scanlines */
__u32 depth; /* color depth of each tile */
__u32 length; /* number of tiles in the map */
__u8 *data; /* actual tile map: a bitmap array, packed
to the nearest byte */
};
struct fb_tilerect {
__u32 sx; /* origin in the x-axis */
__u32 sy; /* origin in the y-axis */
__u32 width; /* number of tiles in the x-axis */
__u32 height; /* number of tiles in the y-axis */
__u32 index; /* what tile to use: index to tile map */
__u32 fg; /* foreground color */
__u32 bg; /* background color */
__u32 rop; /* raster operation */
};
struct fb_tilearea {
__u32 sx; /* source origin in the x-axis */
__u32 sy; /* source origin in the y-axis */
__u32 dx; /* destination origin in the x-axis */
__u32 dy; /* destination origin in the y-axis */
__u32 width; /* number of tiles in the x-axis */
__u32 height; /* number of tiles in the y-axis */
};
struct fb_tileblit {
__u32 sx; /* origin in the x-axis */
__u32 sy; /* origin in the y-axis */
__u32 width; /* number of tiles in the x-axis */
__u32 height; /* number of tiles in the y-axis */
__u32 fg; /* foreground color */
__u32 bg; /* background color */
__u32 length; /* number of tiles to draw */
__u32 *indices; /* array of indices to tile map */
};
struct fb_tilecursor {
__u32 sx; /* cursor position in the x-axis */
__u32 sy; /* cursor position in the y-axis */
__u32 mode; /* 0 = erase, 1 = draw */
__u32 shape; /* see FB_TILE_CURSOR_* */
__u32 fg; /* foreground color */
__u32 bg; /* background color */
};
struct fb_tile_ops {
/* set tile characteristics */
void (*fb_settile)(struct fb_info *info, struct fb_tilemap *map);
/* all dimensions from hereon are in terms of tiles */
/* move a rectangular region of tiles from one area to another*/
void (*fb_tilecopy)(struct fb_info *info, struct fb_tilearea *area);
/* fill a rectangular region with a tile */
void (*fb_tilefill)(struct fb_info *info, struct fb_tilerect *rect);
/* copy an array of tiles */
void (*fb_tileblit)(struct fb_info *info, struct fb_tileblit *blit);
/* cursor */
void (*fb_tilecursor)(struct fb_info *info,
struct fb_tilecursor *cursor);
};
#endif /* CONFIG_FB_TILEBLITTING */
/* FBINFO_* = fb_info.flags bit flags */
#define FBINFO_MODULE 0x0001 /* Low-level driver is a module */
#define FBINFO_HWACCEL_DISABLED 0x0002
......@@ -586,6 +663,7 @@ struct fb_ops {
from userspace */
#define FBINFO_MISC_MODESWITCH 0x20000 /* mode switch */
#define FBINFO_MISC_MODESWITCHLATE 0x40000 /* init hardware later */
#define FBINFO_MISC_TILEBLITTING 0x80000 /* use tile blitting */
struct fb_info {
int node;
......@@ -602,6 +680,9 @@ struct fb_info {
struct list_head modelist; /* mode list */
struct fb_ops *fbops;
struct device *device;
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
char __iomem *screen_base; /* Virtual address */
unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */
int currcon; /* Current VC. */
......@@ -609,7 +690,7 @@ struct fb_info {
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */
void *fbcon_par; /* fbcon use-only private area */
/* From here on everything is device dependent */
void *par;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment