[layout] Reduce memory use slightly

By using raw pointer instead of vector for subtable accelerator.

To be used for more memory saving by making subtable accelerators
lazy-loaded by shape-plans for large fonts.
This commit is contained in:
Behdad Esfahbod 2023-01-31 14:32:14 -07:00
parent 2b6d74b42e
commit 83353f13f4
4 changed files with 32 additions and 24 deletions

View File

@ -67,7 +67,7 @@ inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply
if (lookup_index < gpos->lookup_count) if (lookup_index < gpos->lookup_count)
{ {
auto &accel = gpos->accels[lookup_index]; auto &accel = gpos->accels[lookup_index];
ret = accel.apply (c, false); ret = accel.apply (c, l.get_subtable_count (), false);
} }
c->set_lookup_index (saved_lookup_index); c->set_lookup_index (saved_lookup_index);

View File

@ -80,7 +80,7 @@ inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_app
if (lookup_index < gsub->lookup_count) if (lookup_index < gsub->lookup_count)
{ {
auto &accel = gsub->accels[lookup_index]; auto &accel = gsub->accels[lookup_index];
ret = accel.apply (c, false); ret = accel.apply (c, l.get_subtable_count (), false);
} }
c->set_lookup_index (saved_lookup_index); c->set_lookup_index (saved_lookup_index);

View File

@ -944,8 +944,6 @@ struct hb_accelerate_subtables_context_t :
hb_set_digest_t digest; hb_set_digest_t digest;
}; };
typedef hb_vector_t<hb_applicable_t> array_t;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
template <typename T> template <typename T>
auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () ) auto cache_cost (const T &obj, hb_priority<1>) HB_AUTO_RETURN ( obj.cache_cost () )
@ -957,7 +955,7 @@ struct hb_accelerate_subtables_context_t :
template <typename T> template <typename T>
return_t dispatch (const T &obj) return_t dispatch (const T &obj)
{ {
hb_applicable_t *entry = array.push (); hb_applicable_t *entry = &array[i++];
entry->init (obj, entry->init (obj,
apply_to<T> apply_to<T>
@ -977,9 +975,9 @@ struct hb_accelerate_subtables_context_t :
* and we allocate the cache opportunity to the costliest subtable. * and we allocate the cache opportunity to the costliest subtable.
*/ */
unsigned cost = cache_cost (obj, hb_prioritize); unsigned cost = cache_cost (obj, hb_prioritize);
if (cost > cache_user_cost && !array.in_error ()) if (cost > cache_user_cost)
{ {
cache_user_idx = array.length - 1; cache_user_idx = i - 1;
cache_user_cost = cost; cache_user_cost = cost;
} }
#endif #endif
@ -988,10 +986,11 @@ struct hb_accelerate_subtables_context_t :
} }
static return_t default_return_value () { return hb_empty_t (); } static return_t default_return_value () { return hb_empty_t (); }
hb_accelerate_subtables_context_t (array_t &array_) : hb_accelerate_subtables_context_t (hb_applicable_t *array_) :
array (array_) {} array (array_) {}
array_t &array; hb_applicable_t *array;
unsigned i = 0;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
unsigned cache_user_idx = (unsigned) -1; unsigned cache_user_idx = (unsigned) -1;
@ -4016,34 +4015,40 @@ struct hb_ot_layout_lookup_accelerator_t
template <typename TLookup> template <typename TLookup>
void init (const TLookup &lookup) void init (const TLookup &lookup)
{ {
subtables.init (); unsigned count = lookup.get_subtable_count ();
subtables.alloc (lookup.get_subtable_count (), true); subtables = (hb_accelerate_subtables_context_t::hb_applicable_t *)
hb_calloc (count, sizeof (hb_accelerate_subtables_context_t::hb_applicable_t));
if (unlikely (!subtables))
return;
hb_accelerate_subtables_context_t c_accelerate_subtables (subtables); hb_accelerate_subtables_context_t c_accelerate_subtables (subtables);
lookup.dispatch (&c_accelerate_subtables); lookup.dispatch (&c_accelerate_subtables);
digest.init (); digest.init ();
for (auto& subtable : subtables) for (auto& subtable : hb_iter (subtables, count))
digest.add (subtable.digest); digest.add (subtable.digest);
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
cache_user_idx = c_accelerate_subtables.cache_user_idx; cache_user_idx = c_accelerate_subtables.cache_user_idx;
for (unsigned i = 0; i < subtables.length; i++) for (unsigned i = 0; i < count; i++)
if (i != cache_user_idx) if (i != cache_user_idx)
subtables[i].apply_cached_func = subtables[i].apply_func; subtables[i].apply_cached_func = subtables[i].apply_func;
#endif #endif
} }
void fini () { subtables.fini (); } void fini () { hb_free (subtables); }
bool may_have (hb_codepoint_t g) const bool may_have (hb_codepoint_t g) const
{ return digest.may_have (g); } { return digest.may_have (g); }
bool apply (hb_ot_apply_context_t *c, bool use_cache) const bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
{ {
if (unlikely (!subtables)) return false;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
if (use_cache) if (use_cache)
{ {
return return
+ hb_iter (subtables) + hb_iter (hb_iter (subtables, subtables_count))
| hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); }) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply_cached (c); })
| hb_any | hb_any
; ;
@ -4052,7 +4057,7 @@ struct hb_ot_layout_lookup_accelerator_t
#endif #endif
{ {
return return
+ hb_iter (subtables) + hb_iter (hb_iter (subtables, subtables_count))
| hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); }) | hb_map ([&c] (const hb_accelerate_subtables_context_t::hb_applicable_t &_) { return _.apply (c); })
| hb_any | hb_any
; ;
@ -4079,7 +4084,7 @@ struct hb_ot_layout_lookup_accelerator_t
hb_set_digest_t digest; hb_set_digest_t digest;
private: private:
hb_accelerate_subtables_context_t::array_t subtables; hb_accelerate_subtables_context_t::hb_applicable_t *subtables;
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
unsigned cache_user_idx = (unsigned) -1; unsigned cache_user_idx = (unsigned) -1;
#endif #endif

View File

@ -1854,7 +1854,8 @@ struct GPOSProxy
static inline bool static inline bool
apply_forward (OT::hb_ot_apply_context_t *c, apply_forward (OT::hb_ot_apply_context_t *c,
const OT::hb_ot_layout_lookup_accelerator_t &accel) const OT::hb_ot_layout_lookup_accelerator_t &accel,
unsigned subtable_count)
{ {
bool use_cache = accel.cache_enter (c); bool use_cache = accel.cache_enter (c);
@ -1867,7 +1868,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
(buffer->cur().mask & c->lookup_mask) && (buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props)) c->check_glyph_property (&buffer->cur(), c->lookup_props))
{ {
applied = accel.apply (c, use_cache); applied = accel.apply (c, subtable_count, use_cache);
} }
if (applied) if (applied)
@ -1884,7 +1885,8 @@ apply_forward (OT::hb_ot_apply_context_t *c,
static inline bool static inline bool
apply_backward (OT::hb_ot_apply_context_t *c, apply_backward (OT::hb_ot_apply_context_t *c,
const OT::hb_ot_layout_lookup_accelerator_t &accel) const OT::hb_ot_layout_lookup_accelerator_t &accel,
unsigned subtable_count)
{ {
bool ret = false; bool ret = false;
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
@ -1893,7 +1895,7 @@ apply_backward (OT::hb_ot_apply_context_t *c,
if (accel.digest.may_have (buffer->cur().codepoint) && if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) && (buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props)) c->check_glyph_property (&buffer->cur(), c->lookup_props))
ret |= accel.apply (c, false); ret |= accel.apply (c, subtable_count, false);
/* The reverse lookup doesn't "advance" cursor (for good reason). */ /* The reverse lookup doesn't "advance" cursor (for good reason). */
buffer->idx--; buffer->idx--;
@ -1911,6 +1913,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
{ {
bool ret = false; bool ret = false;
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
unsigned subtable_count = lookup.get_subtable_count ();
if (unlikely (!buffer->len || !c->lookup_mask)) if (unlikely (!buffer->len || !c->lookup_mask))
return ret; return ret;
@ -1924,7 +1927,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
buffer->clear_output (); buffer->clear_output ();
buffer->idx = 0; buffer->idx = 0;
ret = apply_forward (c, accel); ret = apply_forward (c, accel, subtable_count);
if (!Proxy::always_inplace) if (!Proxy::always_inplace)
buffer->sync (); buffer->sync ();
@ -1934,7 +1937,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
/* in-place backward substitution/positioning */ /* in-place backward substitution/positioning */
assert (!buffer->have_output); assert (!buffer->have_output);
buffer->idx = buffer->len - 1; buffer->idx = buffer->len - 1;
ret = apply_backward (c, accel); ret = apply_backward (c, accel, subtable_count);
} }
return ret; return ret;