Merge pull request #5042 from harfbuzz/aat-regression

[aat] Fix performance regression
pull/5043/head
Behdad Esfahbod 1 week ago committed by GitHub
commit dc8da6129f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 25
      src/hb-aat-layout-common.hh
  2. 30
      src/hb-aat-layout-morx-table.hh

@ -66,6 +66,7 @@ struct hb_aat_apply_context_t :
const ankr *ankr_table;
const OT::GDEF *gdef_table;
const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
bool using_buffer_glyph_set = false;
hb_bit_set_t buffer_glyph_set;
const hb_bit_set_t *left_set = nullptr;
const hb_bit_set_t *right_set = nullptr;
@ -86,6 +87,30 @@ struct hb_aat_apply_context_t :
HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
void set_lookup_index (unsigned int i) { lookup_index = i; }
#define HB_MALLOC_COST 48
#define HB_BIT_SET_HAS_COST 8
void setup_buffer_glyph_set (unsigned subchain_count)
{
// Using buffer_glyph_set has at least two mallocs. Avoid it for small workloads.
unsigned malloced_cost = HB_MALLOC_COST * 2 + subchain_count * HB_BIT_SET_HAS_COST;
unsigned unmalloced_cost = subchain_count * buffer->len;
using_buffer_glyph_set = malloced_cost < unmalloced_cost;
if (using_buffer_glyph_set)
buffer_glyph_set = buffer->bit_set ();
}
bool buffer_intersects_machine () const
{
if (using_buffer_glyph_set)
return buffer_glyph_set.intersects (*machine_glyph_set);
// Faster for shorter buffers.
for (unsigned i = 0; i < buffer->len; i++)
if (machine_glyph_set->has (buffer->info[i].codepoint))
return true;
return false;
}
};

@ -177,7 +177,7 @@ struct RearrangementSubtable
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
if (!c->buffer_glyph_set.intersects (*c->machine_glyph_set))
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches");
return_trace (false);
@ -347,7 +347,7 @@ struct ContextualSubtable
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
if (!c->buffer_glyph_set.intersects (*c->machine_glyph_set))
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches");
return_trace (false);
@ -623,7 +623,7 @@ struct LigatureSubtable
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
if (!c->buffer_glyph_set.intersects (*c->machine_glyph_set))
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches");
return_trace (false);
@ -664,8 +664,11 @@ struct NoncontextualSubtable
{
TRACE_APPLY (this);
if (!c->buffer_glyph_set.intersects (*c->machine_glyph_set))
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches");
return_trace (false);
}
const OT::GDEF &gdef (*c->gdef_table);
bool has_glyph_classes = gdef.has_glyph_classes ();
@ -917,7 +920,7 @@ struct InsertionSubtable
StateTableDriver<Types, EntryData, Flags> driver (machine, c->face);
if (!c->buffer_glyph_set.intersects (*c->machine_glyph_set))
if (!c->buffer_intersects_machine ())
{
(void) c->buffer->message (c->font, "skipped chainsubtable because no glyph matches");
return_trace (false);
@ -1371,11 +1374,13 @@ struct mortmorx
}
this->chain_count = table->get_chain_count ();
this->subchain_count = table->get_subchain_count ();
this->accels = (hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *) hb_calloc (this->chain_count, sizeof (*accels));
if (unlikely (!this->accels))
{
this->chain_count = 0;
this->subchain_count = 0;
this->table.destroy ();
this->table = hb_blob_get_empty ();
}
@ -1419,6 +1424,7 @@ struct mortmorx
hb_blob_ptr_t<T> table;
unsigned int chain_count;
unsigned int subchain_count;
hb_atomic_ptr_t<hb_aat_layout_chain_accelerator_t> *accels;
};
@ -1443,6 +1449,18 @@ struct mortmorx
{
return chainCount;
}
unsigned get_subchain_count () const
{
const Chain<Types> *chain = &firstChain;
unsigned int count = chainCount;
unsigned int subchain_count = 0;
for (unsigned int i = 0; i < count; i++)
{
subchain_count += chain->get_subtable_count ();
chain = &StructAfter<Chain<Types>> (*chain);
}
return subchain_count;
}
void apply (hb_aat_apply_context_t *c,
const hb_aat_map_t &map,
@ -1452,7 +1470,7 @@ struct mortmorx
c->buffer->unsafe_to_concat ();
c->buffer_glyph_set = c->buffer->bit_set ();
c->setup_buffer_glyph_set (accel.subchain_count);
c->set_lookup_index (0);
const Chain<Types> *chain = &firstChain;

Loading…
Cancel
Save