diff options
author | greg <greg@blackbox> | 2009-06-19 05:13:07 +0200 |
---|---|---|
committer | greg <greg@blackbox> | 2009-06-19 05:13:07 +0200 |
commit | 457a9146ee07060a8c45b850a69ea5c6bbdae70e (patch) | |
tree | 0c643447b6f4ceddc2ba7508f43660d6f3edb8a1 /libass/ass_cache.h | |
parent | e7e108672381007c2beaec5c436d757cca0017a2 (diff) | |
download | libass-457a9146ee07060a8c45b850a69ea5c6bbdae70e.tar.bz2 libass-457a9146ee07060a8c45b850a69ea5c6bbdae70e.tar.xz |
From uau: libass: Fix cache lookup problem causing memory bloat
The cache code did hash lookups by storing key values in struct fields
and then hashing and comparing the struct as a single memory block. In
at least one case such a struct contained uninitialized padding bytes
which prevented the complete memory area of the struct from matching
even though the fields did. As a result the code failed to find
existing objects in the cache and stored new versions of them, causing
gigabytes of memory use in some circumstances. Initializing the struct
memory to zero before writing the fields avoided such memory use in
tests but is not guaranteed to work if I interpret the C standard
correctly (the compiler is allowed to write garbage over padding bytes
when changing struct member values).
Change the code to use struct-specific hashing and comparison
functions that work field by field to guarantee correct behavior.
Create these by replacing the struct definition with a template that
lists the fields and can be used the generate each of struct
definition, hash function and compare function with some preprocessor
magic (otherwise every field would need to be listed separately in all
three).
Diffstat (limited to 'libass/ass_cache.h')
-rw-r--r-- | libass/ass_cache.h | 34 |
1 files changed, 3 insertions, 31 deletions
diff --git a/libass/ass_cache.h b/libass/ass_cache.h index 59ac8cee..f227303f 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -32,26 +32,9 @@ ass_font_t* ass_font_cache_find(ass_font_desc_t* desc); void* ass_font_cache_add(ass_font_t* font); void ass_font_cache_done(void); - -// describes a bitmap; bitmaps with equivalents structs are considered identical -typedef struct bitmap_hash_key_s { - char bitmap; // bool : true = bitmap, false = outline - ass_font_t* font; - double size; // font size - uint32_t ch; // character code - unsigned outline; // border width, 16.16 fixed point value - int bold, italic; - char be; // blur edges - double blur; // gaussian blur - - unsigned scale_x, scale_y; // 16.16 - int frx, fry, frz; // signed 16.16 - int shift_x, shift_y; // shift vector that was added to glyph before applying rotation - // = 0, if frx = fry = frx = 0 - // = (glyph base point) - (rotation origin), otherwise - - FT_Vector advance; // subpixel shift vector -} bitmap_hash_key_t; +// Create definitions for bitmap_hash_key and glyph_hash_key +#define CREATE_STRUCT_DEFINITIONS +#include "ass_cache_template.c" typedef struct bitmap_hash_val_s { bitmap_t* bm; // the actual bitmaps @@ -86,17 +69,6 @@ void ass_composite_cache_reset(void); void ass_composite_cache_done(void); -// describes an outline glyph -typedef struct glyph_hash_key_s { - ass_font_t* font; - double size; // font size - uint32_t ch; // character code - int bold, italic; - unsigned scale_x, scale_y; // 16.16 - FT_Vector advance; // subpixel shift vector - unsigned outline; // border width, 16.16 -} glyph_hash_key_t; - typedef struct glyph_hash_val_s { FT_Glyph glyph; FT_Glyph outline_glyph; |