[VARC] Reduce malloc pressure

By caching one hb_glyf_scratch_t on the VARC accelerator.
This commit is contained in:
Behdad Esfahbod 2025-02-24 23:20:12 -07:00
parent 2c5ab14aaa
commit d5d199fbc7
4 changed files with 67 additions and 5 deletions

View file

@ -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) \

View file

@ -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<VARC> (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<VARC> table;
hb_atomic_ptr_t<hb_glyf_scratch_t> cached_scratch;
};
protected:
FixedVersion<> version; /* Version identifier */
Offset32To<Coverage> 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
//}

View file

@ -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

View file

@ -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"