From 1994df6844d9b478f2199d63e70e88996e3b4096 Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Mon, 23 Aug 2010 18:17:54 +0000 Subject: Read glyph cache in disk order to speed up loading - FS#11168 by Fred Bauer git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27864 a1c6a512-1295-4272-9138-f99709370657 --- firmware/font.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'firmware') diff --git a/firmware/font.c b/firmware/font.c index b8ad76ec3a..d4f0dfa77a 100644 --- a/firmware/font.c +++ b/firmware/font.c @@ -28,6 +28,7 @@ #include #include +#include #include "inttypes.h" #include "lcd.h" #include "font.h" @@ -57,7 +58,6 @@ #define FONT_HEADER_SIZE 36 #endif - #ifndef BOOTLOADER /* Font cache includes */ #include "font_cache.h" @@ -586,9 +586,12 @@ static void glyph_file_write(void* data) unsigned short ch; unsigned char tmp[2]; + if ( p->_char_code == 0xffff ) + return; + ch = p->_char_code + pf->firstchar; - if (ch != 0xffff && cache_fd >= 0) { + if ( cache_fd >= 0) { tmp[0] = ch >> 8; tmp[1] = ch & 0xff; if (write(cache_fd, tmp, 2) != 2) { @@ -625,28 +628,73 @@ void glyph_cache_save(struct font* pf) return; } +static int ushortcmp(const void *a, const void *b) +{ + return ((int)(*(unsigned short*)a - *(unsigned short*)b)); +} static void glyph_cache_load(struct font* pf) { + +#define MAX_SORT 256 if (pf->fd >= 0) { int fd; + int i, size; unsigned char tmp[2]; unsigned short ch; char path[MAX_PATH]; + unsigned short glyphs[MAX_SORT]; + unsigned short glyphs_lru_order[MAX_SORT]; + int glyph_file_skip=0, glyph_file_size=0; + + int sort_size = pf->cache._capacity; + if ( sort_size > MAX_SORT ) + sort_size = MAX_SORT; fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE, path, sizeof(path)), O_RDONLY|O_BINARY); if (fd >= 0) { + + /* only read what fits */ + glyph_file_size = filesize( fd ); + if ( glyph_file_size > 2*pf->cache._capacity ) { + glyph_file_skip = glyph_file_size - 2*pf->cache._capacity; + lseek( fd, glyph_file_skip, SEEK_SET ); + } - while (read(fd, tmp, 2) == 2) { - ch = (tmp[0] << 8) | tmp[1]; - font_get_bits(pf, ch); + while(1) { + + for ( size = 0; + read( fd, tmp, 2 ) == 2 && size < sort_size; + size++ ) + { + glyphs[size] = (tmp[0] << 8) | tmp[1]; + glyphs_lru_order[size] = glyphs[size]; + } + + /* sort glyphs array to make sector cache happy */ + qsort((void *)glyphs, size, sizeof(unsigned short), + ushortcmp ); + + /* load font bitmaps */ + i = 0; + font_get_bits(pf, glyphs[i]); + for ( i = 1; i < size ; i++) { + if ( glyphs[i] != glyphs[i-1] ) + font_get_bits(pf, glyphs[i]); + } + + /* redo to fix lru order */ + for ( i = 0; i < size ; i++) + font_get_bits(pf, glyphs_lru_order[i]); + + if ( size < sort_size ) + break; } close(fd); } else { /* load latin1 chars into cache */ - ch = 256; - while (ch-- > 32) + for ( ch = 32 ; ch < 256 ; ch++ ); font_get_bits(pf, ch); } } -- cgit