9
0
Fork 0

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:
Jean-Christophe PLAGNIOL-VILLARD 2012-09-26 11:59:02 +02:00 committed by Sascha Hauer
parent 21a8ef55b0
commit 3fa8d74abe
7 changed files with 113 additions and 72 deletions

View File

@ -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);

View File

@ -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__ */

36
include/gui/gui.h Normal file
View File

@ -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__ */

View File

@ -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);

View File

@ -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;
} }

View File

@ -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)

View File

@ -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;