Font cache: Enforce mutually exclusive access to the font cache
This commit is contained in:
parent
0b52e6f571
commit
d7173f2eb5
@ -624,14 +624,14 @@ FCACHE nxf_cache_connect(enum nx_fontid_e fontid,
|
|||||||
* font handler is invalid upon return in either case.
|
* font handler is invalid upon return in either case.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* fcache - A font cache handler previously returned by nxf_cache_connect();
|
* fhandle - A font cache handler previously returned by nxf_cache_connect();
|
||||||
*
|
*
|
||||||
* Returned value:
|
* Returned value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void nxf_cache_disconnect(FCACHE fcache);
|
void nxf_cache_disconnect(FCACHE fhandle);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxf_cache_getfonthandle
|
* Name: nxf_cache_getfonthandle
|
||||||
@ -641,7 +641,7 @@ void nxf_cache_disconnect(FCACHE fcache);
|
|||||||
* cache.
|
* cache.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* fcache - A font cache handle previously returned by nxf_cache_connect();
|
* fhandle - A font cache handle previously returned by nxf_cache_connect();
|
||||||
*
|
*
|
||||||
* Returned value:
|
* Returned value:
|
||||||
* Zero (OK) is returned if the metrics were
|
* Zero (OK) is returned if the metrics were
|
||||||
@ -651,7 +651,7 @@ void nxf_cache_disconnect(FCACHE fcache);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
NXHANDLE nxf_cache_getfonthandle(FCACHE fcache);
|
NXHANDLE nxf_cache_getfonthandle(FCACHE fhandle);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxf_cache_getglyph
|
* Name: nxf_cache_getglyph
|
||||||
@ -667,7 +667,7 @@ NXHANDLE nxf_cache_getfonthandle(FCACHE fcache);
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
FAR const struct nxfonts_glyph_s *nxf_cache_getglyph(FCACHE fcache, uint8_t ch);
|
FAR const struct nxfonts_glyph_s *nxf_cache_getglyph(FCACHE fhandle, uint8_t ch);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
@ -88,11 +88,93 @@ struct nxfonts_fcache_s
|
|||||||
/* Head of a list of font caches */
|
/* Head of a list of font caches */
|
||||||
|
|
||||||
static FAR struct nxfonts_fcache_s *g_fcaches;
|
static FAR struct nxfonts_fcache_s *g_fcaches;
|
||||||
|
static sem_t g_cachesem = SEM_INITIALIZER(1);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxf_list_lock and nxf_list_unlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get/relinquish exclusive access to the font cache list
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nxf_list_lock(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get exclusive access to the font cache */
|
||||||
|
|
||||||
|
while ((ret = sem_wait(&g_cachesem)) < 0)
|
||||||
|
{
|
||||||
|
int errorcode = errno;
|
||||||
|
DEBUGASSERT(errorcode == EINTR || errorcode == ECANCELED);
|
||||||
|
UNUSED(errorcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define nxf_list_unlock() (sem_post(&g_cachesem))
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxf_removecache
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes the entry 'glyph' from the font cache.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The caller holds the font cache list semaphore.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void nxf_removecache(FAR struct nxfonts_fcache_s *fcache,
|
||||||
|
FAR struct nxfonts_fcache_s *prev)
|
||||||
|
{
|
||||||
|
/* Remove the cache for the list. First check for removal from the head */
|
||||||
|
|
||||||
|
if (prev == NULL)
|
||||||
|
{
|
||||||
|
/* Replace the head with the node following glyph */
|
||||||
|
|
||||||
|
g_fcaches = fcache->flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No.. Remove from the head or from mid-list */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev->flink = fcache->flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcache->flink = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxf_cache_lock and nxf_cache_unlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get/relinquish exclusive access to the font cache
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nxf_cache_lock(FAR struct nxfonts_fcache_s *priv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Get exclusive access to the font cache */
|
||||||
|
|
||||||
|
while ((ret = sem_wait(&priv->fsem)) < 0)
|
||||||
|
{
|
||||||
|
int errorcode = errno;
|
||||||
|
DEBUGASSERT(errorcode == EINTR || errorcode == ECANCELED);
|
||||||
|
UNUSED(errorcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define nxf_cache_unlock(p) (sem_post(&priv->fsem))
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxf_removeglyph
|
* Name: nxf_removeglyph
|
||||||
*
|
*
|
||||||
@ -131,7 +213,7 @@ static inline void nxf_removeglyph(FAR struct nxfonts_fcache_s *priv,
|
|||||||
prev->flink = NULL;
|
prev->flink = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No.. removae from mid-list */
|
/* No.. remove from mid-list */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -191,6 +273,9 @@ static inline void nxf_addglyph(FAR struct nxfonts_fcache_s *priv,
|
|||||||
* glyphs since it is now the most recently used (leaving the least
|
* glyphs since it is now the most recently used (leaving the least
|
||||||
* recently used glyph at the tail of the list).
|
* recently used glyph at the tail of the list).
|
||||||
*
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The caller has exclusive access to the font cache.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static FAR struct nxfonts_glyph_s *
|
static FAR struct nxfonts_glyph_s *
|
||||||
@ -340,8 +425,26 @@ static inline void nxf_fillglyph(FAR struct nxfonts_fcache_s *priv,
|
|||||||
#ifndef CONFIG_NX_DISABLE_24BPP
|
#ifndef CONFIG_NX_DISABLE_24BPP
|
||||||
if (priv->bpp == 24)
|
if (priv->bpp == 24)
|
||||||
{
|
{
|
||||||
gerr("ERROR: Additional logic is needed to support 24-bit color\n");
|
FAR uint32_t *ptr = (FAR uint32_t *)glyph->bitmap;
|
||||||
goto errout_with_glyph;
|
FAR uint32_t pixel[3];
|
||||||
|
|
||||||
|
/* Get two 32-bit values for alternating 32 representations */
|
||||||
|
|
||||||
|
pixel[0] = (uint32_t)priv->bgcolor << 8 | (uint32_t)priv->bgcolor >> 16;
|
||||||
|
pixel[1] = (uint32_t)priv->bgcolor << 16 | (uint32_t)priv->bgcolor >> 8;
|
||||||
|
pixel[1] = (uint32_t)priv->bgcolor << 24 | (uint32_t)priv->bgcolor;
|
||||||
|
|
||||||
|
for (row = 0; row < glyph->height; row++)
|
||||||
|
{
|
||||||
|
/* Just copy the color value into the glyph memory */
|
||||||
|
|
||||||
|
for (col = 0; col < glyph->width; col += 3)
|
||||||
|
{
|
||||||
|
*ptr++ = pixel[0];
|
||||||
|
*ptr++ = pixel[1];
|
||||||
|
*ptr++ = pixel[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -370,6 +473,14 @@ static inline void nxf_fillglyph(FAR struct nxfonts_fcache_s *priv,
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxf_renderglyph
|
* Name: nxf_renderglyph
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate memory for a new glyph and render the bitmap font into the
|
||||||
|
* allocated glyph memory.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The caller holds the font cache semaphore.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline FAR struct nxfonts_glyph_s *
|
static inline FAR struct nxfonts_glyph_s *
|
||||||
@ -434,6 +545,13 @@ nxf_renderglyph(FAR struct nxfonts_fcache_s *priv,
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxf_findcache
|
* Name: nxf_findcache
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find a font cache tht matches the font charcteristics.
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* The caller holds the font cache list semaphore.
|
||||||
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static FAR struct nxfonts_fcache_s *
|
static FAR struct nxfonts_fcache_s *
|
||||||
@ -442,9 +560,6 @@ nxf_findcache(enum nx_fontid_e fontid, nxgl_mxpixel_t fgcolor,
|
|||||||
{
|
{
|
||||||
FAR struct nxfonts_fcache_s *fcache;
|
FAR struct nxfonts_fcache_s *fcache;
|
||||||
|
|
||||||
/* Get exclusive access to the font cache list */
|
|
||||||
#warning Missing logic
|
|
||||||
|
|
||||||
/* Search for a cache for this font characteristics */
|
/* Search for a cache for this font characteristics */
|
||||||
|
|
||||||
for (fcache = g_fcaches; fcache != NULL; fcache = fcache->flink)
|
for (fcache = g_fcaches; fcache != NULL; fcache = fcache->flink)
|
||||||
@ -499,6 +614,10 @@ FCACHE nxf_cache_connect(enum nx_fontid_e fontid,
|
|||||||
FAR struct nxfonts_fcache_s *priv;
|
FAR struct nxfonts_fcache_s *priv;
|
||||||
int errcode;
|
int errcode;
|
||||||
|
|
||||||
|
/* Get exclusive access to the font cache list */
|
||||||
|
|
||||||
|
nxf_list_lock();
|
||||||
|
|
||||||
/* Find a font cache with the matching font characteristics */
|
/* Find a font cache with the matching font characteristics */
|
||||||
|
|
||||||
priv = nxf_findcache(fontid, fgcolor, bgcolor, bpp);
|
priv = nxf_findcache(fontid, fgcolor, bgcolor, bpp);
|
||||||
@ -516,7 +635,7 @@ FCACHE nxf_cache_connect(enum nx_fontid_e fontid,
|
|||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
{
|
{
|
||||||
errcode = ENOMEM;
|
errcode = ENOMEM;
|
||||||
goto errout;
|
goto errout_with_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the font cache */
|
/* Initialize the font cache */
|
||||||
@ -598,6 +717,11 @@ FCACHE nxf_cache_connect(enum nx_fontid_e fontid,
|
|||||||
gerr("ERROR: Failed to get font ID %d: %d\n", fontid, errcode);
|
gerr("ERROR: Failed to get font ID %d: %d\n", fontid, errcode);
|
||||||
goto errout_with_fcache;
|
goto errout_with_fcache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add the new font cache to the list of font caches */
|
||||||
|
|
||||||
|
priv->flink = g_fcaches;
|
||||||
|
g_fcaches = priv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -611,11 +735,13 @@ FCACHE nxf_cache_connect(enum nx_fontid_e fontid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxf_list_unlock();
|
||||||
return (FCACHE)priv;
|
return (FCACHE)priv;
|
||||||
|
|
||||||
errout_with_fcache:
|
errout_with_fcache:
|
||||||
lib_free(priv);
|
lib_free(priv);
|
||||||
errout:
|
errout_with_lock:
|
||||||
|
nxf_list_unlock();
|
||||||
set_errno(errcode);
|
set_errno(errcode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -629,36 +755,46 @@ errout:
|
|||||||
* font handle is invalid upon return in either case.
|
* font handle is invalid upon return in either case.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* fcache - A font cache handle previously returned by nxf_cache_connect();
|
* fhandle - A font cache handle previously returned by nxf_cache_connect();
|
||||||
*
|
*
|
||||||
* Returned value:
|
* Returned value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void nxf_cache_disconnect(FCACHE fcache)
|
void nxf_cache_disconnect(FCACHE fhandle)
|
||||||
{
|
{
|
||||||
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fcache;
|
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fhandle;
|
||||||
|
FAR struct nxfonts_fcache_s *fcache;
|
||||||
|
FAR struct nxfonts_fcache_s *prev;
|
||||||
FAR struct nxfonts_glyph_s *glyph;
|
FAR struct nxfonts_glyph_s *glyph;
|
||||||
FAR struct nxfonts_glyph_s *next;
|
FAR struct nxfonts_glyph_s *next;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL && priv->fclients > 0);
|
DEBUGASSERT(priv != NULL && priv->fclients > 0);
|
||||||
|
|
||||||
/* Get exclusive access to the font cache */
|
/* Get exclusive access to the font cache */
|
||||||
|
|
||||||
while ((ret = sem_wait(&priv->fsem)) < 0)
|
nxf_cache_lock(priv);
|
||||||
{
|
|
||||||
int errorcode = errno;
|
|
||||||
DEBUGASSERT(errorcode == EINTR || errorcode == ECANCELED);
|
|
||||||
UNUSED(errorcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this the last client of the font cache? */
|
/* Is this the last client of the font cache? */
|
||||||
|
|
||||||
if (priv->fclients <= 1)
|
if (priv->fclients <= 1)
|
||||||
{
|
{
|
||||||
/* Yes.. destroy the font cache */
|
/* Get exclusive access to the font cache list */
|
||||||
|
|
||||||
|
nxf_list_lock();
|
||||||
|
|
||||||
|
/* Remove the font cache from the list of caches. This is a singly
|
||||||
|
* linked list, so we must do this the hard way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (prev = NULL, fcache = g_fcaches;
|
||||||
|
fcache != priv && fcache != NULL;
|
||||||
|
fcache = fcache->flink);
|
||||||
|
|
||||||
|
ASSERT(fcache == priv);
|
||||||
|
nxf_removecache(fcache, prev);
|
||||||
|
nxf_list_unlock();
|
||||||
|
|
||||||
/* Free all allocated glyph memory */
|
/* Free all allocated glyph memory */
|
||||||
|
|
||||||
@ -683,7 +819,7 @@ void nxf_cache_disconnect(FCACHE fcache)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
priv->fclients--;
|
priv->fclients--;
|
||||||
sem_post(&priv->fsem);
|
nxf_cache_unlock(priv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,7 +831,7 @@ void nxf_cache_disconnect(FCACHE fcache)
|
|||||||
* cache.
|
* cache.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* fcache - A font cache handle previously returned by nxf_cache_connect();
|
* fhandle - A font cache handle previously returned by nxf_cache_connect();
|
||||||
*
|
*
|
||||||
* Returned value:
|
* Returned value:
|
||||||
* Zero (OK) is returned if the metrics were
|
* Zero (OK) is returned if the metrics were
|
||||||
@ -705,9 +841,9 @@ void nxf_cache_disconnect(FCACHE fcache)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
NXHANDLE nxf_cache_getfonthandle(FCACHE fcache)
|
NXHANDLE nxf_cache_getfonthandle(FCACHE fhandle)
|
||||||
{
|
{
|
||||||
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fcache;
|
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fhandle;
|
||||||
|
|
||||||
DEBUGASSERT(priv != NULL && priv->font != NULL);
|
DEBUGASSERT(priv != NULL && priv->font != NULL);
|
||||||
return priv->font;
|
return priv->font;
|
||||||
@ -727,31 +863,32 @@ NXHANDLE nxf_cache_getfonthandle(FCACHE fcache)
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
FAR const struct nxfonts_glyph_s *nxf_cache_getglyph(FCACHE fcache, uint8_t ch)
|
FAR const struct nxfonts_glyph_s *nxf_cache_getglyph(FCACHE fhandle, uint8_t ch)
|
||||||
{
|
{
|
||||||
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fcache;
|
FAR struct nxfonts_fcache_s *priv = (FAR struct nxfonts_fcache_s *)fhandle;
|
||||||
FAR struct nxfonts_glyph_s *glyph;
|
FAR struct nxfonts_glyph_s *glyph;
|
||||||
FAR const struct nx_fontbitmap_s *fbm;
|
FAR const struct nx_fontbitmap_s *fbm;
|
||||||
|
|
||||||
|
/* Get exclusive access to the font cache */
|
||||||
|
|
||||||
|
nxf_cache_lock(priv);
|
||||||
|
|
||||||
/* First, try to find the glyph in the cache of pre-rendered glyphs */
|
/* First, try to find the glyph in the cache of pre-rendered glyphs */
|
||||||
|
|
||||||
glyph = nxf_findglyph(priv, ch);
|
glyph = nxf_findglyph(priv, ch);
|
||||||
if (glyph != NULL)
|
if (glyph == NULL)
|
||||||
{
|
{
|
||||||
/* We found it in the cache .. return the cached glyph */
|
/* No, it is not cached... Does the code map to a font? */
|
||||||
|
|
||||||
return glyph;
|
fbm = nxf_getbitmap(priv->font, ch);
|
||||||
}
|
if (fbm)
|
||||||
|
{
|
||||||
/* No, it is not cached... Does the code map to a font? */
|
/* Yes.. render the glyph */
|
||||||
|
|
||||||
fbm = nxf_getbitmap(priv->font, ch);
|
glyph = nxf_renderglyph(priv, fbm, ch);
|
||||||
if (fbm)
|
}
|
||||||
{
|
|
||||||
/* Yes.. render the glyph */
|
|
||||||
|
|
||||||
glyph = nxf_renderglyph(priv, fbm, ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nxf_cache_unlock(priv);
|
||||||
return glyph;
|
return glyph;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user