mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-05 21:45:06 +00:00
[COLR] Reduce malloc pressure
By caching paint-extents.
This commit is contained in:
parent
9efd17e225
commit
e9134c8ce3
3 changed files with 79 additions and 14 deletions
|
@ -47,6 +47,11 @@ namespace OT {
|
|||
struct hb_paint_context_t;
|
||||
}
|
||||
|
||||
struct hb_colr_scratch_t
|
||||
{
|
||||
hb_paint_extents_context_t paint_extents;
|
||||
};
|
||||
|
||||
namespace OT {
|
||||
|
||||
struct COLR;
|
||||
|
@ -2079,6 +2084,8 @@ struct COLR
|
|||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
|
||||
|
||||
bool has_data () const { return has_v0_data () || version; }
|
||||
|
||||
bool has_v0_data () const { return numBaseGlyphs; }
|
||||
bool has_v1_data () const
|
||||
{
|
||||
|
@ -2115,13 +2122,21 @@ struct COLR
|
|||
|
||||
~accelerator_t () { this->colr.destroy (); }
|
||||
|
||||
bool has_data () const { return colr->has_data (); }
|
||||
|
||||
#ifndef HB_NO_PAINT
|
||||
bool
|
||||
get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents) const
|
||||
{
|
||||
return colr->get_extents (font, glyph, extents);
|
||||
if (unlikely (!has_data ())) return false;
|
||||
|
||||
hb_colr_scratch_t *scratch = acquire_scratch ();
|
||||
if (unlikely (!scratch)) return true;
|
||||
bool ret = colr->get_extents (font, glyph, extents, *scratch);
|
||||
release_scratch (scratch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool paint_glyph (hb_font_t *font,
|
||||
|
@ -2131,7 +2146,13 @@ struct COLR
|
|||
hb_color_t foreground,
|
||||
bool clip = true) const
|
||||
{
|
||||
return colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip);
|
||||
if (unlikely (!has_data ())) return false;
|
||||
|
||||
hb_colr_scratch_t *scratch = acquire_scratch ();
|
||||
if (unlikely (!scratch)) return true;
|
||||
bool ret = colr->paint_glyph (font, glyph, funcs, data, palette_index, foreground, clip, *scratch);
|
||||
release_scratch (scratch);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2168,8 +2189,34 @@ struct COLR
|
|||
const DeltaSetIndexMap *get_delta_set_index_map_ptr () const
|
||||
{ return colr->get_delta_set_index_map_ptr (); }
|
||||
|
||||
private:
|
||||
|
||||
hb_colr_scratch_t *acquire_scratch () const
|
||||
{
|
||||
hb_colr_scratch_t *scratch = cached_scratch.get_acquire ();
|
||||
|
||||
if (!scratch || unlikely (!cached_scratch.cmpexch (scratch, nullptr)))
|
||||
{
|
||||
scratch = (hb_colr_scratch_t *) hb_calloc (1, sizeof (hb_colr_scratch_t));
|
||||
if (unlikely (!scratch))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return scratch;
|
||||
}
|
||||
void release_scratch (hb_colr_scratch_t *scratch) const
|
||||
{
|
||||
if (!cached_scratch.cmpexch (nullptr, scratch))
|
||||
{
|
||||
scratch->~hb_colr_scratch_t ();
|
||||
hb_free (scratch);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
hb_blob_ptr_t<COLR> colr;
|
||||
private:
|
||||
hb_atomic_ptr_t<hb_colr_scratch_t> cached_scratch;
|
||||
};
|
||||
|
||||
void closure_glyphs (hb_codepoint_t glyph,
|
||||
|
@ -2541,7 +2588,10 @@ struct COLR
|
|||
|
||||
#ifndef HB_NO_PAINT
|
||||
bool
|
||||
get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
|
||||
get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
hb_colr_scratch_t &scratch) const
|
||||
{
|
||||
|
||||
ItemVarStoreInstancer instancer (get_var_store_ptr (),
|
||||
|
@ -2555,10 +2605,10 @@ struct COLR
|
|||
}
|
||||
|
||||
auto *extents_funcs = hb_paint_extents_get_funcs ();
|
||||
hb_paint_extents_context_t extents_data;
|
||||
bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
|
||||
scratch.paint_extents.clear ();
|
||||
bool ret = paint_glyph (font, glyph, extents_funcs, &scratch.paint_extents, 0, HB_COLOR(0,0,0,0), true, scratch);
|
||||
|
||||
hb_extents_t e = extents_data.get_extents ();
|
||||
auto e = scratch.paint_extents.get_extents ();
|
||||
if (e.is_void ())
|
||||
{
|
||||
extents->x_bearing = 0;
|
||||
|
@ -2604,7 +2654,12 @@ struct COLR
|
|||
|
||||
#ifndef HB_NO_PAINT
|
||||
bool
|
||||
paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
|
||||
paint_glyph (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_paint_funcs_t *funcs, void *data,
|
||||
unsigned int palette_index, hb_color_t foreground,
|
||||
bool clip,
|
||||
hb_colr_scratch_t &scratch) const
|
||||
{
|
||||
ItemVarStoreInstancer instancer (get_var_store_ptr (),
|
||||
get_delta_set_index_map_ptr (),
|
||||
|
@ -2639,15 +2694,16 @@ struct COLR
|
|||
else
|
||||
{
|
||||
auto *extents_funcs = hb_paint_extents_get_funcs ();
|
||||
hb_paint_extents_context_t extents_data;
|
||||
scratch.paint_extents.clear ();
|
||||
|
||||
paint_glyph (font, glyph,
|
||||
extents_funcs, &extents_data,
|
||||
extents_funcs, &scratch.paint_extents,
|
||||
palette_index, foreground,
|
||||
false);
|
||||
false,
|
||||
scratch);
|
||||
|
||||
hb_extents_t extents = extents_data.get_extents ();
|
||||
is_bounded = extents_data.is_bounded ();
|
||||
auto extents = scratch.paint_extents.get_extents ();
|
||||
is_bounded = scratch.paint_extents.is_bounded ();
|
||||
|
||||
c.funcs->push_clip_rectangle (c.data,
|
||||
extents.xmin,
|
||||
|
|
|
@ -243,7 +243,7 @@ struct hb_bounds_t
|
|||
EMPTY,
|
||||
};
|
||||
|
||||
hb_bounds_t (status_t status) : status (status) {}
|
||||
hb_bounds_t (status_t status = UNBOUNDED) : status (status) {}
|
||||
hb_bounds_t (const hb_extents_t &extents) :
|
||||
status (extents.is_empty () ? EMPTY : BOUNDED), extents (extents) {}
|
||||
|
||||
|
|
|
@ -35,13 +35,22 @@ typedef struct hb_paint_extents_context_t hb_paint_extents_context_t;
|
|||
|
||||
struct hb_paint_extents_context_t
|
||||
{
|
||||
hb_paint_extents_context_t ()
|
||||
void clear ()
|
||||
{
|
||||
transforms.clear ();
|
||||
clips.clear ();
|
||||
groups.clear ();
|
||||
|
||||
transforms.push (hb_transform_t{});
|
||||
clips.push (hb_bounds_t{hb_bounds_t::UNBOUNDED});
|
||||
groups.push (hb_bounds_t{hb_bounds_t::EMPTY});
|
||||
}
|
||||
|
||||
hb_paint_extents_context_t ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
hb_extents_t get_extents ()
|
||||
{
|
||||
return groups.tail().extents;
|
||||
|
|
Loading…
Add table
Reference in a new issue