From 83353f13f45fefbf0ad1eb0d5388b2c8bf2f7702 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 31 Jan 2023 14:32:14 -0700 Subject: [PATCH] [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. --- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-ot-layout-gsub-table.hh | 2 +- src/hb-ot-layout-gsubgpos.hh | 37 +++++++++++++++++++--------------- src/hb-ot-layout.cc | 15 ++++++++------ 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index f99f86a2a..afc02f5ef 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -67,7 +67,7 @@ inline bool PosLookup::dispatch_recurse_func (hb_ot_apply if (lookup_index < gpos->lookup_count) { 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); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 418116126..6a3d12ce0 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -80,7 +80,7 @@ inline bool SubstLookup::dispatch_recurse_func (hb_ot_app if (lookup_index < gsub->lookup_count) { 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); diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index db6177383..1b9be91d3 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -944,8 +944,6 @@ struct hb_accelerate_subtables_context_t : hb_set_digest_t digest; }; - typedef hb_vector_t array_t; - #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE template 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 return_t dispatch (const T &obj) { - hb_applicable_t *entry = array.push (); + hb_applicable_t *entry = &array[i++]; entry->init (obj, apply_to @@ -977,9 +975,9 @@ struct hb_accelerate_subtables_context_t : * and we allocate the cache opportunity to the costliest subtable. */ 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; } #endif @@ -988,10 +986,11 @@ struct hb_accelerate_subtables_context_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_t &array; + hb_applicable_t *array; + unsigned i = 0; #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE unsigned cache_user_idx = (unsigned) -1; @@ -4016,34 +4015,40 @@ struct hb_ot_layout_lookup_accelerator_t template void init (const TLookup &lookup) { - subtables.init (); - subtables.alloc (lookup.get_subtable_count (), true); + unsigned count = lookup.get_subtable_count (); + 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); lookup.dispatch (&c_accelerate_subtables); digest.init (); - for (auto& subtable : subtables) + for (auto& subtable : hb_iter (subtables, count)) digest.add (subtable.digest); #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE 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) subtables[i].apply_cached_func = subtables[i].apply_func; #endif } - void fini () { subtables.fini (); } + void fini () { hb_free (subtables); } bool may_have (hb_codepoint_t g) const { 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 if (use_cache) { 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_any ; @@ -4052,7 +4057,7 @@ struct hb_ot_layout_lookup_accelerator_t #endif { 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_any ; @@ -4079,7 +4084,7 @@ struct hb_ot_layout_lookup_accelerator_t hb_set_digest_t digest; 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 unsigned cache_user_idx = (unsigned) -1; #endif diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 8d098767f..dcaf62d91 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1854,7 +1854,8 @@ struct GPOSProxy static inline bool 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); @@ -1867,7 +1868,7 @@ apply_forward (OT::hb_ot_apply_context_t *c, (buffer->cur().mask & c->lookup_mask) && 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) @@ -1884,7 +1885,8 @@ apply_forward (OT::hb_ot_apply_context_t *c, static inline bool 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; 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) && (buffer->cur().mask & c->lookup_mask) && 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). */ buffer->idx--; @@ -1911,6 +1913,7 @@ apply_string (OT::hb_ot_apply_context_t *c, { bool ret = false; hb_buffer_t *buffer = c->buffer; + unsigned subtable_count = lookup.get_subtable_count (); if (unlikely (!buffer->len || !c->lookup_mask)) return ret; @@ -1924,7 +1927,7 @@ apply_string (OT::hb_ot_apply_context_t *c, buffer->clear_output (); buffer->idx = 0; - ret = apply_forward (c, accel); + ret = apply_forward (c, accel, subtable_count); if (!Proxy::always_inplace) buffer->sync (); @@ -1934,7 +1937,7 @@ apply_string (OT::hb_ot_apply_context_t *c, /* in-place backward substitution/positioning */ assert (!buffer->have_output); buffer->idx = buffer->len - 1; - ret = apply_backward (c, accel); + ret = apply_backward (c, accel, subtable_count); } return ret;