graphic_utils: introduce common fb_open/close
To open, memmap, get the fb_info and if needed allocate the offscreen buffer Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
3fa8d74abe
commit
9a048064e4
|
@ -1,11 +1,8 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <fs.h>
|
|
||||||
#include <linux/stat.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <gui/image_renderer.h>
|
#include <gui/image_renderer.h>
|
||||||
#include <gui/graphic_utils.h>
|
#include <gui/graphic_utils.h>
|
||||||
|
@ -52,39 +49,18 @@ static int do_splash(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
image_file = argv[optind];
|
image_file = argv[optind];
|
||||||
|
|
||||||
fd = open(fbdev, O_RDWR);
|
fd = fb_open(fbdev, &sc, offscreen);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
perror("open");
|
perror("fd_open");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.fb = memmap(fd, PROT_READ | PROT_WRITE);
|
if (sc.offscreenbuf) {
|
||||||
if (sc.fb == (void *)-1) {
|
if (do_bg)
|
||||||
perror("memmap");
|
memset_pixel(&info, sc.offscreenbuf, bg_color,
|
||||||
goto failed_memmap;
|
sc.s.width * sc.s.height);
|
||||||
}
|
else
|
||||||
|
memcpy(sc.offscreenbuf, sc.fb, sc.fbsize);
|
||||||
ret = ioctl(fd, FBIOGET_SCREENINFO, &info);
|
|
||||||
if (ret) {
|
|
||||||
perror("ioctl");
|
|
||||||
goto failed_memmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offscreen) {
|
|
||||||
int fbsize;
|
|
||||||
/* Don't fail if malloc fails, just continue rendering directly
|
|
||||||
* on the framebuffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
fbsize = sc.s.x * sc.s.x * (sc.info.bits_per_pixel >> 3);
|
|
||||||
sc.offscreenbuf = malloc(fbsize);
|
|
||||||
if (sc.offscreenbuf) {
|
|
||||||
if (do_bg)
|
|
||||||
memset_pixel(&info, sc.offscreenbuf, bg_color,
|
|
||||||
sc.s.width * sc.s.height);
|
|
||||||
else
|
|
||||||
memcpy(sc.offscreenbuf, sc.fb, fbsize);
|
|
||||||
}
|
|
||||||
} else if (do_bg) {
|
} else if (do_bg) {
|
||||||
memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height);
|
memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height);
|
||||||
}
|
}
|
||||||
|
@ -92,17 +68,9 @@ static int do_splash(int argc, char *argv[])
|
||||||
if (image_renderer_file(&sc, &s, image_file) < 0)
|
if (image_renderer_file(&sc, &s, image_file) < 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
if (sc.offscreenbuf)
|
fb_close(&sc);
|
||||||
free(sc.offscreenbuf);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
failed_memmap:
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAREBOX_CMD_HELP_START(splash)
|
BAREBOX_CMD_HELP_START(splash)
|
||||||
|
|
|
@ -17,6 +17,7 @@ void set_pixel(struct fb_info *info, void *adr, u32 px);
|
||||||
void set_rgb_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b);
|
void set_rgb_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b);
|
||||||
void set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a);
|
void set_rgba_pixel(struct fb_info *info, void *adr, u8 r, u8 g, u8 b, u8 a);
|
||||||
void memset_pixel(struct fb_info *info, void* buf, u32 color, size_t size);
|
void memset_pixel(struct fb_info *info, void* buf, u32 color, size_t size);
|
||||||
int fb_open(const char * fbdev, struct screen *sc);
|
int fb_open(const char * fbdev, struct screen *sc, bool offscreen);
|
||||||
|
void fb_close(struct screen *sc);
|
||||||
|
|
||||||
#endif /* __GRAPHIC_UTILS_H__ */
|
#endif /* __GRAPHIC_UTILS_H__ */
|
||||||
|
|
|
@ -17,12 +17,14 @@ struct surface {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct screen {
|
struct screen {
|
||||||
|
int fd;
|
||||||
struct fb_info info;
|
struct fb_info info;
|
||||||
|
|
||||||
struct surface s;
|
struct surface s;
|
||||||
|
|
||||||
void *fb;
|
void *fb;
|
||||||
void *offscreenbuf;
|
void *offscreenbuf;
|
||||||
|
int fbsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void* gui_screen_redering_buffer(struct screen *sc)
|
static inline void* gui_screen_redering_buffer(struct screen *sc)
|
||||||
|
|
|
@ -37,7 +37,7 @@ void bmp_close(struct image *img)
|
||||||
static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
|
static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
{
|
{
|
||||||
struct bmp_image *bmp = img->data;
|
struct bmp_image *bmp = img->data;
|
||||||
int bits_per_pixel, fbsize;
|
int bits_per_pixel;
|
||||||
void *adr, *buf;
|
void *adr, *buf;
|
||||||
char *image;
|
char *image;
|
||||||
int width = s->width;
|
int width = s->width;
|
||||||
|
@ -69,7 +69,6 @@ static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
buf = gui_screen_redering_buffer(sc);
|
buf = gui_screen_redering_buffer(sc);
|
||||||
|
|
||||||
bits_per_pixel = img->bits_per_pixel;
|
bits_per_pixel = img->bits_per_pixel;
|
||||||
fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
|
|
||||||
|
|
||||||
if (bits_per_pixel == 8) {
|
if (bits_per_pixel == 8) {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -119,7 +118,7 @@ static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
|
printf("bmp: illegal bits per pixel value: %d\n", bits_per_pixel);
|
||||||
|
|
||||||
if (sc->offscreenbuf)
|
if (sc->offscreenbuf)
|
||||||
memcpy(sc->fb, sc->offscreenbuf, fbsize);
|
memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
|
||||||
|
|
||||||
return img->height;
|
return img->height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <gui/graphic_utils.h>
|
#include <gui/graphic_utils.h>
|
||||||
|
#include <linux/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
static u32 get_pixel(struct fb_info *info, u32 color)
|
static u32 get_pixel(struct fb_info *info, u32 color)
|
||||||
{
|
{
|
||||||
|
@ -190,3 +195,50 @@ void rgba_blend(struct fb_info *info, struct image *img, void* buf, int height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fb_open(const char * fbdev, struct screen *sc, bool offscreen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
sc->fd = open(fbdev, O_RDWR);
|
||||||
|
if (sc->fd < 0)
|
||||||
|
return sc->fd;
|
||||||
|
|
||||||
|
sc->fb = memmap(sc->fd, PROT_READ | PROT_WRITE);
|
||||||
|
if (sc->fb == (void *)-1) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto failed_memmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ioctl(sc->fd, FBIOGET_SCREENINFO, &sc->info);
|
||||||
|
if (ret) {
|
||||||
|
goto failed_memmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc->s.x = 0;
|
||||||
|
sc->s.y = 0;
|
||||||
|
sc->s.width = sc->info.xres;
|
||||||
|
sc->s.height = sc->info.yres;
|
||||||
|
sc->fbsize = sc->s.x * sc->s.x * (sc->info.bits_per_pixel >> 3);
|
||||||
|
|
||||||
|
if (offscreen) {
|
||||||
|
/* Don't fail if malloc fails, just continue rendering directly
|
||||||
|
* on the framebuffer
|
||||||
|
*/
|
||||||
|
sc->offscreenbuf = malloc(sc->fbsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sc->fd;
|
||||||
|
|
||||||
|
failed_memmap:
|
||||||
|
sc->fb = NULL;
|
||||||
|
close(sc->fd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fb_close(struct screen *sc)
|
||||||
|
{
|
||||||
|
free(sc->offscreenbuf);
|
||||||
|
close(sc->fd);
|
||||||
|
}
|
||||||
|
|
|
@ -69,12 +69,8 @@ static int png_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
|
|
||||||
rgba_blend(&sc->info, img, buf, height, width, startx, starty, true);
|
rgba_blend(&sc->info, img, buf, height, width, startx, starty, true);
|
||||||
|
|
||||||
if (sc->offscreenbuf) {
|
if (sc->offscreenbuf)
|
||||||
int fbsize;
|
memcpy(sc->fb, sc->offscreenbuf, sc->fbsize);
|
||||||
|
|
||||||
fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
|
|
||||||
memcpy(sc->fb, sc->offscreenbuf, fbsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
return img->height;
|
return img->height;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue