video/fb: add vsync queue
refact vsync queue to support multi fb poll and overlay poll. Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Signed-off-by: rongyichang <rongyichang@xiaomi.com>
This commit is contained in:
parent
43ea7e65e1
commit
e578f3b20d
@ -50,6 +50,11 @@ config VIDEO_FB
|
|||||||
bool "Framebuffer character driver"
|
bool "Framebuffer character driver"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config VIDEO_FB_NPOLLWAITERS
|
||||||
|
int "Video fb poll count of each layer"
|
||||||
|
depends on VIDEO_FB
|
||||||
|
default 2
|
||||||
|
|
||||||
config VIDEO_STREAM
|
config VIDEO_STREAM
|
||||||
bool "Video Stream Support"
|
bool "Video Stream Support"
|
||||||
default n
|
default n
|
||||||
|
@ -41,17 +41,30 @@
|
|||||||
#include <nuttx/video/fb.h>
|
#include <nuttx/video/fb.h>
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/wdog.h>
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/mm/circbuf.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor definitions
|
* Pre-processor definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define FB_NO_OVERLAY -1
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct fb_priv_s
|
||||||
|
{
|
||||||
|
int overlay; /* Overlay number */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fb_paninfo_s
|
||||||
|
{
|
||||||
|
FAR struct circbuf_s buf; /* Pan buffer queued list */
|
||||||
|
|
||||||
|
/* Polling fds of waiting threads */
|
||||||
|
|
||||||
|
FAR struct pollfd *fds[CONFIG_VIDEO_FB_NPOLLWAITERS];
|
||||||
|
};
|
||||||
|
|
||||||
/* This structure defines one framebuffer device. Note that which is
|
/* This structure defines one framebuffer device. Note that which is
|
||||||
* everything in this structure is constant data set up and initialization
|
* everything in this structure is constant data set up and initialization
|
||||||
* time. Therefore, no there is requirement for serialized access to this
|
* time. Therefore, no there is requirement for serialized access to this
|
||||||
@ -60,23 +73,21 @@
|
|||||||
|
|
||||||
struct fb_chardev_s
|
struct fb_chardev_s
|
||||||
{
|
{
|
||||||
FAR struct fb_vtable_s *vtable; /* Framebuffer interface */
|
FAR struct fb_vtable_s *vtable; /* Framebuffer interface */
|
||||||
FAR struct pollfd *fds; /* Polling structure of waiting thread */
|
uint8_t plane; /* Video plan number */
|
||||||
uint8_t plane; /* Video plan number */
|
clock_t vsyncoffset; /* VSync offset ticks */
|
||||||
volatile int pollcnt; /* Poll ready count */
|
struct wdog_s wdog; /* VSync offset timer */
|
||||||
clock_t vsyncoffset; /* VSync offset ticks */
|
mutex_t lock; /* Mutual exclusion */
|
||||||
struct wdog_s wdog; /* VSync offset timer */
|
int16_t crefs; /* Number of open references */
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
FAR struct fb_paninfo_s *paninfo; /* Pan info array */
|
||||||
int overlay; /* Overlay number */
|
size_t paninfo_count; /* Pan info count */
|
||||||
#endif
|
|
||||||
mutex_t lock; /* Mutual exclusion */
|
|
||||||
int16_t crefs; /* Number of open references */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fb_panelinfo_s
|
struct fb_panelinfo_s
|
||||||
{
|
{
|
||||||
FAR void *fbmem; /* Start of frame buffer memory */
|
FAR void *fbmem; /* Start of frame buffer memory */
|
||||||
size_t fblen; /* Size of the framebuffer */
|
size_t fblen; /* Size of the framebuffer */
|
||||||
|
uint8_t fbcount; /* Count of frame buffer */
|
||||||
uint8_t bpp; /* Bits per pixel */
|
uint8_t bpp; /* Bits per pixel */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,6 +95,13 @@ struct fb_panelinfo_s
|
|||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct pollfd **fb_get_free_pollfds(FAR struct fb_chardev_s *fb,
|
||||||
|
int overlay);
|
||||||
|
static FAR struct circbuf_s *fb_get_panbuf(FAR struct fb_chardev_s *fb,
|
||||||
|
int overlay);
|
||||||
|
static int fb_add_paninfo(FAR struct fb_vtable_s *vtable,
|
||||||
|
FAR const union fb_paninfo_u *info,
|
||||||
|
int overlay);
|
||||||
static int fb_open(FAR struct file *filep);
|
static int fb_open(FAR struct file *filep);
|
||||||
static int fb_close(FAR struct file *filep);
|
static int fb_close(FAR struct file *filep);
|
||||||
static ssize_t fb_read(FAR struct file *filep, FAR char *buffer,
|
static ssize_t fb_read(FAR struct file *filep, FAR char *buffer,
|
||||||
@ -97,7 +115,8 @@ static int fb_mmap(FAR struct file *filep,
|
|||||||
static int fb_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
static int fb_poll(FAR struct file *filep, FAR struct pollfd *fds,
|
||||||
bool setup);
|
bool setup);
|
||||||
static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
||||||
FAR struct fb_panelinfo_s *panelinfo);
|
FAR struct fb_panelinfo_s *panelinfo,
|
||||||
|
int overlay);
|
||||||
static int fb_get_planeinfo(FAR struct fb_chardev_s *fb,
|
static int fb_get_planeinfo(FAR struct fb_chardev_s *fb,
|
||||||
FAR struct fb_planeinfo_s *pinfo,
|
FAR struct fb_planeinfo_s *pinfo,
|
||||||
uint8_t display);
|
uint8_t display);
|
||||||
@ -123,6 +142,93 @@ static const struct file_operations g_fb_fops =
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_get_free_pollfds
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct pollfd **fb_get_free_pollfds(FAR struct fb_chardev_s *fb,
|
||||||
|
int overlay)
|
||||||
|
{
|
||||||
|
FAR struct fb_paninfo_s *paninfo;
|
||||||
|
int id = overlay + 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DEBUGASSERT(id >= 0 && id < fb->paninfo_count);
|
||||||
|
|
||||||
|
paninfo = &fb->paninfo[id];
|
||||||
|
|
||||||
|
for (i = 0; i < CONFIG_VIDEO_FB_NPOLLWAITERS; ++i)
|
||||||
|
{
|
||||||
|
if (!paninfo->fds[i])
|
||||||
|
{
|
||||||
|
return &paninfo->fds[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_get_panbuf
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static FAR struct circbuf_s *fb_get_panbuf(FAR struct fb_chardev_s *fb,
|
||||||
|
int overlay)
|
||||||
|
{
|
||||||
|
int id = overlay + 1;
|
||||||
|
|
||||||
|
DEBUGASSERT(id >= 0 && id < fb->paninfo_count);
|
||||||
|
|
||||||
|
return &(fb->paninfo[id].buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_add_paninfo
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int fb_add_paninfo(FAR struct fb_vtable_s *vtable,
|
||||||
|
FAR const union fb_paninfo_u *info,
|
||||||
|
int overlay)
|
||||||
|
{
|
||||||
|
FAR struct circbuf_s *panbuf;
|
||||||
|
FAR struct fb_chardev_s *fb;
|
||||||
|
irqstate_t flags;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(vtable != NULL);
|
||||||
|
|
||||||
|
/* Prevent calling before getting the vtable. */
|
||||||
|
|
||||||
|
fb = vtable->priv;
|
||||||
|
if (fb == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
panbuf = fb_get_panbuf(fb, overlay);
|
||||||
|
if (panbuf == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable the interrupt when writing to the queue to
|
||||||
|
* prevent it from being modified by the interrupted
|
||||||
|
* thread during the writing process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
/* Write planeinfo information to the queue. */
|
||||||
|
|
||||||
|
ret = circbuf_write(panbuf, info, sizeof(union fb_paninfo_u));
|
||||||
|
DEBUGASSERT(ret == sizeof(union fb_paninfo_u));
|
||||||
|
|
||||||
|
/* Re-enable interrupts */
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
return ret <= 0 ? -ENOSPC : OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: fb_open
|
* Name: fb_open
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -131,6 +237,7 @@ static int fb_open(FAR struct file *filep)
|
|||||||
{
|
{
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
FAR struct fb_chardev_s *fb;
|
FAR struct fb_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
@ -144,20 +251,34 @@ static int fb_open(FAR struct file *filep)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = kmm_zalloc(sizeof(*priv));
|
||||||
|
if (priv == NULL)
|
||||||
|
{
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
if (fb->crefs == 0)
|
if (fb->crefs == 0)
|
||||||
{
|
{
|
||||||
if (fb->vtable->open != NULL)
|
if (fb->vtable->open != NULL &&
|
||||||
|
(ret = fb->vtable->open(fb->vtable)) < 0)
|
||||||
{
|
{
|
||||||
ret = fb->vtable->open(fb->vtable);
|
goto err_fb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret >= 0)
|
fb->crefs++;
|
||||||
{
|
DEBUGASSERT(fb->crefs > 0);
|
||||||
fb->crefs++;
|
|
||||||
DEBUGASSERT(fb->crefs > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
priv->overlay = FB_NO_OVERLAY;
|
||||||
|
filep->f_priv = priv;
|
||||||
|
|
||||||
|
nxmutex_unlock(&fb->lock);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_fb:
|
||||||
|
kmm_free(priv);
|
||||||
|
err_out:
|
||||||
nxmutex_unlock(&fb->lock);
|
nxmutex_unlock(&fb->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -170,12 +291,14 @@ 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_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
DEBUGASSERT(fb->vtable != NULL);
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
ret = nxmutex_lock(&fb->lock);
|
ret = nxmutex_lock(&fb->lock);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -195,6 +318,7 @@ static int fb_close(FAR struct file *filep)
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(fb->crefs > 0);
|
DEBUGASSERT(fb->crefs > 0);
|
||||||
fb->crefs--;
|
fb->crefs--;
|
||||||
|
kmm_free(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
nxmutex_unlock(&fb->lock);
|
nxmutex_unlock(&fb->lock);
|
||||||
@ -209,6 +333,7 @@ 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_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
struct fb_panelinfo_s panelinfo;
|
struct fb_panelinfo_s panelinfo;
|
||||||
size_t start;
|
size_t start;
|
||||||
size_t end;
|
size_t end;
|
||||||
@ -221,10 +346,13 @@ static ssize_t fb_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
|||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
/* Get panel info */
|
/* Get panel info */
|
||||||
|
|
||||||
ret = fb_get_panelinfo(fb, &panelinfo);
|
ret = fb_get_panelinfo(fb, &panelinfo, priv->overlay);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -263,6 +391,7 @@ static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
|
|||||||
{
|
{
|
||||||
FAR struct inode *inode;
|
FAR struct inode *inode;
|
||||||
FAR struct fb_chardev_s *fb;
|
FAR struct fb_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
struct fb_panelinfo_s panelinfo;
|
struct fb_panelinfo_s panelinfo;
|
||||||
size_t start;
|
size_t start;
|
||||||
size_t end;
|
size_t end;
|
||||||
@ -275,10 +404,13 @@ static ssize_t fb_write(FAR struct file *filep, FAR const char *buffer,
|
|||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
/* Get panel info */
|
/* Get panel info */
|
||||||
|
|
||||||
ret = fb_get_panelinfo(fb, &panelinfo);
|
ret = fb_get_panelinfo(fb, &panelinfo, priv->overlay);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -322,6 +454,7 @@ 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_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
struct fb_panelinfo_s panelinfo;
|
struct fb_panelinfo_s panelinfo;
|
||||||
off_t newpos;
|
off_t newpos;
|
||||||
int ret;
|
int ret;
|
||||||
@ -332,6 +465,9 @@ static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
|
|||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
/* Determine the new, requested file position */
|
/* Determine the new, requested file position */
|
||||||
|
|
||||||
@ -349,7 +485,7 @@ static off_t fb_seek(FAR struct file *filep, off_t offset, int whence)
|
|||||||
|
|
||||||
/* Get panel info */
|
/* Get panel info */
|
||||||
|
|
||||||
ret = fb_get_panelinfo(fb, &panelinfo);
|
ret = fb_get_panelinfo(fb, &panelinfo, priv->overlay);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -507,14 +643,15 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
case FBIO_SELECT_OVERLAY: /* Select video overlay */
|
case FBIO_SELECT_OVERLAY: /* Select video overlay */
|
||||||
{
|
{
|
||||||
struct fb_overlayinfo_s oinfo;
|
struct fb_overlayinfo_s oinfo;
|
||||||
|
FAR struct fb_priv_s *priv = filep->f_priv;
|
||||||
|
|
||||||
DEBUGASSERT(fb->vtable != NULL &&
|
DEBUGASSERT(priv != NULL && fb->vtable != NULL &&
|
||||||
fb->vtable->getoverlayinfo != NULL);
|
fb->vtable->getoverlayinfo != NULL);
|
||||||
memset(&oinfo, 0, sizeof(oinfo));
|
memset(&oinfo, 0, sizeof(oinfo));
|
||||||
ret = fb->vtable->getoverlayinfo(fb->vtable, arg, &oinfo);
|
ret = fb->vtable->getoverlayinfo(fb->vtable, arg, &oinfo);
|
||||||
if (ret == OK)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
fb->overlay = arg;
|
priv->overlay = arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -625,10 +762,18 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
{
|
{
|
||||||
FAR struct fb_overlayinfo_s *oinfo =
|
FAR struct fb_overlayinfo_s *oinfo =
|
||||||
(FAR struct fb_overlayinfo_s *)((uintptr_t)arg);
|
(FAR struct fb_overlayinfo_s *)((uintptr_t)arg);
|
||||||
|
union fb_paninfo_u paninfo;
|
||||||
|
|
||||||
DEBUGASSERT(oinfo != 0 && fb->vtable != NULL &&
|
DEBUGASSERT(oinfo != 0 && fb->vtable != NULL);
|
||||||
fb->vtable->panoverlay != NULL);
|
|
||||||
ret = fb->vtable->panoverlay(fb->vtable, oinfo);
|
memcpy(&paninfo, oinfo, sizeof(*oinfo));
|
||||||
|
|
||||||
|
if (fb->vtable->panoverlay != NULL)
|
||||||
|
{
|
||||||
|
fb->vtable->panoverlay(fb->vtable, oinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fb_add_paninfo(fb->vtable, &paninfo, oinfo->overlay);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -676,15 +821,18 @@ static int fb_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
{
|
{
|
||||||
FAR struct fb_planeinfo_s *pinfo =
|
FAR struct fb_planeinfo_s *pinfo =
|
||||||
(FAR struct fb_planeinfo_s *)((uintptr_t)arg);
|
(FAR struct fb_planeinfo_s *)((uintptr_t)arg);
|
||||||
|
union fb_paninfo_u paninfo;
|
||||||
|
|
||||||
DEBUGASSERT(pinfo != NULL && fb->vtable != NULL &&
|
DEBUGASSERT(pinfo != NULL && fb->vtable != NULL);
|
||||||
fb->vtable->pandisplay != NULL);
|
|
||||||
ret = fb->vtable->pandisplay(fb->vtable, pinfo);
|
|
||||||
fb->pollcnt--;
|
|
||||||
|
|
||||||
/* Check pan display overrun. */
|
memcpy(&paninfo, pinfo, sizeof(*pinfo));
|
||||||
|
|
||||||
DEBUGASSERT(fb->pollcnt >= 0);
|
if (fb->vtable->pandisplay != NULL)
|
||||||
|
{
|
||||||
|
fb->vtable->pandisplay(fb->vtable, pinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fb_add_paninfo(fb->vtable, &paninfo, FB_NO_OVERLAY);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -844,6 +992,7 @@ 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_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
struct fb_panelinfo_s panelinfo;
|
struct fb_panelinfo_s panelinfo;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -851,10 +1000,13 @@ static int fb_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
|
|||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
/* Get panel info */
|
/* Get panel info */
|
||||||
|
|
||||||
ret = fb_get_panelinfo(fb, &panelinfo);
|
ret = fb_get_panelinfo(fb, &panelinfo, priv->overlay);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -885,36 +1037,52 @@ 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_chardev_s *fb;
|
||||||
|
FAR struct fb_priv_s *priv;
|
||||||
|
FAR struct circbuf_s *panbuf;
|
||||||
|
FAR struct pollfd **pollfds;
|
||||||
|
irqstate_t flags;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
/* Get the framebuffer instance */
|
/* Get the framebuffer instance */
|
||||||
|
|
||||||
inode = filep->f_inode;
|
inode = filep->f_inode;
|
||||||
fb = inode->i_private;
|
fb = inode->i_private;
|
||||||
|
priv = filep->f_priv;
|
||||||
|
|
||||||
|
DEBUGASSERT(fb->vtable != NULL && priv != NULL);
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
if (setup)
|
if (setup)
|
||||||
{
|
{
|
||||||
if (fb->fds == NULL)
|
pollfds = fb_get_free_pollfds(fb, priv->overlay);
|
||||||
|
if (pollfds == NULL)
|
||||||
{
|
{
|
||||||
fb->fds = fds;
|
ret = -EBUSY;
|
||||||
fds->priv = &fb->fds;
|
goto errout;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb->pollcnt > 0)
|
*pollfds = fds;
|
||||||
|
fds->priv = pollfds;
|
||||||
|
|
||||||
|
panbuf = fb_get_panbuf(fb, priv->overlay);
|
||||||
|
if (!circbuf_is_full(panbuf))
|
||||||
{
|
{
|
||||||
poll_notify(&fb->fds, 1, POLLOUT);
|
poll_notify(pollfds, 1, POLLOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fds->priv)
|
else if (fds->priv != NULL)
|
||||||
{
|
{
|
||||||
fb->fds = NULL;
|
/* This is a request to tear down the poll. */
|
||||||
|
|
||||||
|
FAR struct pollfd **slot = (FAR struct pollfd **)fds->priv;
|
||||||
|
*slot = NULL;
|
||||||
fds->priv = NULL;
|
fds->priv = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
errout:
|
||||||
|
leave_critical_section(flags);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -922,18 +1090,20 @@ static int fb_poll(FAR struct file *filep, struct pollfd *fds, bool setup)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
||||||
FAR struct fb_panelinfo_s *panelinfo)
|
FAR struct fb_panelinfo_s *panelinfo,
|
||||||
|
int overlay)
|
||||||
{
|
{
|
||||||
struct fb_planeinfo_s pinfo;
|
struct fb_planeinfo_s pinfo;
|
||||||
|
struct fb_videoinfo_s vinfo;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
#ifdef CONFIG_FB_OVERLAY
|
||||||
if (fb->overlay != FB_NO_OVERLAY)
|
if (overlay != FB_NO_OVERLAY)
|
||||||
{
|
{
|
||||||
struct fb_overlayinfo_s oinfo;
|
struct fb_overlayinfo_s oinfo;
|
||||||
DEBUGASSERT(fb->vtable->getoverlayinfo != NULL);
|
DEBUGASSERT(fb->vtable->getoverlayinfo != NULL);
|
||||||
memset(&oinfo, 0, sizeof(oinfo));
|
memset(&oinfo, 0, sizeof(oinfo));
|
||||||
ret = fb->vtable->getoverlayinfo(fb->vtable, fb->overlay, &oinfo);
|
ret = fb->vtable->getoverlayinfo(fb->vtable, overlay, &oinfo);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -941,9 +1111,11 @@ static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
panelinfo->fbmem = oinfo.fbmem;
|
panelinfo->fbmem = oinfo.fbmem;
|
||||||
panelinfo->fblen = oinfo.fblen;
|
panelinfo->fblen = oinfo.fblen;
|
||||||
panelinfo->bpp = oinfo.bpp;
|
panelinfo->fbcount = oinfo.yres_virtual == 0 ?
|
||||||
|
1 : (oinfo.yres_virtual / oinfo.yres);
|
||||||
|
panelinfo->bpp = oinfo.bpp;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -954,9 +1126,18 @@ static int fb_get_panelinfo(FAR struct fb_chardev_s *fb,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
panelinfo->fbmem = pinfo.fbmem;
|
ret = fb->vtable->getvideoinfo(fb->vtable, &vinfo);
|
||||||
panelinfo->fblen = pinfo.fblen;
|
if (ret < 0)
|
||||||
panelinfo->bpp = pinfo.bpp;
|
{
|
||||||
|
gerr("ERROR: getvideoinfo() failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
panelinfo->fbmem = pinfo.fbmem;
|
||||||
|
panelinfo->fblen = pinfo.fblen;
|
||||||
|
panelinfo->fbcount = pinfo.yres_virtual == 0 ?
|
||||||
|
1 : (pinfo.yres_virtual / vinfo.yres);
|
||||||
|
panelinfo->bpp = pinfo.bpp;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -994,19 +1175,25 @@ static int fb_get_planeinfo(FAR struct fb_chardev_s *fb,
|
|||||||
|
|
||||||
static void fb_do_pollnotify(wdparm_t arg)
|
static void fb_do_pollnotify(wdparm_t arg)
|
||||||
{
|
{
|
||||||
FAR struct fb_chardev_s *fb = (FAR struct fb_chardev_s *)arg;
|
FAR struct fb_paninfo_s *paninfo = (FAR struct fb_paninfo_s *)arg;
|
||||||
|
irqstate_t flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
fb->pollcnt++;
|
flags = enter_critical_section();
|
||||||
|
|
||||||
/* Notify framebuffer is writable. */
|
for (i = 0; i < CONFIG_VIDEO_FB_NPOLLWAITERS; i++)
|
||||||
|
{
|
||||||
|
if (paninfo->fds[i] != NULL)
|
||||||
|
{
|
||||||
|
/* Notify framebuffer is writable. */
|
||||||
|
|
||||||
poll_notify(&fb->fds, 1, POLLOUT);
|
poll_notify(&paninfo->fds[i], 1, POLLOUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Public Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: fb_pollnotify
|
* Name: fb_pollnotify
|
||||||
*
|
*
|
||||||
@ -1018,9 +1205,10 @@ static void fb_do_pollnotify(wdparm_t arg)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void fb_pollnotify(FAR struct fb_vtable_s *vtable)
|
static void fb_pollnotify(FAR struct fb_vtable_s *vtable, int overlay)
|
||||||
{
|
{
|
||||||
FAR struct fb_chardev_s *fb;
|
FAR struct fb_chardev_s *fb;
|
||||||
|
int id = overlay + 1;
|
||||||
|
|
||||||
DEBUGASSERT(vtable != NULL);
|
DEBUGASSERT(vtable != NULL);
|
||||||
|
|
||||||
@ -1033,16 +1221,170 @@ void fb_pollnotify(FAR struct fb_vtable_s *vtable)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUGASSERT(id >= 0 && id < fb->paninfo_count);
|
||||||
|
|
||||||
if (fb->vsyncoffset > 0)
|
if (fb->vsyncoffset > 0)
|
||||||
{
|
{
|
||||||
wd_start(&fb->wdog, fb->vsyncoffset, fb_do_pollnotify, (wdparm_t)fb);
|
wd_start(&fb->wdog, fb->vsyncoffset, fb_do_pollnotify,
|
||||||
|
(wdparm_t)(&fb->paninfo[id]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fb_do_pollnotify((wdparm_t)fb);
|
fb_do_pollnotify((wdparm_t)(&fb->paninfo[id]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_peek_paninfo
|
||||||
|
* Description:
|
||||||
|
* Peek a frame from pan info queue of the specified overlay.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* info - Pointer to pan info.
|
||||||
|
* overlay - Overlay index.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
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 fb_chardev_s *fb;
|
||||||
|
irqstate_t flags;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* Prevent calling before getting the vtable. */
|
||||||
|
|
||||||
|
fb = vtable->priv;
|
||||||
|
if (fb == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
panbuf = fb_get_panbuf(fb, overlay);
|
||||||
|
if (panbuf == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
/* Attempt to peek a frame from the vsync queue. */
|
||||||
|
|
||||||
|
ret = circbuf_peek(panbuf, info, sizeof(union fb_paninfo_u));
|
||||||
|
DEBUGASSERT(ret <= 0 || ret == sizeof(union fb_paninfo_u));
|
||||||
|
|
||||||
|
/* Re-enable interrupts */
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
return ret <= 0 ? -ENOSPC : OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_remove_paninfo
|
||||||
|
* Description:
|
||||||
|
* Remove a frame from pan info queue of the specified overlay.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* overlay - Overlay index.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int fb_remove_paninfo(FAR struct fb_vtable_s *vtable, int overlay)
|
||||||
|
{
|
||||||
|
FAR struct circbuf_s *panbuf;
|
||||||
|
FAR struct fb_chardev_s *fb;
|
||||||
|
irqstate_t flags;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
fb = vtable->priv;
|
||||||
|
if (fb == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
panbuf = fb_get_panbuf(fb, overlay);
|
||||||
|
if (panbuf == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
/* Attempt to take a frame from the pan info. */
|
||||||
|
|
||||||
|
ret = circbuf_skip(panbuf, sizeof(union fb_paninfo_u));
|
||||||
|
DEBUGASSERT(ret <= 0 || ret == sizeof(union fb_paninfo_u));
|
||||||
|
|
||||||
|
/* Re-enable interrupts */
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
if (ret == sizeof(union fb_paninfo_u))
|
||||||
|
{
|
||||||
|
fb_pollnotify(vtable, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret <= 0 ? -ENOSPC : OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_paninfo_count
|
||||||
|
* Description:
|
||||||
|
* Get pan info count of specified overlay pan info queue.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* overlay - Overlay index.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* a non-negative value is returned on success; a negated errno value is
|
||||||
|
* returned on any failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int fb_paninfo_count(FAR struct fb_vtable_s *vtable, int overlay)
|
||||||
|
{
|
||||||
|
FAR struct circbuf_s *panbuf;
|
||||||
|
FAR struct fb_chardev_s *fb;
|
||||||
|
irqstate_t flags;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
/* Prevent calling before getting the vtable. */
|
||||||
|
|
||||||
|
fb = vtable->priv;
|
||||||
|
if (fb == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
panbuf = fb_get_panbuf(fb, overlay);
|
||||||
|
if (panbuf == NULL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
ret = circbuf_used(panbuf) / sizeof(union fb_paninfo_u);
|
||||||
|
|
||||||
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: fb_register
|
* Name: fb_register
|
||||||
*
|
*
|
||||||
@ -1071,13 +1413,10 @@ int fb_register(int display, int plane)
|
|||||||
FAR struct fb_chardev_s *fb;
|
FAR struct fb_chardev_s *fb;
|
||||||
struct fb_panelinfo_s panelinfo;
|
struct fb_panelinfo_s panelinfo;
|
||||||
struct fb_videoinfo_s vinfo;
|
struct fb_videoinfo_s vinfo;
|
||||||
struct fb_planeinfo_s pinfo;
|
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
|
||||||
struct fb_overlayinfo_s oinfo;
|
|
||||||
#endif
|
|
||||||
char devname[16];
|
char devname[16];
|
||||||
int nplanes;
|
int nplanes;
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
/* Allocate a framebuffer state instance */
|
/* Allocate a framebuffer state instance */
|
||||||
|
|
||||||
@ -1087,13 +1426,6 @@ int fb_register(int display, int plane)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
|
||||||
|
|
||||||
/* Set the default overlay number */
|
|
||||||
|
|
||||||
fb->overlay = FB_NO_OVERLAY;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize the frame buffer device. */
|
/* Initialize the frame buffer device. */
|
||||||
|
|
||||||
ret = up_fbinitialize(display);
|
ret = up_fbinitialize(display);
|
||||||
@ -1127,57 +1459,38 @@ int fb_register(int display, int plane)
|
|||||||
nplanes = vinfo.nplanes;
|
nplanes = vinfo.nplanes;
|
||||||
DEBUGASSERT(vinfo.nplanes > 0 && (unsigned)plane < vinfo.nplanes);
|
DEBUGASSERT(vinfo.nplanes > 0 && (unsigned)plane < vinfo.nplanes);
|
||||||
|
|
||||||
/* Get plane info */
|
|
||||||
|
|
||||||
ret = fb_get_planeinfo(fb, &pinfo, 0);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
goto errout_with_fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The initial value of pollcnt is the number of virtual framebuffers */
|
|
||||||
|
|
||||||
if (pinfo.yres_virtual > 0)
|
|
||||||
{
|
|
||||||
fb->pollcnt = pinfo.yres_virtual / vinfo.yres;
|
|
||||||
DEBUGASSERT(fb->pollcnt > 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fb->pollcnt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get panel info */
|
|
||||||
|
|
||||||
ret = fb_get_panelinfo(fb, &panelinfo);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
goto errout_with_fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the framebuffer memory */
|
|
||||||
|
|
||||||
memset(panelinfo.fbmem, 0, panelinfo.fblen);
|
|
||||||
|
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
#ifdef CONFIG_FB_OVERLAY
|
||||||
/* Initialize first overlay but do not select */
|
fb->paninfo_count = vinfo.noverlays;
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(fb->vtable->getoverlayinfo != NULL);
|
/* Add the primary framebuffer */
|
||||||
memset(&oinfo, 0, sizeof(oinfo));
|
|
||||||
ret = fb->vtable->getoverlayinfo(fb->vtable, 0, &oinfo);
|
fb->paninfo_count += 1;
|
||||||
if (ret < 0)
|
fb->paninfo = kmm_zalloc(sizeof(struct fb_paninfo_s) * fb->paninfo_count);
|
||||||
|
|
||||||
|
if (fb->paninfo == NULL)
|
||||||
{
|
{
|
||||||
gerr("ERROR: getoverlayinfo() failed: %d\n", ret);
|
gerr("ERROR: alloc panbuf failed\n");
|
||||||
goto errout_with_fb;
|
goto errout_with_fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the overlay memory. Necessary when plane 0 and overlay 0
|
for (i = 0; i < fb->paninfo_count; i++)
|
||||||
* different.
|
{
|
||||||
*/
|
ret = fb_get_panelinfo(fb, &panelinfo, i - 1);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto errout_with_paninfo;
|
||||||
|
}
|
||||||
|
|
||||||
memset(oinfo.fbmem, 0, oinfo.fblen);
|
ret = circbuf_init(&(fb->paninfo[i].buf), NULL, panelinfo.fbcount
|
||||||
#endif
|
* sizeof(union fb_paninfo_u));
|
||||||
|
|
||||||
|
DEBUGASSERT(ret == 0);
|
||||||
|
|
||||||
|
/* Clear the framebuffer memory */
|
||||||
|
|
||||||
|
memset(panelinfo.fbmem, 0, panelinfo.fblen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register the framebuffer device */
|
/* Register the framebuffer device */
|
||||||
|
|
||||||
@ -1196,15 +1509,23 @@ int fb_register(int display, int plane)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
gerr("ERROR: register_driver() failed: %d\n", ret);
|
gerr("ERROR: register_driver() failed: %d\n", ret);
|
||||||
goto errout_with_fb;
|
goto errout_with_nxmutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
fb->vtable->priv = fb;
|
fb->vtable->priv = fb;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
||||||
errout_with_fb:
|
errout_with_nxmutex:
|
||||||
nxmutex_destroy(&fb->lock);
|
nxmutex_destroy(&fb->lock);
|
||||||
|
errout_with_paninfo:
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
circbuf_uninit(&(fb->paninfo[i].buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
kmm_free(fb->paninfo);
|
||||||
|
errout_with_fb:
|
||||||
kmm_free(fb);
|
kmm_free(fb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,8 @@
|
|||||||
|
|
||||||
/* Hardware overlay acceleration ********************************************/
|
/* Hardware overlay acceleration ********************************************/
|
||||||
|
|
||||||
|
#define FB_NO_OVERLAY -1
|
||||||
|
|
||||||
#ifdef CONFIG_FB_OVERLAY
|
#ifdef CONFIG_FB_OVERLAY
|
||||||
# define FB_ACCL_TRANSP 0x01 /* Hardware tranparency support */
|
# define FB_ACCL_TRANSP 0x01 /* Hardware tranparency support */
|
||||||
# define FB_ACCL_CHROMA 0x02 /* Hardware chromakey support */
|
# define FB_ACCL_CHROMA 0x02 /* Hardware chromakey support */
|
||||||
@ -673,6 +675,14 @@ struct fb_setcursor_s
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
union fb_paninfo_u
|
||||||
|
{
|
||||||
|
struct fb_planeinfo_s planeinfo;
|
||||||
|
#ifdef CONFIG_FB_OVERLAY
|
||||||
|
struct fb_overlayinfo_s overlayinfo;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/* The framebuffer "object" is accessed through within the OS via
|
/* The framebuffer "object" is accessed through within the OS via
|
||||||
* the following vtable:
|
* the following vtable:
|
||||||
*/
|
*/
|
||||||
@ -996,17 +1006,55 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane);
|
|||||||
void up_fbuninitialize(int display);
|
void up_fbuninitialize(int display);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: fb_pollnotify
|
* Name: fb_peek_paninfo
|
||||||
*
|
|
||||||
* Description:
|
* Description:
|
||||||
* Notify the waiting thread that the framebuffer can be written.
|
* Peek a frame from pan info queue of the specified overlay.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* vtable - Pointer to framebuffer's virtual table.
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* info - Pointer to pan info.
|
||||||
|
* overlay - Overlay index.
|
||||||
*
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void fb_pollnotify(FAR struct fb_vtable_s *vtable);
|
int fb_peek_paninfo(FAR struct fb_vtable_s *vtable,
|
||||||
|
FAR union fb_paninfo_u *info,
|
||||||
|
int overlay);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_remove_paninfo
|
||||||
|
* Description:
|
||||||
|
* Remove a frame from pan info queue of the specified overlay.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* overlay - Overlay index.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int fb_remove_paninfo(FAR struct fb_vtable_s *vtable, int overlay);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: fb_paninfo_count
|
||||||
|
* Description:
|
||||||
|
* Get pan info count of specified overlay pan info queue.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vtable - Pointer to framebuffer's virtual table.
|
||||||
|
* overlay - Overlay index.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* a non-negative value is returned on success; a negated errno value is
|
||||||
|
* returned on any failure.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int fb_paninfo_count(FAR struct fb_vtable_s *vtable, int overlay);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: fb_register
|
* Name: fb_register
|
||||||
|
Loading…
x
Reference in New Issue
Block a user