[PATCH 1/1] sandbox: add sdl video support
Sascha Hauer
s.hauer at pengutronix.de
Tue Sep 25 04:16:18 EDT 2012
On Wed, Sep 12, 2012 at 03:38:42PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> This will allow speed up the dev on framebuffer.
>
> By default the resolution is VGA but this can be changed via cmdline.
>
> We use a pthread to Flip the screen every 100ms as we can not detect when
> barebox update it as barebox simpliy write in a buffer.
>
> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Applied, thanks
Sascha
> ---
> arch/sandbox/Kconfig | 3 +
> arch/sandbox/Makefile | 6 +-
> arch/sandbox/board/board.c | 21 +++++
> arch/sandbox/mach-sandbox/include/mach/linux.h | 13 +++
> arch/sandbox/os/Makefile | 2 +
> arch/sandbox/os/common.c | 25 +++++-
> arch/sandbox/os/sdl.c | 108 ++++++++++++++++++++++++
> drivers/video/Kconfig | 4 +
> drivers/video/Makefile | 1 +
> drivers/video/sdl.c | 101 ++++++++++++++++++++++
> 10 files changed, 279 insertions(+), 5 deletions(-)
> create mode 100644 arch/sandbox/os/sdl.c
> create mode 100644 drivers/video/sdl.c
>
> diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
> index 10e6829..84fadda 100644
> --- a/arch/sandbox/Kconfig
> +++ b/arch/sandbox/Kconfig
> @@ -1,3 +1,6 @@
> +config SANDBOX
> + bool
> + default y
>
> config ARCH_TEXT_BASE
> hex
> diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
> index 9fd18a2..c0aa8c6 100644
> --- a/arch/sandbox/Makefile
> +++ b/arch/sandbox/Makefile
> @@ -9,8 +9,7 @@ lds-y := $(BOARD)/barebox.lds
>
>
> TEXT_BASE = $(CONFIG_TEXT_BASE)
> -
> -CFLAGS += -Dmalloc=barebox_malloc \
> +CFLAGS += -Dmalloc=barebox_malloc -Dcalloc=barebox_calloc \
> -Dfree=barebox_free -Drealloc=barebox_realloc \
> -Dread=barebox_read -Dwrite=barebox_write \
> -Dopen=barebox_open -Dclose=barebox_close \
> @@ -40,9 +39,10 @@ archprepare: maketools
>
> PHONY += maketools
>
> +SDL_LIBS-$(CONFIG_DRIVER_VIDEO_SDL) := $(shell pkg-config sdl --libs)
> cmd_barebox__ = $(CC) -o $@ -Wl,-T,$(barebox-lds) \
> -Wl,--start-group $(barebox-common) -Wl,--end-group \
> - -lrt -lpthread
> + -lrt -lpthread $(SDL_LIBS-y)
>
> common-y += $(BOARD) arch/sandbox/os/
>
> diff --git a/arch/sandbox/board/board.c b/arch/sandbox/board/board.c
> index 6bccd2c..71efcc4 100644
> --- a/arch/sandbox/board/board.c
> +++ b/arch/sandbox/board/board.c
> @@ -26,16 +26,37 @@
> #include <mach/linux.h>
> #include <init.h>
> #include <errno.h>
> +#include <fb.h>
> +
> +struct fb_videomode mode = {
> + .name = "sdl", /* optional */
> + .xres = 640,
> + .yres = 480,
> +};
>
> static struct device_d tap_device = {
> .id = DEVICE_ID_DYNAMIC,
> .name = "tap",
> };
>
> +static struct device_d sdl_device = {
> + .id = DEVICE_ID_DYNAMIC,
> + .name = "sdlfb",
> + .platform_data = &mode,
> +};
> +
> static int devices_init(void)
> {
> register_device(&tap_device);
>
> + if (sdl_xres)
> + mode.xres = sdl_xres;
> +
> + if (sdl_yres)
> + mode.yres = sdl_yres;
> +
> + register_device(&sdl_device);
> +
> return 0;
> }
>
> diff --git a/arch/sandbox/mach-sandbox/include/mach/linux.h b/arch/sandbox/mach-sandbox/include/mach/linux.h
> index 5917fe9..81f4946 100644
> --- a/arch/sandbox/mach-sandbox/include/mach/linux.h
> +++ b/arch/sandbox/mach-sandbox/include/mach/linux.h
> @@ -1,6 +1,8 @@
> #ifndef __ASM_ARCH_LINUX_H
> #define __ASM_ARCH_LINUX_H
>
> +struct fb_bitfield;
> +
> int linux_register_device(const char *name, void *start, void *end);
> int tap_alloc(char *dev);
> uint64_t linux_get_time(void);
> @@ -20,4 +22,15 @@ struct linux_console_data {
> unsigned int flags;
> };
>
> +extern int sdl_xres;
> +extern int sdl_yres;
> +int sdl_init(void);
> +void sdl_close(void);
> +int sdl_open(int xres, int yres, int bpp, void* buf);
> +void sdl_stop_timer(void);
> +void sdl_start_timer(void);
> +void sdl_get_bitfield_rgba(struct fb_bitfield *r, struct fb_bitfield *g,
> + struct fb_bitfield *b, struct fb_bitfield *a);
> +void sdl_setpixel(int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
> +
> #endif /* __ASM_ARCH_LINUX_H */
> diff --git a/arch/sandbox/os/Makefile b/arch/sandbox/os/Makefile
> index dc211d9..2e65be5 100644
> --- a/arch/sandbox/os/Makefile
> +++ b/arch/sandbox/os/Makefile
> @@ -13,3 +13,5 @@ NOSTDINC_FLAGS :=
>
> obj-y = common.o tap.o
>
> +CFLAGS_sdl.o = $(shell pkg-config sdl --cflags)
> +obj-$(CONFIG_DRIVER_VIDEO_SDL) += sdl.o
> diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
> index e296574..15c9945 100644
> --- a/arch/sandbox/os/common.c
> +++ b/arch/sandbox/os/common.c
> @@ -52,6 +52,9 @@
> #include <mach/linux.h>
> #include <mach/hostfile.h>
>
> +int sdl_xres;
> +int sdl_yres;
> +
> static struct termios term_orig, term_vi;
> static char erase_char; /* the users erase character */
>
> @@ -278,10 +281,12 @@ static struct option long_options[] = {
> {"env", 1, 0, 'e'},
> {"stdout", 1, 0, 'O'},
> {"stdin", 1, 0, 'I'},
> + {"xres", 1, 0, 'x'},
> + {"yres", 1, 0, 'y'},
> {0, 0, 0, 0},
> };
>
> -static const char optstring[] = "hm:i:e:O:I:";
> +static const char optstring[] = "hm:i:e:O:I:x:y:";
>
> int main(int argc, char *argv[])
> {
> @@ -331,6 +336,12 @@ int main(int argc, char *argv[])
>
> barebox_register_console("cin", fd, -1);
> break;
> + case 'x':
> + sdl_xres = strtoul(optarg, NULL, 0);
> + break;
> + case 'y':
> + sdl_yres = strtoul(optarg, NULL, 0);
> + break;
> default:
> exit(1);
> }
> @@ -409,7 +420,9 @@ static void print_usage(const char *prgname)
> " -O, --stdout=<file> Register a file as a console capable of doing stdout.\n"
> " <file> can be a regular file or a FIFO.\n"
> " -I, --stdin=<file> Register a file as a console capable of doing stdin.\n"
> -" <file> can be a regular file or a FIFO.\n",
> +" <file> can be a regular file or a FIFO.\n"
> +" -x, --xres=<res> SDL width.\n"
> +" -y, --yres=<res> SDL height.\n",
> prgname
> );
> }
> @@ -449,6 +462,14 @@ static void print_usage(const char *prgname)
> * Register \<file\> as a console capable of doing stdin. \<file\> can be a regular
> * file or a fifo.
> *
> + * -x, --xres \<res\>
> + *
> + * Specify SDL width
> + *
> + * -y, --yres \<res\>
> + *
> + * Specify SDL height
> + *
> * @section simu_dbg How to debug barebox simulator
> *
> */
> diff --git a/arch/sandbox/os/sdl.c b/arch/sandbox/os/sdl.c
> new file mode 100644
> index 0000000..62bbc44
> --- /dev/null
> +++ b/arch/sandbox/os/sdl.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> + *
> + * GPL v2
> + */
> +
> +#include <stdio.h>
> +#include <SDL.h>
> +#include <time.h>
> +#include <signal.h>
> +#include <mach/linux.h>
> +#include <unistd.h>
> +#include <pthread.h>
> +
> +struct fb_bitfield {
> + uint32_t offset; /* beginning of bitfield */
> + uint32_t length; /* length of bitfield */
> + uint32_t msb_right; /* != 0 : Most significant bit is */
> + /* right */
> +};
> +
> +static SDL_Surface *real_screen;
> +static void *buffer = NULL;
> +pthread_t th;
> +
> +int sdl_init(void)
> +{
> + return SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
> +}
> +
> +static void sdl_copy_buffer(SDL_Surface *screen)
> +{
> + if (SDL_MUSTLOCK(screen)) {
> + if (SDL_LockSurface(screen) < 0)
> + return;
> + }
> +
> + memcpy(screen->pixels, buffer, screen->pitch * screen->h);
> +
> + if(SDL_MUSTLOCK(screen))
> + SDL_UnlockSurface(screen);
> +}
> +
> +static void *threadStart(void *ptr)
> +{
> + while (1) {
> + usleep(1000 * 100);
> +
> + sdl_copy_buffer(real_screen);
> + SDL_Flip(real_screen);
> + }
> +
> + return 0;
> +}
> +
> +void sdl_start_timer(void)
> +{
> + pthread_attr_t attr;
> + pthread_attr_init(&attr);
> + pthread_create(&th, &attr, threadStart, NULL);
> +}
> +
> +void sdl_stop_timer(void)
> +{
> + pthread_cancel(th);
> +}
> +
> +void sdl_get_bitfield_rgba(struct fb_bitfield *r, struct fb_bitfield *g,
> + struct fb_bitfield *b, struct fb_bitfield *a)
> +{
> + SDL_Surface *screen = real_screen;
> +
> + r->length = 8 - screen->format->Rloss;
> + r->offset = screen->format->Rshift;
> + g->length = 8 - screen->format->Gloss;
> + g->offset = screen->format->Gshift;
> + b->length = 8 - screen->format->Bloss;
> + b->offset = screen->format->Bshift;
> + a->length = 8 - screen->format->Aloss;
> + a->offset = screen->format->Ashift;
> +}
> +
> +int sdl_open(int xres, int yres, int bpp, void* buf)
> +{
> + int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
> +
> + if (sdl_init() < 0) {
> + printf("Could not initialize SDL: %s.\n", SDL_GetError());
> + return -1;
> + }
> +
> + real_screen = SDL_SetVideoMode(xres, yres, bpp, flags);
> + if (!real_screen) {
> + sdl_close();
> + fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
> + return -1;
> + }
> +
> + buffer = buf;
> +
> + return 0;
> +}
> +
> +void sdl_close(void)
> +{
> + sdl_stop_timer();
> + SDL_Quit();
> +}
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 519cdbf..4aa92c5 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -44,6 +44,10 @@ config DRIVER_VIDEO_S3C_VERBOSE
>
> endif
>
> +config DRIVER_VIDEO_SDL
> + bool "SDL framebuffer driver"
> + depends on SANDBOX
> +
> config DRIVER_VIDEO_PXA
> bool "PXA27x framebuffer driver"
> depends on ARCH_PXA27X
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 913c78d..77f6682 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -5,3 +5,4 @@ obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
> obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
> obj-$(CONFIG_DRIVER_VIDEO_S3C24XX) += s3c24xx.o
> obj-$(CONFIG_DRIVER_VIDEO_PXA) += pxa.o
> +obj-$(CONFIG_DRIVER_VIDEO_SDL) += sdl.o
> diff --git a/drivers/video/sdl.c b/drivers/video/sdl.c
> new file mode 100644
> index 0000000..ed083d7
> --- /dev/null
> +++ b/drivers/video/sdl.c
> @@ -0,0 +1,101 @@
> +/*
> + * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> + *
> + * GPL v2
> + */
> +
> +#include <common.h>
> +#include <driver.h>
> +#include <init.h>
> +#include <malloc.h>
> +#include <mach/linux.h>
> +#include <fb.h>
> +#include <errno.h>
> +#include <graphic_utils.h>
> +
> +static void sdlfb_enable(struct fb_info *info)
> +{
> + sdl_start_timer();
> +}
> +
> +static void sdlfb_disable(struct fb_info *info)
> +{
> + sdl_stop_timer();
> +}
> +
> +static struct fb_ops sdlfb_ops = {
> + .fb_enable = sdlfb_enable,
> + .fb_disable = sdlfb_disable,
> +};
> +
> +static int sdlfb_probe(struct device_d *dev)
> +{
> + struct fb_info *fb;
> + int ret = -EIO;
> +
> + if (!dev->platform_data)
> + return -EIO;
> +
> + fb = xzalloc(sizeof(*fb));
> + fb->mode_list = fb->mode = dev->platform_data;
> + fb->num_modes = 1;
> + fb->bits_per_pixel = 4 << 3;
> + fb->xres = fb->mode->xres;
> + fb->yres = fb->mode->yres;
> +
> + fb->priv = fb;
> + fb->fbops = &sdlfb_ops,
> +
> + fb->dev.parent = dev;
> + fb->screen_base = xzalloc(fb->xres * fb->yres *
> + fb->bits_per_pixel >> 3);
> +
> + if (sdl_open(fb->xres, fb->yres, fb->bits_per_pixel,
> + fb->screen_base))
> + goto err;
> +
> + sdl_get_bitfield_rgba(&fb->red, &fb->green, &fb->blue, &fb->transp);
> +
> + dev_dbg(dev, "red: length = %d, offset = %d\n",
> + fb->red.length, fb->red.offset);
> + dev_dbg(dev, "green: length = %d, offset = %d\n",
> + fb->green.length, fb->green.offset);
> + dev_dbg(dev, "blue: length = %d, offset = %d\n",
> + fb->blue.length, fb->blue.offset);
> + dev_dbg(dev, "transp: length = %d, offset = %d\n",
> + fb->transp.length, fb->transp.offset);
> +
> + /* add runtime hardware info */
> + dev->priv = fb;
> +
> + ret = register_framebuffer(fb);
> + if (!ret)
> + return 0;
> +
> +err:
> + kfree(fb->screen_base);
> + kfree(fb);
> + sdl_close();
> + return ret;
> +}
> +
> +static void sdlfb_remove(struct device_d *dev)
> +{
> + struct fb_info *fb = dev->priv;
> +
> + kfree(fb->screen_base);
> + kfree(fb);
> + sdl_close();
> +}
> +
> +static struct driver_d sdlfb_driver = {
> + .name = "sdlfb",
> + .probe = sdlfb_probe,
> + .remove = sdlfb_remove,
> +};
> +
> +static int sdlfb_init(void)
> +{
> + return register_driver(&sdlfb_driver);
> +}
> +device_initcall(sdlfb_init);
> --
> 1.7.10.4
>
>
> _______________________________________________
> barebox mailing list
> barebox at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the barebox
mailing list