FS#12333 - Faster cached font loading

Attached to Project: Rockbox
Opened by Fred Bauer (freddyb) - Friday, 14 October 2011, 03:14 GMT
Last edited by Fred Bauer (freddyb) - Monday, 17 October 2011, 15:48 GMT
Task Type Patches
Category Font/charset
Status Closed
Assigned To No-one
Operating System All players
Severity Low
Priority Low
Reported Version Release 3.9
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No


When font glyphs are loaded from disk there are 3 file sections to read from: width data, offset data, and bitmap data. The number of disk seeks can be very much reduced by opening the font file with three separate file descriptors, each of which have a small cache. This is a small patch that opens additional file descriptors for width and offset data during glyph_cache_load(). The fd's are closed after the initial load so it only uses two extra fd's for a short time. It's a bit of a kludge but it increases initial glyph loading speed about 600% for a cached font.
This task depends upon

Closed by  Fred Bauer (freddyb)
Monday, 17 October 2011, 15:48 GMT
Reason for closing:  Accepted
Additional comments about closing:  in 30769.
Comment by Fred Bauer (freddyb) - Friday, 14 October 2011, 22:10 GMT
Resync to SVN.
Update convbdf.c c source generation to include extra structure members.
Comment by Thomas Martitz (kugel.) - Saturday, 15 October 2011, 12:15 GMT
I'm not sure I understand this patch correctly.

- Does this change the font structure in a way that existing fonts are incompatible?
- Is lseek() that bad? I thought it was bad if the underlying disk needs to actually seek. I don't see how multple FDs can help the disk there. Also you don't actually reduce lseek() calls do you?
Comment by Fred Bauer (freddyb) - Saturday, 15 October 2011, 21:25 GMT
Lseek() can be cheap or expensive depending on if the seek is outside of the cache.
When a font loads a glyph it does the following:
1) reads 1 byte from the width section of the file
2) reads 2-4 bytes from the offset section of the file
3) reads the bitmap data pointed to by the offset
4) glyph
The default font preload without a .glyphcache file is to load 224 glyphs and some fonts are spread over 100,000's of bytes. The seeks are mostly cache misses because the read locations are round-robin.
Opening separate file handles for width, offset, and bitmap data gives you a small amount of cache for each section so that width and offset data would only be lseeked a few times as each seek/read is hitting the same cache repeatedly. It's not about having multiple fd's, but having three caches.

The font files do not change.

Comment by Fred Bauer (freddyb) - Monday, 17 October 2011, 02:01 GMT
Resynced and simplified glyph_cache_load() by removing some of the old glyph presorting code which will no longer be necessary.