[repacker] for ext promotion choose lookups from highest subtables per byte to lowest.
Attempts to roughly maximize the number of subtables that are non-ext.
This commit is contained in:
parent
9d0b2da51b
commit
f56e66f3f0
|
@ -348,6 +348,8 @@ HB_SUBSET_sources = \
|
||||||
hb-subset.hh \
|
hb-subset.hh \
|
||||||
hb-repacker.hh \
|
hb-repacker.hh \
|
||||||
graph/graph.hh \
|
graph/graph.hh \
|
||||||
|
graph/gsubgpos-graph.hh \
|
||||||
|
graph/gsubgpos-graph.cc \
|
||||||
graph/serialize.hh \
|
graph/serialize.hh \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,29 @@ using graph::graph_t;
|
||||||
* docs/repacker.md
|
* docs/repacker.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct lookup_size_t
|
||||||
|
{
|
||||||
|
unsigned lookup_index;
|
||||||
|
size_t size;
|
||||||
|
unsigned num_subtables;
|
||||||
|
};
|
||||||
|
|
||||||
inline int compare_sizes (const void* a, const void* b)
|
inline int compare_sizes (const void* a, const void* b)
|
||||||
{
|
{
|
||||||
hb_pair_t<unsigned, size_t>* size_a = (hb_pair_t<unsigned, size_t>*) a;
|
lookup_size_t* size_a = (lookup_size_t*) a;
|
||||||
hb_pair_t<unsigned, size_t>* size_b = (hb_pair_t<unsigned, size_t>*) b;
|
lookup_size_t* size_b = (lookup_size_t*) b;
|
||||||
if (size_a->second == size_b->second) {
|
|
||||||
return size_b->first - size_a->first;
|
double subtables_per_byte_a = (double) size_a->num_subtables / (double) size_a->size;
|
||||||
|
double subtables_per_byte_b = (double) size_b->num_subtables / (double) size_b->size;
|
||||||
|
|
||||||
|
if (subtables_per_byte_a == subtables_per_byte_b) {
|
||||||
|
return size_b->lookup_index - size_b->lookup_index;
|
||||||
|
|
||||||
}
|
}
|
||||||
return size_a->second - size_b->second;
|
double cmp = subtables_per_byte_b - subtables_per_byte_a;
|
||||||
|
if (cmp < 0) return -1;
|
||||||
|
if (cmp > 0) return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -80,15 +95,17 @@ bool _promote_extensions_if_needed (graph::make_extension_context_t& ext_context
|
||||||
// solution.
|
// solution.
|
||||||
if (!ext_context.lookups) return true;
|
if (!ext_context.lookups) return true;
|
||||||
|
|
||||||
hb_vector_t<hb_pair_t<unsigned, size_t>> lookup_sizes;
|
hb_vector_t<lookup_size_t> lookup_sizes;
|
||||||
lookup_sizes.alloc (ext_context.lookups.get_population ());
|
lookup_sizes.alloc (ext_context.lookups.get_population ());
|
||||||
|
|
||||||
for (unsigned lookup_index : ext_context.lookups.keys ())
|
for (unsigned lookup_index : ext_context.lookups.keys ())
|
||||||
{
|
{
|
||||||
|
const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
|
||||||
hb_set_t visited;
|
hb_set_t visited;
|
||||||
lookup_sizes.push (hb_pair_t<unsigned, size_t> {
|
lookup_sizes.push (lookup_size_t {
|
||||||
lookup_index,
|
lookup_index,
|
||||||
ext_context.graph.find_subgraph_size (lookup_index, visited)
|
ext_context.graph.find_subgraph_size (lookup_index, visited),
|
||||||
|
lookup->number_of_subtables (),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,8 +120,7 @@ bool _promote_extensions_if_needed (graph::make_extension_context_t& ext_context
|
||||||
// if it's decided to not make a lookup extension.
|
// if it's decided to not make a lookup extension.
|
||||||
for (auto p : lookup_sizes)
|
for (auto p : lookup_sizes)
|
||||||
{
|
{
|
||||||
unsigned lookup_index = p.first;
|
unsigned subtables_size = p.num_subtables * 8;
|
||||||
unsigned subtables_size = ext_context.lookups.get(lookup_index)->number_of_subtables () * 8;
|
|
||||||
l3_l4_size += subtables_size;
|
l3_l4_size += subtables_size;
|
||||||
l4_plus_size += subtables_size;
|
l4_plus_size += subtables_size;
|
||||||
}
|
}
|
||||||
|
@ -112,22 +128,21 @@ bool _promote_extensions_if_needed (graph::make_extension_context_t& ext_context
|
||||||
bool layers_full = false;
|
bool layers_full = false;
|
||||||
for (auto p : lookup_sizes)
|
for (auto p : lookup_sizes)
|
||||||
{
|
{
|
||||||
unsigned lookup_index = p.first;
|
const graph::Lookup* lookup = ext_context.lookups.get(p.lookup_index);
|
||||||
const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
|
|
||||||
if (lookup->is_extension (ext_context.table_tag))
|
if (lookup->is_extension (ext_context.table_tag))
|
||||||
// already an extension so size is counted by the loop above.
|
// already an extension so size is counted by the loop above.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!layers_full)
|
if (!layers_full)
|
||||||
{
|
{
|
||||||
size_t lookup_size = ext_context.graph.vertices_[lookup_index].table_size ();
|
size_t lookup_size = ext_context.graph.vertices_[p.lookup_index].table_size ();
|
||||||
hb_set_t visited;
|
hb_set_t visited;
|
||||||
size_t subtables_size = ext_context.graph.find_subgraph_size (lookup_index, visited, 1) - lookup_size;
|
size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size;
|
||||||
size_t remaining_size = p.second - subtables_size - lookup_size;
|
size_t remaining_size = p.size - subtables_size - lookup_size;
|
||||||
|
|
||||||
l2_l3_size += lookup_size;
|
l2_l3_size += lookup_size;
|
||||||
l3_l4_size += lookup_size + subtables_size;
|
l3_l4_size += lookup_size + subtables_size;
|
||||||
l3_l4_size -= lookup->number_of_subtables () * 8;
|
l3_l4_size -= p.num_subtables * 8;
|
||||||
l4_plus_size += subtables_size + remaining_size;
|
l4_plus_size += subtables_size + remaining_size;
|
||||||
|
|
||||||
if (l2_l3_size < (1 << 16)
|
if (l2_l3_size < (1 << 16)
|
||||||
|
@ -137,7 +152,7 @@ bool _promote_extensions_if_needed (graph::make_extension_context_t& ext_context
|
||||||
layers_full = true;
|
layers_full = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ext_context.lookups.get(lookup_index)->make_extension (ext_context, lookup_index))
|
if (!ext_context.lookups.get(p.lookup_index)->make_extension (ext_context, p.lookup_index))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1485,4 +1485,5 @@ main (int argc, char **argv)
|
||||||
test_resolve_with_extension_promotion ();
|
test_resolve_with_extension_promotion ();
|
||||||
// TODO(grieger): test with extensions already mixed in as well.
|
// TODO(grieger): test with extensions already mixed in as well.
|
||||||
// TODO(grieger): test two layer ext promotion setup.
|
// TODO(grieger): test two layer ext promotion setup.
|
||||||
|
// TODO(grieger): test sorting by subtables per byte in ext. promotion.
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue