[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