mirror of
https://github.com/apache/nuttx.git
synced 2025-05-07 22:01:55 +08:00
drivers/video/fb.c: Add startup splashscreen option
Adds Kconfig-selected splashscreen options used when the driver is first registered * Includes a new Python script in ./tools to create RLE bitmap files * Includes default NS logo btimaps in 320x320, 160x160 and 80x80 resolutions along with their PNG files Signed-off-by: Tim Hardisty timh@jti.uk.com>
This commit is contained in:
parent
b333ad3ab5
commit
ed0c18c66c
@ -56,6 +56,102 @@ config VIDEO_FB_NPOLLWAITERS
|
||||
depends on VIDEO_FB
|
||||
default 2
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN
|
||||
bool "Enable Splashscreen when Framebuffer Driver is registered"
|
||||
depends on VIDEO_FB
|
||||
default n
|
||||
---help---
|
||||
This feature allows a splashscreen image to be displayed during the
|
||||
Framebuffer device driver register function. It provides the following
|
||||
functionality:
|
||||
- Choice of 80x80, 160x160 or 320x320 default "NX" logos
|
||||
- Alternative "out-of-tree" image as splashscreen
|
||||
- Configurable background colour (default black)
|
||||
- Bit-per-pixel choice (32/24/16/8/Greyscale/Mono) to suit the LCD used
|
||||
- Splashscreen can be set to remain displayed for 'n' seconds ('n' can be 0)
|
||||
- Splashscreen can be cleared (to black) once framebuffer device register is
|
||||
complete
|
||||
- Python "splashscreen_converter.py" tool (in NuttX tools directory) can be used
|
||||
to create custom splashscreens - note the tool restricts the number of colours
|
||||
to 256.
|
||||
|
||||
|
||||
if VIDEO_FB_SPLASHSCREEN
|
||||
|
||||
menu "Splashscreen Image Selection and Configuration"
|
||||
|
||||
choice
|
||||
prompt "Select Splashscreen Image Source"
|
||||
default VIDEO_FB_SPLASHSCREEN_NXLOGO
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_NXLOGO
|
||||
bool "Use default NuttX NX Logo"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_CUSTOM
|
||||
bool "Use Custom file as splashscreen"
|
||||
---help---
|
||||
This must be a compiled C source file, such as fb_splash.o, created
|
||||
as a c src file using the splashscreen_converter.py Python script,
|
||||
available in the nuttx/tools directory, and compiled as part of the
|
||||
build.
|
||||
Typically this would be a source file of an out-of-tree custom board.
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Select NXlogo bitmap size to use"
|
||||
default VIDEO_FB_SPLASHSCREEN_NXLOGO_160
|
||||
depends on VIDEO_FB_SPLASHSCREEN_NXLOGO
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_NXLOGO_320
|
||||
bool "320x320 pixels"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_NXLOGO_160
|
||||
bool "160x160 pixels"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_NXLOGO_80
|
||||
bool "80x80 pixels"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Select Splashscreen Bits-per-pixel (BPP)"
|
||||
default VIDEO_FB_SPLASHSCREEN_BPP32
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_BPP32
|
||||
bool "32BPP (ARGB)"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_BPP24
|
||||
bool "24BPP (RGB)"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_BPP16
|
||||
bool "16BPP (RGB565)"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_MONO
|
||||
bool "Monochrome"
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_GREY
|
||||
bool "Greyscale (8BPP)"
|
||||
|
||||
endchoice
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_BG_COLOUR
|
||||
hex "Hex (A)RGB background colour for splashscreen"
|
||||
default 0
|
||||
---help---
|
||||
default is black
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_DISP_TIME
|
||||
int "Time to sleep once Splashscreen displayed"
|
||||
default 1
|
||||
|
||||
config VIDEO_FB_SPLASHSCREEN_CLR_ON_EXIT
|
||||
bool "Clear Framebuffer memory when driver registration is complete"
|
||||
default y
|
||||
|
||||
endmenu # "Splashscreen Image Selection and Configuration"
|
||||
|
||||
endif # VIDEO_FB_SPLASHSCREEN
|
||||
|
||||
config VIDEO_STREAM
|
||||
bool "Video Stream Support"
|
||||
default n
|
||||
|
@ -32,6 +32,18 @@ ifeq ($(CONFIG_VIDEO_STREAM),y)
|
||||
CSRCS += v4l2_core.c video_framebuff.c v4l2_cap.c v4l2_m2m.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VIDEO_FB_SPLASHSCREEN),y)
|
||||
ifeq ($(CONFIG_VIDEO_FB_SPLASHSCREEN_NXLOGO),y)
|
||||
ifeq ($(CONFIG_VIDEO_FB_SPLASHSCREEN_NXLOGO_320),y)
|
||||
CSRCS += nxlogo320.c
|
||||
else ifeq ($(CONFIG_VIDEO_FB_SPLASHSCREEN_NXLOGO_160),y)
|
||||
CSRCS += nxlogo160.c
|
||||
else
|
||||
CSRCS += nxlogo80.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# These video drivers depend on I2C support
|
||||
|
||||
ifeq ($(CONFIG_I2C),y)
|
||||
|
@ -45,11 +45,34 @@
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/circbuf.h>
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
# include <nuttx/signal.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
# define SPLASH_BGCOL CONFIG_VIDEO_FB_SPLASHSCREEN_BG_COLOUR
|
||||
# define SPLASH_SLEEP CONFIG_VIDEO_FB_SPLASHSCREEN_DISP_TIME
|
||||
#
|
||||
# if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_RGBA32
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_RGB24
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_RGB16_565
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP8)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_RGB8_332
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_GREY)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_GREY
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_MONO)
|
||||
# define SPLASHSCREEN_FMT FB_FMT_MONO
|
||||
# endif /* CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32 */
|
||||
#
|
||||
#endif /* CONFIG_VIDEO_FB_SPLASHSCREEN */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -73,10 +96,8 @@ struct fb_priv_s
|
||||
|
||||
struct fb_paninfo_s
|
||||
{
|
||||
FAR struct circbuf_s buf; /* Pan buffer queued list */
|
||||
|
||||
struct wdog_s wdog; /* VSync offset timer */
|
||||
|
||||
FAR struct circbuf_s buf; /* Pan buffer queued list */
|
||||
struct wdog_s wdog; /* VSync offset timer */
|
||||
FAR struct fb_chardev_s *dev;
|
||||
};
|
||||
|
||||
@ -88,20 +109,20 @@ struct fb_paninfo_s
|
||||
|
||||
struct fb_chardev_s
|
||||
{
|
||||
FAR struct fb_vtable_s *vtable; /* Framebuffer interface */
|
||||
uint8_t plane; /* Video plan number */
|
||||
clock_t vsyncoffset; /* VSync offset ticks */
|
||||
FAR struct fb_priv_s *head;
|
||||
FAR struct fb_paninfo_s *paninfo; /* Pan info array */
|
||||
size_t paninfo_count; /* Pan info count */
|
||||
FAR struct fb_vtable_s *vtable; /* Framebuffer interface */
|
||||
uint8_t plane; /* Video plan number */
|
||||
clock_t vsyncoffset; /* VSync offset ticks */
|
||||
FAR struct fb_priv_s *head;
|
||||
FAR struct fb_paninfo_s *paninfo; /* Pan info array */
|
||||
size_t paninfo_count; /* Pan info count */
|
||||
};
|
||||
|
||||
struct fb_panelinfo_s
|
||||
{
|
||||
FAR void *fbmem; /* Start of frame buffer memory */
|
||||
size_t fblen; /* Size of the framebuffer */
|
||||
uint8_t fbcount; /* Count of frame buffer */
|
||||
uint8_t bpp; /* Bits per pixel */
|
||||
FAR void *fbmem; /* Start of frame buffer memory */
|
||||
size_t fblen; /* Size of the framebuffer */
|
||||
uint8_t fbcount; /* Count of frame buffer */
|
||||
uint8_t bpp; /* Bits per pixel */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -146,6 +167,14 @@ static int fb_munmap(FAR struct task_group_s *group,
|
||||
FAR void *start, size_t length);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
static int fb_splashscreen(FAR struct fb_videoinfo_s *vinfo,
|
||||
FAR struct fb_planeinfo_s *pinfo);
|
||||
static int fb_splash_fill(FAR struct fb_videoinfo_s *vinfo,
|
||||
FAR struct fb_planeinfo_s *pinfo,
|
||||
uint32_t colour);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -163,10 +192,138 @@ static const struct file_operations g_fb_fops =
|
||||
fb_poll /* poll */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
extern const struct palette_bitmap_s g_splscr;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
static int fb_splash_fill(FAR struct fb_videoinfo_s *vinfo,
|
||||
FAR struct fb_planeinfo_s *pinfo,
|
||||
uint32_t colour)
|
||||
{
|
||||
FAR uint8_t *row;
|
||||
int rgb_colour;
|
||||
int y;
|
||||
#if !defined(CONFIG_VIDEO_FB_SPLASHSCREEN_MONO) && \
|
||||
!defined(CONFIG_VIDEO_FB_SPLASHSCREEN_GREY) && \
|
||||
!defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32)
|
||||
const int r = (colour >> 16) & 0xff;
|
||||
const int g = (colour >> 8) & 0xff;
|
||||
const int b = (colour) & 0xff;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32
|
||||
rgb_colour = colour;
|
||||
#elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24)
|
||||
rgb_colour = MKRGB(r, g, b);
|
||||
#elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16)
|
||||
rgb_colour = MKRGB(r, g, b);
|
||||
#elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP8)
|
||||
rgb_colour = MKRGB(r, g, b);
|
||||
#elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_MONO) || \
|
||||
defined(CONFIG_VIDEO_FB_SPLASHSCREEN_GREY)
|
||||
rgb_colour = colour & 0xff; /* No conversion needed */
|
||||
#endif
|
||||
|
||||
row = (FAR uint8_t *)pinfo->fbmem;
|
||||
for (y = 0; y < (vinfo->yres - 1); y++)
|
||||
{
|
||||
memset(row, rgb_colour, pinfo->stride);
|
||||
row += pinfo->stride;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int fb_splashscreen(FAR struct fb_videoinfo_s *vinfo,
|
||||
FAR struct fb_planeinfo_s *pinfo)
|
||||
{
|
||||
FAR const struct splscr_bitmap_s *record = &g_splscr.data[0];
|
||||
FAR uint8_t *dst;
|
||||
unsigned int row;
|
||||
unsigned int nrun;
|
||||
FAR fb_pixel_t *buf;
|
||||
FAR fb_pixel_t colour;
|
||||
int ret = OK;
|
||||
|
||||
DEBUGASSERT(SPLASHSCREEN_FMT == vinfo->fmt);
|
||||
if (SPLASHSCREEN_FMT != vinfo->fmt)
|
||||
{
|
||||
gwarn("WARNING: Splashscreen format (%d) doesn't match LCD (%d)\n",
|
||||
SPLASHSCREEN_FMT, vinfo->fmt);
|
||||
}
|
||||
|
||||
DEBUGASSERT(g_splscr.width <= vinfo->xres);
|
||||
if (g_splscr.width > vinfo->xres)
|
||||
{
|
||||
gwarn("Splashscreen width %d wider than the display width: %d\n",
|
||||
(int)g_splscr.width, vinfo->xres);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DEBUGASSERT(g_splscr.height <= vinfo->yres);
|
||||
if (g_splscr.height > vinfo->yres)
|
||||
{
|
||||
gerr("ERROR: Splashscreen height %d taller than the display: %d\n",
|
||||
(int)g_splscr.height, vinfo->yres);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf = kmm_malloc(sizeof(fb_pixel_t) * g_splscr.width);
|
||||
if (buf == NULL)
|
||||
{
|
||||
gerr("ERROR: Failed to allocate memory for splashsceeb buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Centre the image and set destination to start of area to be used */
|
||||
|
||||
dst = pinfo->fbmem + (pinfo->stride *
|
||||
((vinfo->yres - g_splscr.height) / 2)) +
|
||||
(((vinfo->xres - g_splscr.width) / 2) *
|
||||
sizeof(fb_pixel_t));
|
||||
|
||||
/* Now output the rows */
|
||||
|
||||
for (row = 0; row < g_splscr.height; row++)
|
||||
{
|
||||
unsigned int width;
|
||||
FAR fb_pixel_t *bufp = buf; /* Start address of the buffer */
|
||||
|
||||
/* Process each run-length encoded pixel in the image */
|
||||
|
||||
for (width = 0; width < g_splscr.width; record++)
|
||||
{
|
||||
nrun = (unsigned int)record->npixels; /* num pixels of the colour */
|
||||
colour = g_splscr.lut[record->lookup];
|
||||
width += nrun;
|
||||
while (nrun-- > 0)
|
||||
{
|
||||
*bufp = colour; /* fill with the colour */
|
||||
bufp++;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGASSERT(width == g_splscr.width);
|
||||
gerr("ERROR: Splashscreen file RLE line length doe not match LCD\n");
|
||||
|
||||
/* copy the decoded/expanded pixel data for this row to framebuffer */
|
||||
|
||||
memcpy(dst, buf, sizeof(fb_pixel_t) * g_splscr.width);
|
||||
|
||||
/* Increment the vertical position */
|
||||
|
||||
dst += pinfo->stride;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_VIDEO_FB_SPLASHSCREEN */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fb_get_panbuf
|
||||
****************************************************************************/
|
||||
@ -316,13 +473,13 @@ err_fb:
|
||||
|
||||
static int fb_close(FAR struct file *filep)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
FAR struct fb_priv_s *curr;
|
||||
FAR struct fb_priv_s *prev;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
FAR struct fb_priv_s *priv;
|
||||
FAR struct fb_priv_s *curr;
|
||||
FAR struct fb_priv_s *prev;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
inode = filep->f_inode;
|
||||
fb = inode->i_private;
|
||||
@ -383,14 +540,14 @@ static int fb_close(FAR struct file *filep)
|
||||
|
||||
static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t size;
|
||||
int ret;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
ginfo("len: %u\n", (unsigned int)len);
|
||||
|
||||
@ -441,14 +598,14 @@ static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||
static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t len)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t size;
|
||||
int ret;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
size_t start;
|
||||
size_t end;
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
ginfo("len: %u\n", (unsigned int)len);
|
||||
|
||||
@ -504,12 +661,12 @@ static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
|
||||
|
||||
static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
off_t newpos;
|
||||
int ret;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
off_t newpos;
|
||||
int ret;
|
||||
|
||||
ginfo("offset: %u whence: %d\n", (unsigned int)offset, whence);
|
||||
|
||||
@ -589,9 +746,9 @@ static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
|
||||
|
||||
static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
int ret = OK;
|
||||
int ret = OK;
|
||||
|
||||
ginfo("cmd: %d arg: %ld\n", cmd, arg);
|
||||
|
||||
@ -1183,11 +1340,11 @@ static int fb_munmap(FAR struct task_group_s *group,
|
||||
|
||||
static int fb_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
int ret;
|
||||
FAR struct fb_priv_s *priv;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
int ret;
|
||||
|
||||
/* Get the framebuffer instance */
|
||||
|
||||
@ -1236,14 +1393,14 @@ static int fb_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
|
||||
|
||||
static int fb_poll(FAR struct file *filep, struct pollfd *fds, bool setup)
|
||||
{
|
||||
FAR struct inode *inode;
|
||||
FAR struct inode *inode;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s *priv;
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct pollfd **pollfds = NULL;
|
||||
irqstate_t flags;
|
||||
int ret = OK;
|
||||
int i;
|
||||
FAR struct fb_priv_s *priv;
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct pollfd **pollfds = NULL;
|
||||
irqstate_t flags;
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
/* Get the framebuffer instance */
|
||||
|
||||
@ -1525,7 +1682,7 @@ static void fb_pollnotify(FAR struct fb_chardev_s *fb, int overlay)
|
||||
void fb_notify_vsync(FAR struct fb_vtable_s *vtable)
|
||||
{
|
||||
FAR struct fb_chardev_s *fb;
|
||||
FAR struct fb_priv_s * priv;
|
||||
FAR struct fb_priv_s *priv;
|
||||
irqstate_t flags;
|
||||
|
||||
fb = vtable->priv;
|
||||
@ -1562,10 +1719,10 @@ int fb_peek_paninfo(FAR struct fb_vtable_s *vtable,
|
||||
FAR union fb_paninfo_u *info,
|
||||
int overlay)
|
||||
{
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
|
||||
/* Prevent calling before getting the vtable. */
|
||||
|
||||
@ -1610,11 +1767,11 @@ int fb_peek_paninfo(FAR struct fb_vtable_s *vtable,
|
||||
|
||||
int fb_remove_paninfo(FAR struct fb_vtable_s *vtable, int overlay)
|
||||
{
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
bool full;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
bool full;
|
||||
|
||||
fb = vtable->priv;
|
||||
if (fb == NULL)
|
||||
@ -1671,10 +1828,10 @@ int fb_remove_paninfo(FAR struct fb_vtable_s *vtable, int overlay)
|
||||
|
||||
int fb_paninfo_count(FAR struct fb_vtable_s *vtable, int overlay)
|
||||
{
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct circbuf_s *panbuf;
|
||||
FAR struct fb_chardev_s *fb;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
|
||||
/* Prevent calling before getting the vtable. */
|
||||
|
||||
@ -1727,12 +1884,15 @@ int fb_register_device(int display, int plane,
|
||||
FAR struct fb_vtable_s *vtable)
|
||||
{
|
||||
FAR struct fb_chardev_s *fb;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
struct fb_videoinfo_s vinfo;
|
||||
char devname[16];
|
||||
int nplanes;
|
||||
int ret;
|
||||
ssize_t i;
|
||||
struct fb_panelinfo_s panelinfo;
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
struct fb_planeinfo_s pinfo;
|
||||
#endif
|
||||
struct fb_videoinfo_s vinfo;
|
||||
char devname[16];
|
||||
int nplanes;
|
||||
int ret;
|
||||
ssize_t i;
|
||||
|
||||
/* Allocate a framebuffer state instance */
|
||||
|
||||
@ -1814,6 +1974,39 @@ int fb_register_device(int display, int plane,
|
||||
goto errout_with_paninfo;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
ret = fb_get_planeinfo(fb, &pinfo, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_paninfo;
|
||||
}
|
||||
|
||||
ret = fb_splash_fill(&vinfo, &pinfo, SPLASH_BGCOL);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_paninfo;
|
||||
}
|
||||
|
||||
ret = fb_splashscreen(&vinfo, &pinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_paninfo;
|
||||
}
|
||||
|
||||
if (SPLASH_SLEEP != 0)
|
||||
{
|
||||
nxsig_sleep(SPLASH_SLEEP);
|
||||
}
|
||||
|
||||
# ifdef VIDEO_FB_SPLASHSCREEN_CLR_ON_EXIT
|
||||
ret = fb_splash_fill(&vinfo, &pinfo, 0); /* Fill with black to clear LCD */
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_paninfo;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
vtable->priv = fb;
|
||||
return OK;
|
||||
|
||||
|
532740
drivers/video/new_logo.c
Normal file
532740
drivers/video/new_logo.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
drivers/video/new_nx_logo.png
Normal file
BIN
drivers/video/new_nx_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 186 KiB |
27636
drivers/video/nxlogo160.c
Normal file
27636
drivers/video/nxlogo160.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
drivers/video/nxlogo160.png
Normal file
BIN
drivers/video/nxlogo160.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
41913
drivers/video/nxlogo320.c
Normal file
41913
drivers/video/nxlogo320.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
drivers/video/nxlogo320.png
Normal file
BIN
drivers/video/nxlogo320.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
11439
drivers/video/nxlogo80.c
Normal file
11439
drivers/video/nxlogo80.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
drivers/video/nxlogo80.png
Normal file
BIN
drivers/video/nxlogo80.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
@ -33,6 +33,9 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
# include <nuttx/video/rgbcolors.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
@ -484,6 +487,18 @@
|
||||
#define FB_ROTATE_UD 2
|
||||
#define FB_ROTATE_CCW 3
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
# if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32)
|
||||
# define MKRGB ARGBTO32
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24)
|
||||
# define MKRGB RGBTO24
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16)
|
||||
# define MKRGB RGBTO16
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP8)
|
||||
# define MKRGB RGBTO8
|
||||
# endif /* CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32 */
|
||||
#endif /* CONFIG_VIDEO_FB_SPLASHSCREEN */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
@ -933,6 +948,53 @@ struct fb_var_screeninfo
|
||||
uint32_t reserved[4]; /* Reserved for future compatibility */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN
|
||||
# if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP8) || \
|
||||
defined(CONFIG_VIDEO_FB_SPLASHSCREEN_MONO) || \
|
||||
defined(CONFIG_VIDEO_FB_SPLASHSCREEN_GREY)
|
||||
typedef uint8_t fb_pixel_t;
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16)
|
||||
typedef uint16_t fb_pixel_t;
|
||||
#elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24)
|
||||
typedef uint32_t fb_pixel_t;
|
||||
# elif defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32)
|
||||
typedef uint32_t fb_pixel_t;
|
||||
# else
|
||||
# error "Pixel depth is unknown"
|
||||
#endif
|
||||
|
||||
/* Describes a point on the display */
|
||||
|
||||
struct fb_point_s
|
||||
{
|
||||
fb_coord_t x; /* X position, range: 0 to screen width - 1 */
|
||||
fb_coord_t y; /* Y position, range: 0 to screen height - 1 */
|
||||
};
|
||||
|
||||
struct fb_rect_s
|
||||
{
|
||||
struct fb_point_s pt1; /* Upper, left-hand corner */
|
||||
struct fb_point_s pt2; /* Lower, right-hand corner */
|
||||
};
|
||||
|
||||
/* This structure describes the splashscreen */
|
||||
|
||||
struct splscr_bitmap_s
|
||||
{
|
||||
uint8_t npixels; /* Number of pixels */
|
||||
uint8_t lookup; /* Pixel RGB lookup index */
|
||||
};
|
||||
|
||||
struct palette_bitmap_s
|
||||
{
|
||||
fb_coord_t width; /* Width in pixels */
|
||||
fb_coord_t height; /* Height in rows */
|
||||
FAR const fb_pixel_t *lut; /* Pointer to the palette (LUT) */
|
||||
FAR const struct
|
||||
splscr_bitmap_s *data; /* The RLE data */
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
@ -33,6 +33,18 @@
|
||||
|
||||
/* Color Creation and Conversion Macros *************************************/
|
||||
|
||||
/* This macro creates RGB24 from 8:8:8:8 RGB */
|
||||
|
||||
#define ARGBTO32(a,r,g,b) \
|
||||
((uint32_t)((a) & 0xff) << 24 | (uint32_t)((r) & 0xff) << 16 | (uint32_t)((g) & 0xff) << 8 | (uint32_t)((b) & 0xff))
|
||||
|
||||
/* And these macros perform the inverse transformation */
|
||||
|
||||
#define RGB32ALPHA(argb) (((argb) >> 24) & 0xff)
|
||||
#define RGB32RED(argb) (((argb) >> 16) & 0xff)
|
||||
#define RGB32GREEN(argb) (((argb) >> 8) & 0xff)
|
||||
#define RGB32BLUE(argb) ( (argb) & 0xff)
|
||||
|
||||
/* This macro creates RGB24 from 8:8:8 RGB */
|
||||
|
||||
#define RGBTO24(r,g,b) \
|
||||
|
256
tools/splashscreen_converter.py
Executable file
256
tools/splashscreen_converter.py
Executable file
@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env python3
|
||||
# tools/splashscreen_converter.py
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
"""This script converts from any image type supported by
|
||||
Python imaging library to the RLE-encoded format used by
|
||||
the framebuffer splashscreen feature.
|
||||
"""
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def get_palette(img, maxcolors=256):
|
||||
"""Returns a list of colours. If there are too many colours in the image,
|
||||
the least used are removed.
|
||||
"""
|
||||
|
||||
colors = img.getcolors(65536)
|
||||
colors.sort(key=lambda c: -c[0])
|
||||
return [c[1] for c in colors[:maxcolors]]
|
||||
|
||||
|
||||
def write_palette(outfile, palette, type):
|
||||
"""Write the palette to the output file."""
|
||||
|
||||
if type == "ARGB":
|
||||
outfile.write("#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN_BPP32\n")
|
||||
outfile.write("static const fb_pixel_t palette[] =\n")
|
||||
outfile.write("{\n")
|
||||
|
||||
for i in range(0, len(palette), 4):
|
||||
for r, g, b, a in palette[i : i + 4]:
|
||||
outfile.write(" MKRGB(%d, %d, %d, %d),\n" % (a, r, g, b))
|
||||
|
||||
outfile.write("};\n")
|
||||
outfile.write("#endif\n\n")
|
||||
|
||||
elif type == "RGB":
|
||||
outfile.write("#if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24) || \\\n")
|
||||
outfile.write(" defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16) || \\\n")
|
||||
outfile.write(" defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP8)\n")
|
||||
outfile.write("static const fb_pixel_t palette[] =\n")
|
||||
outfile.write("{\n")
|
||||
|
||||
for i in range(0, len(palette), 4):
|
||||
for r, g, b in palette[i : i + 4]:
|
||||
outfile.write(" MKRGB(%d, %d, %d),\n" % (r, g, b))
|
||||
|
||||
outfile.write("};\n")
|
||||
outfile.write("#endif\n\n")
|
||||
|
||||
else:
|
||||
outfile.write("#if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_GREY) || \\\n")
|
||||
outfile.write(" defined(CONFIG_VIDEO_FB_SPLASHSCREEN_MONO)\n")
|
||||
outfile.write("static const fb_pixel_t palette[] =\n{\n};\n")
|
||||
outfile.write("#endif\n\n")
|
||||
|
||||
|
||||
def quantize(color, palette):
|
||||
"""Return the color index to closest match in the palette."""
|
||||
try:
|
||||
return palette.index(color)
|
||||
except ValueError:
|
||||
# No exact match, search for the closest
|
||||
def distance(color2):
|
||||
return sum([(a - b) ** 2 for a, b in zip(color, color2)])
|
||||
|
||||
return palette.index(min(palette, key=distance))
|
||||
|
||||
|
||||
def encode_row(img, palette, y, type):
|
||||
"""RLE-encode one row of image data."""
|
||||
|
||||
color = None
|
||||
entries = []
|
||||
repeats = 0
|
||||
|
||||
for x in range(0, img.width):
|
||||
if type == "BPP32" or type == "BPP24" or type == "BPP16":
|
||||
c = quantize(img.getpixel((x, y)), palette)
|
||||
else:
|
||||
c = img.getpixel((x, y))
|
||||
if c == color and repeats < 255:
|
||||
repeats += 1
|
||||
else:
|
||||
if color is not None:
|
||||
entries.append((repeats, color))
|
||||
|
||||
repeats = 1
|
||||
color = c
|
||||
|
||||
if color is not None:
|
||||
entries.append((repeats, color))
|
||||
|
||||
return entries
|
||||
|
||||
|
||||
def write_image(outfile, img, palette, suffix):
|
||||
"""Write the image contents to the output file."""
|
||||
|
||||
if suffix == "BPP24" or suffix == "BPP16":
|
||||
outfile.write("#if defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP24) || \\")
|
||||
outfile.write("\n defined(CONFIG_VIDEO_FB_SPLASHSCREEN_BPP16)\n")
|
||||
else:
|
||||
outfile.write("#ifdef CONFIG_VIDEO_FB_SPLASHSCREEN_%s\n" % suffix)
|
||||
outfile.write("static const struct splscr_bitmap_s bitmap[] =\n")
|
||||
outfile.write("{")
|
||||
for y in range(0, img.height):
|
||||
entries = encode_row(img, palette, y, suffix)
|
||||
for r, c in entries:
|
||||
outfile.write("\n")
|
||||
row = " {%d, %d}," % (r, c)
|
||||
outfile.write(row)
|
||||
|
||||
outfile.write(("/* End of row %3d */" % (y + 1)).rjust(78 - len(row), " "))
|
||||
|
||||
outfile.write("\n};\n")
|
||||
outfile.write("#endif /* CONFIG_VIDEO_FB_SPLASHSCREEN_%s */\n\n" % suffix)
|
||||
|
||||
|
||||
def write_descriptor(outfile, name):
|
||||
outfile.write("const struct palette_bitmap_s g_%s =\n" % name)
|
||||
outfile.write("{\n")
|
||||
lw = len(str(img.width))
|
||||
lh = len(str(img.height))
|
||||
outfile.write(" %d," % img.width)
|
||||
outfile.write(
|
||||
("/* width in pixels */\n").rjust(
|
||||
76 - lw, " "
|
||||
)
|
||||
)
|
||||
outfile.write(" %d," % img.height)
|
||||
outfile.write(
|
||||
("/* height in pixels */\n").rjust(
|
||||
76 - lh, " "
|
||||
)
|
||||
)
|
||||
outfile.write(
|
||||
(
|
||||
" palette, /* Colour palette */\n"
|
||||
).rjust(76, " ")
|
||||
)
|
||||
outfile.write(
|
||||
(
|
||||
" bitmap, /* Pointer to the start of the RLE data */\n"
|
||||
).rjust(76, " ")
|
||||
)
|
||||
outfile.write("};\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: splashscreen_converter.py image.xxx output_directory out.c")
|
||||
print(
|
||||
"\t- image.xxx\t\tis the image file (e.g. logo.png) in a format supported by PIL"
|
||||
)
|
||||
print("\t- output_directory\tis where the output file will be saved.")
|
||||
print("\t- out.c\t\t\tis the name of the output file.")
|
||||
print("\t\t\t\t- If out.c is not specified it will default to fb_splash.c,")
|
||||
print("\t\t\t\t which is the name required for custom splashscreens")
|
||||
sys.exit(1)
|
||||
elif len(sys.argv) == 3:
|
||||
path = sys.argv[2]
|
||||
filename = "fb_splash.c"
|
||||
else:
|
||||
path = os.path.relpath(sys.argv[2])
|
||||
filename = sys.argv[3]
|
||||
img = Image.open(sys.argv[1]).convert("RGBA")
|
||||
file = os.path.realpath(path + "/" + filename)
|
||||
outfile = open(file, "w")
|
||||
palette_argb = get_palette(img)
|
||||
palette_rgb = get_palette(img.convert("RGB"))
|
||||
outfile.write(
|
||||
"""/****************************************************************************
|
||||
* %(file)s
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Script-generated framebuffer splashscreen bitmap file.
|
||||
* Generated from %(src)s
|
||||
* by splashscreen_converter.py
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/video/fb.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
"""
|
||||
% {"file": path + "/" + filename, "src": os.path.relpath(sys.argv[1])}
|
||||
)
|
||||
|
||||
name = "splscr"
|
||||
|
||||
write_palette(outfile, palette_argb, "ARGB")
|
||||
write_palette(outfile, palette_rgb, "RGB")
|
||||
write_palette(outfile, None, None)
|
||||
write_image(outfile, img, palette_argb, "BPP32")
|
||||
write_image(outfile, img.convert("RGB"), palette_rgb, "BPP24")
|
||||
write_image(outfile, img.convert("L"), None, "GREY")
|
||||
write_image(outfile, img.convert("1"), None, "MONO")
|
||||
write_descriptor(outfile, name)
|
||||
outfile.write(
|
||||
"""
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
"""
|
||||
)
|
||||
print("Created %s from %s" % (file, sys.argv[1]))
|
Loading…
x
Reference in New Issue
Block a user