gui: introduce screen and surface to factorize and simplify code
Instead of passing hundreds of parameter, just pass the right structure. struct screen represent the screen with a without double buffering. struct surface represent the part of the screen we want to render. 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
21a8ef55b0
commit
3fa8d74abe
|
@ -12,17 +12,20 @@
|
||||||
|
|
||||||
static int do_splash(int argc, char *argv[])
|
static int do_splash(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
struct surface s;
|
||||||
|
struct screen sc;
|
||||||
int ret, opt, fd;
|
int ret, opt, fd;
|
||||||
char *fbdev = "/dev/fb0";
|
char *fbdev = "/dev/fb0";
|
||||||
void *fb;
|
|
||||||
struct fb_info info;
|
struct fb_info info;
|
||||||
char *image_file;
|
char *image_file;
|
||||||
int startx = -1, starty = -1;
|
|
||||||
int xres, yres;
|
|
||||||
int offscreen = 0;
|
int offscreen = 0;
|
||||||
u32 bg_color = 0x00000000;
|
u32 bg_color = 0x00000000;
|
||||||
bool do_bg = false;
|
bool do_bg = false;
|
||||||
void *offscreenbuf = NULL;
|
|
||||||
|
s.x = -1;
|
||||||
|
s.y = -1;
|
||||||
|
s.width = -1;
|
||||||
|
s.height = -1;
|
||||||
|
|
||||||
while((opt = getopt(argc, argv, "f:x:y:ob:")) > 0) {
|
while((opt = getopt(argc, argv, "f:x:y:ob:")) > 0) {
|
||||||
switch(opt) {
|
switch(opt) {
|
||||||
|
@ -34,10 +37,10 @@ static int do_splash(int argc, char *argv[])
|
||||||
do_bg = true;
|
do_bg = true;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
startx = simple_strtoul(optarg, NULL, 0);
|
s.x = simple_strtoul(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
starty = simple_strtoul(optarg, NULL, 0);
|
s.y = simple_strtoul(optarg, NULL, 0);
|
||||||
case 'o':
|
case 'o':
|
||||||
offscreen = 1;
|
offscreen = 1;
|
||||||
}
|
}
|
||||||
|
@ -55,8 +58,8 @@ static int do_splash(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fb = memmap(fd, PROT_READ | PROT_WRITE);
|
sc.fb = memmap(fd, PROT_READ | PROT_WRITE);
|
||||||
if (fb == (void *)-1) {
|
if (sc.fb == (void *)-1) {
|
||||||
perror("memmap");
|
perror("memmap");
|
||||||
goto failed_memmap;
|
goto failed_memmap;
|
||||||
}
|
}
|
||||||
|
@ -67,33 +70,30 @@ static int do_splash(int argc, char *argv[])
|
||||||
goto failed_memmap;
|
goto failed_memmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
xres = info.xres;
|
|
||||||
yres = info.yres;
|
|
||||||
|
|
||||||
if (offscreen) {
|
if (offscreen) {
|
||||||
int fbsize;
|
int fbsize;
|
||||||
/* Don't fail if malloc fails, just continue rendering directly
|
/* Don't fail if malloc fails, just continue rendering directly
|
||||||
* on the framebuffer
|
* on the framebuffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fbsize = xres * yres * (info.bits_per_pixel >> 3);
|
fbsize = sc.s.x * sc.s.x * (sc.info.bits_per_pixel >> 3);
|
||||||
offscreenbuf = malloc(fbsize);
|
sc.offscreenbuf = malloc(fbsize);
|
||||||
if (offscreenbuf) {
|
if (sc.offscreenbuf) {
|
||||||
if (do_bg)
|
if (do_bg)
|
||||||
memset_pixel(&info, offscreenbuf, bg_color, xres * yres);
|
memset_pixel(&info, sc.offscreenbuf, bg_color,
|
||||||
|
sc.s.width * sc.s.height);
|
||||||
else
|
else
|
||||||
memcpy(offscreenbuf, fb, fbsize);
|
memcpy(sc.offscreenbuf, sc.fb, fbsize);
|
||||||
}
|
}
|
||||||
} else if (do_bg) {
|
} else if (do_bg) {
|
||||||
memset_pixel(&info, fb, bg_color, xres * yres);
|
memset_pixel(&info, sc.fb, bg_color, sc.s.width * sc.s.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image_renderer_file(&info, image_file, fb, startx, starty,
|
if (image_renderer_file(&sc, &s, image_file) < 0)
|
||||||
offscreenbuf) < 0)
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
if (offscreenbuf)
|
if (sc.offscreenbuf)
|
||||||
free(offscreenbuf);
|
free(sc.offscreenbuf);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <gui/image.h>
|
#include <gui/image.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
|
||||||
void rgba_blend(struct fb_info *info, struct image *img, void* dest, int height,
|
void rgba_blend(struct fb_info *info, struct image *img, void* dest, int height,
|
||||||
int width, int startx, int starty, bool is_rgba);
|
int width, int startx, int starty, bool is_rgba);
|
||||||
|
@ -16,5 +17,6 @@ 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);
|
||||||
|
|
||||||
#endif /* __GRAPHIC_UTILS_H__ */
|
#endif /* __GRAPHIC_UTILS_H__ */
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
|
||||||
|
*
|
||||||
|
* GPL v2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GUI_H__
|
||||||
|
#define __GUI_H__
|
||||||
|
|
||||||
|
#include <fb.h>
|
||||||
|
|
||||||
|
struct surface {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct screen {
|
||||||
|
struct fb_info info;
|
||||||
|
|
||||||
|
struct surface s;
|
||||||
|
|
||||||
|
void *fb;
|
||||||
|
void *offscreenbuf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void* gui_screen_redering_buffer(struct screen *sc)
|
||||||
|
{
|
||||||
|
if (sc->offscreenbuf)
|
||||||
|
return sc->offscreenbuf;
|
||||||
|
return sc->fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __GUI_H__ */
|
|
@ -13,13 +13,13 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <gui/image.h>
|
#include <gui/image.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
|
||||||
struct image_renderer {
|
struct image_renderer {
|
||||||
enum filetype type;
|
enum filetype type;
|
||||||
struct image *(*open)(char *data, int size);
|
struct image *(*open)(char *data, int size);
|
||||||
void (*close)(struct image *img);
|
void (*close)(struct image *img);
|
||||||
int (*renderer)(struct fb_info *info, struct image *img, void* fb,
|
int (*renderer)(struct screen *sc, struct surface *s, struct image *img);
|
||||||
int startx, int starty, void* offscreenbuf);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do not free the data read from the file
|
* do not free the data read from the file
|
||||||
|
@ -34,8 +34,7 @@ struct image_renderer {
|
||||||
int image_renderer_register(struct image_renderer *ir);
|
int image_renderer_register(struct image_renderer *ir);
|
||||||
void image_render_unregister(struct image_renderer *ir);
|
void image_render_unregister(struct image_renderer *ir);
|
||||||
|
|
||||||
int image_renderer_image(struct fb_info *info, struct image *img, void* fb,
|
int image_renderer_image(struct screen *sc, struct surface *s, struct image *img);
|
||||||
int startx, int starty, void* offscreenbuf);
|
|
||||||
|
|
||||||
struct image *image_renderer_open(const char* file);
|
struct image *image_renderer_open(const char* file);
|
||||||
void image_renderer_close(struct image *img);
|
void image_renderer_close(struct image *img);
|
||||||
|
@ -54,12 +53,10 @@ static inline struct image *image_renderer_open(const char* file)
|
||||||
|
|
||||||
static inline void image_renderer_close(struct image *img) {}
|
static inline void image_renderer_close(struct image *img) {}
|
||||||
|
|
||||||
int image_renderer_image(struct fb_info *info, struct image *img, void* fb,
|
int image_renderer_image(struct surface *s, struct image *img);
|
||||||
int startx, int starty, void* offscreenbuf);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline int image_renderer_file(struct fb_info *info, const char* file, void* fb,
|
static inline int image_renderer_file(struct screen *sc, struct surface *s, const char* file)
|
||||||
int startx, int starty, void* offscreenbuf)
|
|
||||||
{
|
{
|
||||||
struct image* img = image_renderer_open(file);
|
struct image* img = image_renderer_open(file);
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -67,8 +64,7 @@ static inline int image_renderer_file(struct fb_info *info, const char* file, vo
|
||||||
if (IS_ERR(img))
|
if (IS_ERR(img))
|
||||||
return PTR_ERR(img);
|
return PTR_ERR(img);
|
||||||
|
|
||||||
ret = image_renderer_image(info, img, fb, startx, starty,
|
ret = image_renderer_image(sc, s, img);
|
||||||
offscreenbuf);
|
|
||||||
|
|
||||||
image_renderer_close(img);
|
image_renderer_close(img);
|
||||||
|
|
||||||
|
|
|
@ -34,38 +34,42 @@ void bmp_close(struct image *img)
|
||||||
free(img->data);
|
free(img->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bmp_renderer(struct fb_info *info, struct image *img, void* fb,
|
static int bmp_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
int startx, int starty, void* offscreenbuf)
|
|
||||||
{
|
{
|
||||||
struct bmp_image *bmp = img->data;
|
struct bmp_image *bmp = img->data;
|
||||||
int width, height;
|
|
||||||
int bits_per_pixel, fbsize;
|
int bits_per_pixel, fbsize;
|
||||||
void *adr, *buf;
|
void *adr, *buf;
|
||||||
char *image;
|
char *image;
|
||||||
int xres, yres;
|
int width = s->width;
|
||||||
|
int height = s->height;
|
||||||
|
int startx = s->x;
|
||||||
|
int starty = s->y;
|
||||||
|
|
||||||
xres = info->xres;
|
if (s->width < 0)
|
||||||
yres = info->yres;
|
width = img->width;
|
||||||
|
|
||||||
|
if (s->height < 0)
|
||||||
|
height = img->height;
|
||||||
|
|
||||||
if (startx < 0) {
|
if (startx < 0) {
|
||||||
startx = (xres - img->width) / 2;
|
startx = (sc->s.width - width) / 2;
|
||||||
if (startx < 0)
|
if (startx < 0)
|
||||||
startx = 0;
|
startx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starty < 0) {
|
if (starty < 0) {
|
||||||
starty = (yres - img->height) / 2;
|
starty = (sc->s.height - height) / 2;
|
||||||
if (starty < 0)
|
if (starty < 0)
|
||||||
starty = 0;
|
starty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = min(img->width, xres - startx);
|
width = min(width, sc->s.width - startx);
|
||||||
height = min(img->height, yres - starty);
|
height = min(height, sc->s.height - starty);
|
||||||
|
|
||||||
|
buf = gui_screen_redering_buffer(sc);
|
||||||
|
|
||||||
bits_per_pixel = img->bits_per_pixel;
|
bits_per_pixel = img->bits_per_pixel;
|
||||||
fbsize = xres * yres * (info->bits_per_pixel >> 3);
|
fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
|
||||||
|
|
||||||
buf = offscreenbuf ? offscreenbuf : fb;
|
|
||||||
|
|
||||||
if (bits_per_pixel == 8) {
|
if (bits_per_pixel == 8) {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -75,17 +79,17 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb,
|
||||||
image = (char *)bmp +
|
image = (char *)bmp +
|
||||||
le32_to_cpu(bmp->header.data_offset);
|
le32_to_cpu(bmp->header.data_offset);
|
||||||
image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3);
|
image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3);
|
||||||
adr = buf + ((y + starty) * xres + startx) *
|
adr = buf + ((y + starty) * sc->s.width + startx) *
|
||||||
(info->bits_per_pixel >> 3);
|
(sc->info.bits_per_pixel >> 3);
|
||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
int pixel;
|
int pixel;
|
||||||
|
|
||||||
pixel = *image;
|
pixel = *image;
|
||||||
|
|
||||||
set_rgb_pixel(info, adr, color_table[pixel].red,
|
set_rgb_pixel(&sc->info, adr, color_table[pixel].red,
|
||||||
color_table[pixel].green,
|
color_table[pixel].green,
|
||||||
color_table[pixel].blue);
|
color_table[pixel].blue);
|
||||||
adr += info->bits_per_pixel >> 3;
|
adr += sc->info.bits_per_pixel >> 3;
|
||||||
|
|
||||||
image += bits_per_pixel >> 3;
|
image += bits_per_pixel >> 3;
|
||||||
}
|
}
|
||||||
|
@ -97,16 +101,16 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb,
|
||||||
image = (char *)bmp +
|
image = (char *)bmp +
|
||||||
le32_to_cpu(bmp->header.data_offset);
|
le32_to_cpu(bmp->header.data_offset);
|
||||||
image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3);
|
image += (img->height - y - 1) * img->width * (bits_per_pixel >> 3);
|
||||||
adr = buf + ((y + starty) * xres + startx) *
|
adr = buf + ((y + starty) * sc->s.width + startx) *
|
||||||
(info->bits_per_pixel >> 3);
|
(sc->info.bits_per_pixel >> 3);
|
||||||
for (x = 0; x < width; x++) {
|
for (x = 0; x < width; x++) {
|
||||||
char *pixel;
|
char *pixel;
|
||||||
|
|
||||||
pixel = image;
|
pixel = image;
|
||||||
|
|
||||||
set_rgb_pixel(info, adr, pixel[2], pixel[1],
|
set_rgb_pixel(&sc->info, adr, pixel[2], pixel[1],
|
||||||
pixel[0]);
|
pixel[0]);
|
||||||
adr += info->bits_per_pixel >> 3;
|
adr += sc->info.bits_per_pixel >> 3;
|
||||||
|
|
||||||
image += bits_per_pixel >> 3;
|
image += bits_per_pixel >> 3;
|
||||||
}
|
}
|
||||||
|
@ -114,8 +118,8 @@ static int bmp_renderer(struct fb_info *info, struct image *img, void* fb,
|
||||||
} else
|
} else
|
||||||
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 (offscreenbuf)
|
if (sc->offscreenbuf)
|
||||||
memcpy(fb, offscreenbuf, fbsize);
|
memcpy(sc->fb, sc->offscreenbuf, fbsize);
|
||||||
|
|
||||||
return img->height;
|
return img->height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,9 @@ void image_renderer_close(struct image *img)
|
||||||
free(img);
|
free(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_renderer_image(struct fb_info *info, struct image *img, void* fb,
|
int image_renderer_image(struct screen *sc, struct surface *s, struct image *img)
|
||||||
int startx, int starty, void* offscreenbuf)
|
|
||||||
{
|
{
|
||||||
return img->ir->renderer(info, img, fb, startx, starty, offscreenbuf);
|
return img->ir->renderer(sc, s, img);
|
||||||
}
|
}
|
||||||
|
|
||||||
int image_renderer_register(struct image_renderer *ir)
|
int image_renderer_register(struct image_renderer *ir)
|
||||||
|
|
|
@ -36,40 +36,44 @@ void png_uncompress_exit(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int png_renderer(struct fb_info *info, struct image *img, void* fb,
|
static int png_renderer(struct screen *sc, struct surface *s, struct image *img)
|
||||||
int startx, int starty, void* offscreenbuf)
|
|
||||||
{
|
{
|
||||||
int width, height;
|
|
||||||
void *buf;
|
void *buf;
|
||||||
int xres, yres;
|
int width = s->width;
|
||||||
|
int height = s->height;
|
||||||
|
int startx = s->x;
|
||||||
|
int starty = s->y;
|
||||||
|
|
||||||
xres = info->xres;
|
if (s->width < 0)
|
||||||
yres = info->yres;
|
width = img->width;
|
||||||
|
|
||||||
|
if (s->height < 0)
|
||||||
|
height = img->height;
|
||||||
|
|
||||||
if (startx < 0) {
|
if (startx < 0) {
|
||||||
startx = (xres - img->width) / 2;
|
startx = (sc->s.width - width) / 2;
|
||||||
if (startx < 0)
|
if (startx < 0)
|
||||||
startx = 0;
|
startx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (starty < 0) {
|
if (starty < 0) {
|
||||||
starty = (yres - img->height) / 2;
|
starty = (sc->s.height - height) / 2;
|
||||||
if (starty < 0)
|
if (starty < 0)
|
||||||
starty = 0;
|
starty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = min(img->width, xres - startx);
|
width = min(width, sc->s.width - startx);
|
||||||
height = min(img->height, yres - starty);
|
height = min(height, sc->s.height - starty);
|
||||||
|
|
||||||
buf = offscreenbuf ? offscreenbuf : fb;
|
buf = gui_screen_redering_buffer(sc);
|
||||||
|
|
||||||
rgba_blend(info, img, buf, height, width, startx, starty, true);
|
rgba_blend(&sc->info, img, buf, height, width, startx, starty, true);
|
||||||
|
|
||||||
if (offscreenbuf) {
|
if (sc->offscreenbuf) {
|
||||||
int fbsize;
|
int fbsize;
|
||||||
|
|
||||||
fbsize = xres * yres * (info->bits_per_pixel >> 3);
|
fbsize = sc->s.width * sc->s.height * (sc->info.bits_per_pixel >> 3);
|
||||||
memcpy(fb, offscreenbuf, fbsize);
|
memcpy(sc->fb, sc->offscreenbuf, fbsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return img->height;
|
return img->height;
|
||||||
|
|
Loading…
Reference in New Issue