From d5d199fbc73d123809982b36624eb9a84e632df5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 24 Feb 2025 23:20:12 -0700 Subject: [PATCH] [VARC] Reduce malloc pressure By caching one hb_glyf_scratch_t on the VARC accelerator. --- src/OT/Var/VARC/VARC.cc | 2 +- src/OT/Var/VARC/VARC.hh | 67 ++++++++++++++++++++++++++++++++++-- src/hb-ot-face-table-list.hh | 2 +- src/hb-ot-face.cc | 1 + 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/OT/Var/VARC/VARC.cc b/src/OT/Var/VARC/VARC.cc index af30fc5d1..9bdaea6bc 100644 --- a/src/OT/Var/VARC/VARC.cc +++ b/src/OT/Var/VARC/VARC.cc @@ -143,7 +143,7 @@ VarComponent::get_path_at (hb_font_t *font, const unsigned char *end = total_record.arrayZ + total_record.length; const unsigned char *record = total_record.arrayZ; - auto &VARC = *font->face->table.VARC; + auto &VARC = *font->face->table.VARC->table; auto &varStore = &VARC+VARC.varStore; #define READ_UINT32VAR(name) \ diff --git a/src/OT/Var/VARC/VARC.hh b/src/OT/Var/VARC/VARC.hh index 95f58cfd5..bc6dcc04f 100644 --- a/src/OT/Var/VARC/VARC.hh +++ b/src/OT/Var/VARC/VARC.hh @@ -104,12 +104,13 @@ struct VARC hb_glyf_scratch_t &scratch) const; bool - get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + get_path (hb_font_t *font, + hb_codepoint_t gid, + hb_draw_session_t &draw_session, + hb_glyf_scratch_t &scratch) const { hb_decycler_t decycler; signed edges = HB_MAX_GRAPH_EDGE_COUNT; - hb_glyf_scratch_t scratch; - scratch.warm_up (); return get_path_at (font, gid, @@ -136,6 +137,62 @@ struct VARC glyphRecords.sanitize (c, this)); } + struct accelerator_t + { + friend struct VarComponent; + + accelerator_t (hb_face_t *face) + { + table = hb_sanitize_context_t ().reference_table (face); + } + ~accelerator_t () + { + auto *scratch = cached_scratch.get_relaxed (); + if (scratch) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + table.destroy (); + } + + bool + get_path (hb_font_t *font, hb_codepoint_t gid, hb_draw_session_t &draw_session) const + { + hb_glyf_scratch_t *scratch; + + // Borrow the cached strach buffer. + do + { + scratch = cached_scratch.get_relaxed (); + if (!scratch) + { + scratch = (hb_glyf_scratch_t *) hb_calloc (1, sizeof (hb_glyf_scratch_t)); + if (unlikely (!scratch)) + return true; + break; + } + } + while (!cached_scratch.cmpexch (scratch, nullptr)); + + bool ret = table->get_path (font, gid, draw_session, *scratch); + + // Put it back. + if (!cached_scratch.cmpexch (nullptr, scratch)) + { + scratch->~hb_glyf_scratch_t (); + hb_free (scratch); + } + + return ret; + } + + private: + hb_blob_ptr_t table; + hb_atomic_ptr_t cached_scratch; + }; + protected: FixedVersion<> version; /* Version identifier */ Offset32To coverage; @@ -147,6 +204,10 @@ struct VARC DEFINE_SIZE_STATIC (24); }; +struct VARC_accelerator_t : VARC::accelerator_t { + VARC_accelerator_t (hb_face_t *face) : VARC::accelerator_t (face) {} +}; + #endif //} diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh index dd4befffa..d52f98a78 100644 --- a/src/hb-ot-face-table-list.hh +++ b/src/hb-ot-face-table-list.hh @@ -97,7 +97,7 @@ HB_OT_CORE_TABLE (OT, cvar) HB_OT_ACCELERATOR (OT, gvar) HB_OT_CORE_TABLE (OT, MVAR) #ifndef HB_NO_VAR_COMPOSITES -HB_OT_CORE_TABLE (OT, VARC) +HB_OT_ACCELERATOR (OT, VARC) #endif #endif diff --git a/src/hb-ot-face.cc b/src/hb-ot-face.cc index b0c927979..1cf14f3eb 100644 --- a/src/hb-ot-face.cc +++ b/src/hb-ot-face.cc @@ -41,6 +41,7 @@ #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-var-varc-table.hh" #include "hb-aat-layout-kerx-table.hh" #include "hb-aat-layout-morx-table.hh"