Don't create hb_apply_context_t per glyph!

I couldn't measure significant performance gains out of this; maybe
about 5% (with one million Malayalam strings).  Still, not bad.
But reminds me that optimizing this codebase without profiling first
is simply not going to work.  Oh well...
This commit is contained in:
Behdad Esfahbod 2012-04-11 17:11:05 -04:00
parent 4a1e02ef79
commit 41ae674f68
3 changed files with 35 additions and 37 deletions

View File

@ -1404,23 +1404,9 @@ struct PosLookup : Lookup
inline const PosLookupSubTable& get_subtable (unsigned int i) const inline const PosLookupSubTable& get_subtable (unsigned int i) const
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
inline bool apply_once (hb_font_t *font, inline bool apply_once (hb_apply_context_t *c) const
hb_buffer_t *buffer,
hb_mask_t lookup_mask,
unsigned int context_length,
unsigned int nesting_level_left) const
{ {
unsigned int lookup_type = get_type (); unsigned int lookup_type = get_type ();
hb_apply_context_t c[1] = {{0}};
c->font = font;
c->face = font->face;
c->buffer = buffer;
c->direction = buffer->props.direction;
c->lookup_mask = lookup_mask;
c->context_length = context_length;
c->nesting_level_left = nesting_level_left;
c->lookup_props = get_props ();
if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer->idx], c->lookup_props, &c->property)) if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer->idx], c->lookup_props, &c->property))
return false; return false;
@ -1441,11 +1427,12 @@ struct PosLookup : Lookup
if (unlikely (!buffer->len)) if (unlikely (!buffer->len))
return false; return false;
hb_apply_context_t c (font, font->face, buffer, mask, *this);
buffer->idx = 0; buffer->idx = 0;
while (buffer->idx < buffer->len) while (buffer->idx < buffer->len)
{ {
if ((buffer->info[buffer->idx].mask & mask) && if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
apply_once (font, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
ret = true; ret = true;
else else
buffer->idx++; buffer->idx++;
@ -1598,7 +1585,8 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
if (unlikely (c->context_length < 1)) if (unlikely (c->context_length < 1))
return false; return false;
return l.apply_once (c->font, c->buffer, c->lookup_mask, c->context_length, c->nesting_level_left - 1); hb_apply_context_t new_c (*c, l);
return l.apply_once (&new_c);
} }

View File

@ -754,22 +754,9 @@ struct SubstLookup : Lookup
} }
inline bool apply_once (hb_face_t *face, inline bool apply_once (hb_apply_context_t *c) const
hb_buffer_t *buffer,
hb_mask_t lookup_mask,
unsigned int context_length,
unsigned int nesting_level_left) const
{ {
unsigned int lookup_type = get_type (); unsigned int lookup_type = get_type ();
hb_apply_context_t c[1] = {{0}};
c->face = face;
c->buffer = buffer;
c->direction = buffer->props.direction;
c->lookup_mask = lookup_mask;
c->context_length = context_length;
c->nesting_level_left = nesting_level_left;
c->lookup_props = get_props ();
if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer->idx], c->lookup_props, &c->property)) if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->info[c->buffer->idx], c->lookup_props, &c->property))
return false; return false;
@ -805,6 +792,8 @@ struct SubstLookup : Lookup
if (unlikely (!buffer->len)) if (unlikely (!buffer->len))
return false; return false;
hb_apply_context_t c (NULL, face, buffer, mask, *this);
if (likely (!is_reverse ())) if (likely (!is_reverse ()))
{ {
/* in/out forward substitution */ /* in/out forward substitution */
@ -812,8 +801,7 @@ struct SubstLookup : Lookup
buffer->idx = 0; buffer->idx = 0;
while (buffer->idx < buffer->len) while (buffer->idx < buffer->len)
{ {
if ((buffer->info[buffer->idx].mask & mask) && if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
apply_once (face, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
ret = true; ret = true;
else else
buffer->next_glyph (); buffer->next_glyph ();
@ -828,8 +816,7 @@ struct SubstLookup : Lookup
buffer->idx = buffer->len - 1; buffer->idx = buffer->len - 1;
do do
{ {
if ((buffer->info[buffer->idx].mask & mask) && if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
apply_once (face, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
ret = true; ret = true;
else else
buffer->idx--; buffer->idx--;
@ -936,7 +923,8 @@ static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup
if (unlikely (c->context_length < 1)) if (unlikely (c->context_length < 1))
return false; return false;
return l.apply_once (c->face, c->buffer, c->lookup_mask, c->context_length, c->nesting_level_left - 1); hb_apply_context_t new_c (*c, l);
return l.apply_once (&new_c);
} }

View File

@ -67,6 +67,28 @@ struct hb_apply_context_t
unsigned int lookup_props; unsigned int lookup_props;
unsigned int property; /* propety of first glyph */ unsigned int property; /* propety of first glyph */
hb_apply_context_t (hb_font_t *font_,
hb_face_t *face_,
hb_buffer_t *buffer_,
hb_mask_t lookup_mask_,
const Lookup &l,
unsigned int context_length_ = NO_CONTEXT,
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
font (font_), face (face_), buffer (buffer_),
direction (buffer_->props.direction),
lookup_mask (lookup_mask_),
context_length (context_length_),
nesting_level_left (nesting_level_left_),
lookup_props (l.get_props ()),
property (0) {}
hb_apply_context_t (const hb_apply_context_t &c, const Lookup &l) {
*this = c;
nesting_level_left--;
lookup_props = l.get_props ();
}
struct mark_skipping_forward_iterator_t struct mark_skipping_forward_iterator_t
{ {
inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_,