Merge branch 'for-next/fb'
This commit is contained in:
commit
b6b7203aca
|
@ -1458,6 +1458,7 @@ endif
|
|||
config CMD_SPLASH
|
||||
bool
|
||||
select IMAGE_RENDERER
|
||||
depends on VIDEO
|
||||
prompt "splash"
|
||||
help
|
||||
Display a BMP image on a framebuffer device
|
||||
|
|
|
@ -15,9 +15,9 @@ static int do_splash(int argc, char *argv[])
|
|||
int opt;
|
||||
char *fbdev = "/dev/fb0";
|
||||
char *image_file;
|
||||
int offscreen = 0;
|
||||
u32 bg_color = 0x00000000;
|
||||
bool do_bg = false;
|
||||
void *buf;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
|
||||
|
@ -41,8 +41,6 @@ static int do_splash(int argc, char *argv[])
|
|||
case 'y':
|
||||
s.y = simple_strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'o':
|
||||
offscreen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,21 +50,17 @@ static int do_splash(int argc, char *argv[])
|
|||
}
|
||||
image_file = argv[optind];
|
||||
|
||||
sc = fb_open(fbdev, offscreen);
|
||||
sc = fb_open(fbdev);
|
||||
if (IS_ERR(sc)) {
|
||||
perror("fd_open");
|
||||
return PTR_ERR(sc);
|
||||
}
|
||||
|
||||
if (sc->offscreenbuf) {
|
||||
if (do_bg)
|
||||
gu_memset_pixel(sc->info, sc->offscreenbuf, bg_color,
|
||||
sc->s.width * sc->s.height);
|
||||
else
|
||||
memcpy(sc->offscreenbuf, sc->fb, sc->fbsize);
|
||||
} else if (do_bg) {
|
||||
gu_memset_pixel(sc->info, sc->fb, bg_color, sc->s.width * sc->s.height);
|
||||
}
|
||||
buf = gui_screen_render_buffer(sc);
|
||||
|
||||
if (do_bg)
|
||||
gu_memset_pixel(sc->info, buf, bg_color,
|
||||
sc->s.width * sc->s.height);
|
||||
|
||||
ret = image_renderer_file(sc, &s, image_file);
|
||||
if (ret > 0)
|
||||
|
@ -89,7 +83,6 @@ BAREBOX_CMD_HELP_OPT ("-f FB\t", "framebuffer device (default /dev/fb0)")
|
|||
BAREBOX_CMD_HELP_OPT ("-x XOFFS", "x offset (default center)")
|
||||
BAREBOX_CMD_HELP_OPT ("-y YOFFS", "y offset (default center)")
|
||||
BAREBOX_CMD_HELP_OPT ("-b COLOR", "background color in 0xttrrggbb")
|
||||
BAREBOX_CMD_HELP_OPT ("-o\t", "render offscreen")
|
||||
BAREBOX_CMD_HELP_END
|
||||
|
||||
BAREBOX_CMD_START(splash)
|
||||
|
|
|
@ -7,6 +7,7 @@ if VIDEO
|
|||
|
||||
config FRAMEBUFFER_CONSOLE
|
||||
bool
|
||||
depends on !CONSOLE_NONE
|
||||
select IMAGE_RENDERER
|
||||
select FONTS
|
||||
prompt "framebuffer console support"
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
static int fb_ioctl(struct cdev* cdev, int req, void *data)
|
||||
{
|
||||
struct fb_info *info = cdev->priv;
|
||||
struct fb_info **fb;
|
||||
|
||||
switch (req) {
|
||||
case FBIOGET_SCREENINFO:
|
||||
memcpy(data, info, sizeof(*info));
|
||||
fb = data;
|
||||
*fb = info;
|
||||
break;
|
||||
case FBIO_ENABLE:
|
||||
info->fbops->fb_enable(info);
|
||||
|
@ -29,11 +31,40 @@ static int fb_ioctl(struct cdev* cdev, int req, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fb_alloc_shadowfb(struct fb_info *info)
|
||||
{
|
||||
if (info->screen_base_shadow && info->shadowfb)
|
||||
return 0;
|
||||
|
||||
if (!info->screen_base_shadow && !info->shadowfb)
|
||||
return 0;
|
||||
|
||||
if (info->shadowfb) {
|
||||
info->screen_base_shadow = memalign(PAGE_SIZE,
|
||||
info->line_length * info->yres);
|
||||
if (!info->screen_base_shadow)
|
||||
return -ENOMEM;
|
||||
memcpy(info->screen_base_shadow, info->screen_base,
|
||||
info->line_length * info->yres);
|
||||
} else {
|
||||
free(info->screen_base_shadow);
|
||||
info->screen_base_shadow = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fb_enable(struct fb_info *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (info->enabled)
|
||||
return 0;
|
||||
|
||||
ret = fb_alloc_shadowfb(info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
info->fbops->fb_enable(info);
|
||||
|
||||
info->enabled = true;
|
||||
|
@ -186,6 +217,22 @@ static void fb_info(struct device_d *dev)
|
|||
fb_print_modes(&info->edid_modes);
|
||||
}
|
||||
|
||||
void *fb_get_screen_base(struct fb_info *info)
|
||||
{
|
||||
return info->screen_base_shadow ?
|
||||
info->screen_base_shadow : info->screen_base;
|
||||
}
|
||||
|
||||
int fb_set_shadowfb(struct param_d *p, void *priv)
|
||||
{
|
||||
struct fb_info *info = priv;
|
||||
|
||||
if (!info->enabled)
|
||||
return 0;
|
||||
|
||||
return fb_alloc_shadowfb(info);
|
||||
}
|
||||
|
||||
int register_framebuffer(struct fb_info *info)
|
||||
{
|
||||
int id = get_free_deviceid("fb");
|
||||
|
@ -243,6 +290,8 @@ int register_framebuffer(struct fb_info *info)
|
|||
for (i = 0; i < info->edid_modes.num_modes; i++)
|
||||
names[i + info->modes.num_modes] = info->edid_modes.modes[i].name;
|
||||
dev_add_param_enum(dev, "mode_name", fb_set_modename, NULL, &info->current_mode, names, num_modes, info);
|
||||
info->shadowfb = 1;
|
||||
dev_add_param_bool(dev, "shadowfb", fb_set_shadowfb, NULL, &info->shadowfb, info);
|
||||
|
||||
info->mode = fb_num_to_mode(info, 0);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct fbc_priv {
|
|||
u8 csi[256];
|
||||
|
||||
int active;
|
||||
int in_console;
|
||||
};
|
||||
|
||||
static int fbc_getc(struct console_device *cdev)
|
||||
|
@ -57,6 +58,7 @@ static void cls(struct fbc_priv *priv)
|
|||
void *buf = gui_screen_render_buffer(priv->sc);
|
||||
|
||||
memset(buf, 0, priv->fb->line_length * priv->fb->yres);
|
||||
gu_screen_blit(priv->sc);
|
||||
}
|
||||
|
||||
struct rgb {
|
||||
|
@ -137,6 +139,8 @@ static void video_invertchar(struct fbc_priv *priv, int x, int y)
|
|||
|
||||
gu_invert_area(priv->fb, buf, x * priv->font_width, y * priv->font_height,
|
||||
priv->font_width, priv->font_height);
|
||||
gu_screen_blit_area(priv->sc, x * priv->font_width, y * priv->font_height,
|
||||
priv->font_width, priv->font_height);
|
||||
}
|
||||
|
||||
static void printchar(struct fbc_priv *priv, int c)
|
||||
|
@ -169,7 +173,10 @@ static void printchar(struct fbc_priv *priv, int c)
|
|||
|
||||
default:
|
||||
drawchar(priv, priv->x, priv->y, c);
|
||||
gu_screen_blit(priv->sc);
|
||||
|
||||
gu_screen_blit_area(priv->sc, priv->x * priv->font_width,
|
||||
priv->y * priv->font_height,
|
||||
priv->font_width, priv->font_height);
|
||||
|
||||
priv->x++;
|
||||
if (priv->x > priv->cols) {
|
||||
|
@ -187,6 +194,7 @@ static void printchar(struct fbc_priv *priv, int c)
|
|||
|
||||
memcpy(buf, buf + line_height, line_height * (priv->rows + 1));
|
||||
memset(buf + line_height * priv->rows, 0, line_height);
|
||||
gu_screen_blit(priv->sc);
|
||||
priv->y = priv->rows;
|
||||
}
|
||||
|
||||
|
@ -250,6 +258,7 @@ static void fbc_parse_csi(struct fbc_priv *priv)
|
|||
return;
|
||||
case 'J':
|
||||
cls(priv);
|
||||
video_invertchar(priv, priv->x, priv->y);
|
||||
return;
|
||||
case 'H':
|
||||
video_invertchar(priv, priv->x, priv->y);
|
||||
|
@ -282,6 +291,10 @@ static void fbc_putc(struct console_device *cdev, char c)
|
|||
struct fbc_priv *priv = container_of(cdev,
|
||||
struct fbc_priv, cdev);
|
||||
|
||||
if (priv->in_console)
|
||||
return;
|
||||
priv->in_console = 1;
|
||||
|
||||
switch (priv->state) {
|
||||
case LIT:
|
||||
switch (c) {
|
||||
|
@ -329,6 +342,7 @@ static void fbc_putc(struct console_device *cdev, char c)
|
|||
}
|
||||
break;
|
||||
}
|
||||
priv->in_console = 0;
|
||||
}
|
||||
|
||||
static int setup_font(struct fbc_priv *priv)
|
||||
|
@ -370,7 +384,7 @@ static int fbc_set_active(struct console_device *cdev, unsigned flags)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sc = fb_create_screen(fb, 0);
|
||||
priv->sc = fb_create_screen(fb);
|
||||
if (IS_ERR(priv->sc))
|
||||
return PTR_ERR(priv->sc);
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ struct fb_info {
|
|||
struct device_d dev; /* This is this fb device */
|
||||
|
||||
void *screen_base;
|
||||
void *screen_base_shadow;
|
||||
unsigned long screen_size;
|
||||
|
||||
void *priv;
|
||||
|
@ -141,6 +142,7 @@ struct fb_info {
|
|||
int register_simplefb; /* If true a simplefb device node will
|
||||
* be created.
|
||||
*/
|
||||
int shadowfb;
|
||||
};
|
||||
|
||||
struct display_timings *of_get_display_timings(struct device_node *np);
|
||||
|
@ -167,5 +169,6 @@ void fb_edid_add_modes(struct fb_info *info);
|
|||
void fb_of_reserve_add_fixup(struct fb_info *info);
|
||||
|
||||
int register_fbconsole(struct fb_info *fb);
|
||||
void *fb_get_screen_base(struct fb_info *info);
|
||||
|
||||
#endif /* __FB_H */
|
||||
|
|
|
@ -19,11 +19,13 @@ void gu_set_pixel(struct fb_info *info, void *adr, u32 px);
|
|||
void gu_set_rgb_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b);
|
||||
void gu_set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a);
|
||||
void gu_memset_pixel(struct fb_info *info, void* buf, u32 color, size_t size);
|
||||
struct screen *fb_create_screen(struct fb_info *info, bool offscreen);
|
||||
struct screen *fb_open(const char *fbdev, bool offscreen);
|
||||
struct screen *fb_create_screen(struct fb_info *info);
|
||||
struct screen *fb_open(const char *fbdev);
|
||||
void fb_close(struct screen *sc);
|
||||
void gu_screen_blit(struct screen *sc);
|
||||
void gu_invert_area(struct fb_info *info, void *buf, int startx, int starty, int width,
|
||||
int height);
|
||||
void gu_screen_blit_area(struct screen *sc, int startx, int starty, int width,
|
||||
int height);
|
||||
|
||||
#endif /* __GRAPHIC_UTILS_H__ */
|
||||
|
|
|
@ -23,16 +23,12 @@ struct screen {
|
|||
struct surface s;
|
||||
|
||||
void *fb;
|
||||
void *offscreenbuf;
|
||||
int fbsize;
|
||||
};
|
||||
|
||||
static inline void *gui_screen_render_buffer(struct screen *sc)
|
||||
{
|
||||
if (sc->offscreenbuf)
|
||||
return sc->offscreenbuf;
|
||||
return sc->fb;
|
||||
return fb_get_screen_base(sc->info);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __GUI_H__ */
|
||||
|
|
|
@ -245,7 +245,7 @@ void gu_rgba_blend(struct fb_info *info, struct image *img, void* buf, int heigh
|
|||
}
|
||||
}
|
||||
|
||||
struct screen *fb_create_screen(struct fb_info *info, bool offscreen)
|
||||
struct screen *fb_create_screen(struct fb_info *info)
|
||||
{
|
||||
struct screen *sc;
|
||||
|
||||
|
@ -257,19 +257,12 @@ struct screen *fb_create_screen(struct fb_info *info, bool offscreen)
|
|||
sc->s.height = info->yres;
|
||||
sc->fbsize = info->line_length * sc->s.height;
|
||||
sc->fb = info->screen_base;
|
||||
|
||||
if (offscreen) {
|
||||
/*
|
||||
* Don't fail if malloc fails, just continue rendering directly
|
||||
* on the framebuffer
|
||||
*/
|
||||
sc->offscreenbuf = malloc(sc->fbsize);
|
||||
}
|
||||
sc->info = info;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
struct screen *fb_open(const char * fbdev, bool offscreen)
|
||||
struct screen *fb_open(const char * fbdev)
|
||||
{
|
||||
int fd, ret;
|
||||
struct fb_info *info;
|
||||
|
@ -281,12 +274,12 @@ struct screen *fb_open(const char * fbdev, bool offscreen)
|
|||
|
||||
info = xzalloc(sizeof(*info));
|
||||
|
||||
ret = ioctl(fd, FBIOGET_SCREENINFO, info);
|
||||
ret = ioctl(fd, FBIOGET_SCREENINFO, &info);
|
||||
if (ret) {
|
||||
goto failed_screeninfo;
|
||||
}
|
||||
|
||||
sc = fb_create_screen(info, offscreen);
|
||||
sc = fb_create_screen(info);
|
||||
if (IS_ERR(sc)) {
|
||||
ret = PTR_ERR(sc);
|
||||
goto failed_create;
|
||||
|
@ -298,7 +291,6 @@ struct screen *fb_open(const char * fbdev, bool offscreen)
|
|||
return sc;
|
||||
|
||||
failed_create:
|
||||
free(sc->offscreenbuf);
|
||||
free(sc);
|
||||
failed_screeninfo:
|
||||
close(fd);
|
||||
|
@ -308,20 +300,35 @@ failed_screeninfo:
|
|||
|
||||
void fb_close(struct screen *sc)
|
||||
{
|
||||
free(sc->offscreenbuf);
|
||||
|
||||
if (sc->fd > 0) {
|
||||
if (sc->fd > 0)
|
||||
close(sc->fd);
|
||||
free(sc->info);
|
||||
}
|
||||
|
||||
free(sc);
|
||||
}
|
||||
|
||||
void gu_screen_blit_area(struct screen *sc, int startx, int starty, int width,
|
||||
int height)
|
||||
{
|
||||
struct fb_info *info = sc->info;
|
||||
int bpp = info->bits_per_pixel >> 3;
|
||||
|
||||
if (info->screen_base_shadow) {
|
||||
int y;
|
||||
void *fb = info->screen_base + starty * sc->info->line_length + startx * bpp;
|
||||
void *fboff = info->screen_base_shadow + starty * sc->info->line_length + startx * bpp;
|
||||
|
||||
for (y = starty; y < starty + height; y++) {
|
||||
memcpy(fb, fboff, width * bpp);
|
||||
fb += sc->info->line_length;
|
||||
fboff += sc->info->line_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gu_screen_blit(struct screen *sc)
|
||||
{
|
||||
if (!sc->offscreenbuf)
|
||||
return;
|
||||
struct fb_info *info = sc->info;
|
||||
|
||||
memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
|
||||
if (info->screen_base_shadow)
|
||||
memcpy(info->screen_base, info->screen_base_shadow, sc->fbsize);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue