[gsubgpos] Add a cache to intersected_class_glyphs

30% gain on subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400.
This commit is contained in:
Behdad Esfahbod 2022-12-03 12:13:15 -07:00
parent c044f4af3e
commit 630b874ae6
1 changed files with 54 additions and 18 deletions

View File

@ -1003,7 +1003,7 @@ struct hb_accelerate_subtables_context_t :
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache); typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data, void *cache);
typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache);
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data); typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data);
typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
@ -1052,17 +1052,36 @@ static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value,
} }
static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs) static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
{ {
unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value]; unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value];
intersected_glyphs->add (g); intersected_glyphs->add (g);
} }
static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
using intersected_class_cache_t = hb_hashmap_t<unsigned, hb_set_t>;
static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, void *cache)
{ {
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs);
intersected_class_cache_t *map = (intersected_class_cache_t *) cache;
hb_set_t *cached_v;
if (map->has (value, &cached_v))
{
intersected_glyphs->union_ (*cached_v);
return;
}
hb_set_t v;
class_def.intersected_class_glyphs (glyphs, value, &v);
intersected_glyphs->union_ (v);
map->set (value, std::move (v));
} }
static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs, HB_UNUSED void *cache)
{ {
Offset16To<Coverage> coverage; Offset16To<Coverage> coverage;
coverage = value; coverage = value;
@ -1516,7 +1535,8 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
unsigned value, unsigned value,
ContextFormat context_format, ContextFormat context_format,
const void *data, const void *data,
intersected_glyphs_func_t intersected_glyphs_func) intersected_glyphs_func_t intersected_glyphs_func,
void *cache)
{ {
hb_set_t *covered_seq_indicies = hb_set_create (); hb_set_t *covered_seq_indicies = hb_set_create ();
for (unsigned int i = 0; i < lookupCount; i++) for (unsigned int i = 0; i < lookupCount; i++)
@ -1537,7 +1557,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
pos_glyphs.add (value); pos_glyphs.add (value);
break; break;
case ContextFormat::ClassBasedContext: case ContextFormat::ClassBasedContext:
intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs); intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs, cache);
break; break;
case ContextFormat::CoverageBasedContext: case ContextFormat::CoverageBasedContext:
pos_glyphs.set (c->parent_active_glyphs ()); pos_glyphs.set (c->parent_active_glyphs ());
@ -1554,7 +1574,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
input_value = input[seqIndex - 1]; input_value = input[seqIndex - 1];
} }
intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs); intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs, cache);
} }
} }
@ -1734,7 +1754,8 @@ struct ContextClosureLookupContext
ContextClosureFuncs funcs; ContextClosureFuncs funcs;
ContextFormat context_format; ContextFormat context_format;
const void *intersects_data; const void *intersects_data;
void *cache; void *intersects_cache;
void *intersected_glyphs_cache;
}; };
struct ContextCollectGlyphsLookupContext struct ContextCollectGlyphsLookupContext
@ -1757,7 +1778,9 @@ static inline bool context_intersects (const hb_set_t *glyphs,
{ {
return array_is_subset_of (glyphs, return array_is_subset_of (glyphs,
inputCount ? inputCount - 1 : 0, input, inputCount ? inputCount - 1 : 0, input,
lookup_context.funcs.intersects, lookup_context.intersects_data, lookup_context.cache); lookup_context.funcs.intersects,
lookup_context.intersects_data,
lookup_context.intersects_cache);
} }
template <typename HBUINT> template <typename HBUINT>
@ -1778,7 +1801,8 @@ static inline void context_closure_lookup (hb_closure_context_t *c,
value, value,
lookup_context.context_format, lookup_context.context_format,
lookup_context.intersects_data, lookup_context.intersects_data,
lookup_context.funcs.intersected_glyphs); lookup_context.funcs.intersected_glyphs,
lookup_context.intersected_glyphs_cache);
} }
template <typename HBUINT> template <typename HBUINT>
@ -2287,11 +2311,13 @@ struct ContextFormat2_5
const ClassDef &class_def = this+classDef; const ClassDef &class_def = this+classDef;
hb_map_t cache; hb_map_t cache;
intersected_class_cache_t intersected_cache;
struct ContextClosureLookupContext lookup_context = { struct ContextClosureLookupContext lookup_context = {
{intersects_class, intersected_class_glyphs}, {intersects_class, intersected_class_glyphs},
ContextFormat::ClassBasedContext, ContextFormat::ClassBasedContext,
&class_def, &class_def,
&cache &cache,
&intersected_cache
}; };
+ hb_enumerate (ruleSet) + hb_enumerate (ruleSet)
@ -2690,7 +2716,8 @@ struct ChainContextClosureLookupContext
ContextClosureFuncs funcs; ContextClosureFuncs funcs;
ContextFormat context_format; ContextFormat context_format;
const void *intersects_data[3]; const void *intersects_data[3];
void *cache[3]; void *intersects_cache[3];
void *intersected_glyphs_cache;
}; };
struct ChainContextCollectGlyphsLookupContext struct ChainContextCollectGlyphsLookupContext
@ -2717,13 +2744,19 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs,
{ {
return array_is_subset_of (glyphs, return array_is_subset_of (glyphs,
backtrackCount, backtrack, backtrackCount, backtrack,
lookup_context.funcs.intersects, lookup_context.intersects_data[0], lookup_context.cache[0]) lookup_context.funcs.intersects,
lookup_context.intersects_data[0],
lookup_context.intersects_cache[0])
&& array_is_subset_of (glyphs, && array_is_subset_of (glyphs,
inputCount ? inputCount - 1 : 0, input, inputCount ? inputCount - 1 : 0, input,
lookup_context.funcs.intersects, lookup_context.intersects_data[1], lookup_context.cache[1]) lookup_context.funcs.intersects,
lookup_context.intersects_data[1],
lookup_context.intersects_cache[1])
&& array_is_subset_of (glyphs, && array_is_subset_of (glyphs,
lookaheadCount, lookahead, lookaheadCount, lookahead,
lookup_context.funcs.intersects, lookup_context.intersects_data[2], lookup_context.cache[2]); lookup_context.funcs.intersects,
lookup_context.intersects_data[2],
lookup_context.intersects_cache[2]);
} }
template <typename HBUINT> template <typename HBUINT>
@ -2750,7 +2783,8 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
value, value,
lookup_context.context_format, lookup_context.context_format,
lookup_context.intersects_data[1], lookup_context.intersects_data[1],
lookup_context.funcs.intersected_glyphs); lookup_context.funcs.intersected_glyphs,
lookup_context.intersected_glyphs_cache);
} }
template <typename HBUINT> template <typename HBUINT>
@ -3363,13 +3397,15 @@ struct ChainContextFormat2_5
const ClassDef &lookahead_class_def = this+lookaheadClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef;
hb_map_t caches[3] = {}; hb_map_t caches[3] = {};
intersected_class_cache_t intersected_cache;
struct ChainContextClosureLookupContext lookup_context = { struct ChainContextClosureLookupContext lookup_context = {
{intersects_class, intersected_class_glyphs}, {intersects_class, intersected_class_glyphs},
ContextFormat::ClassBasedContext, ContextFormat::ClassBasedContext,
{&backtrack_class_def, {&backtrack_class_def,
&input_class_def, &input_class_def,
&lookahead_class_def}, &lookahead_class_def},
{&caches[0], &caches[1], &caches[2]} {&caches[0], &caches[1], &caches[2]},
&intersected_cache
}; };
+ hb_enumerate (ruleSet) + hb_enumerate (ruleSet)