[autofit] Add embedded array of segments and edges.

Avoids multiple mallocs per typical glyphs.

With this and recent changes to avoid mallocs, the thread-safe
stack-based loader is now as fast as the previous model that had one
cached singleton.

* src/autofit/afhints.h (AF_SEGMENTS_EMBEDDED, AF_EDGES_EMBEDDED):
New macros.
(AF_AxisHintsRec): Add two arrays for segments and edges.

* src/autofit/afhints.c (af_axis_hints_new_segment): Only allocate
data if number of segments exceeds given threshold value.
(af_axis_hints_new_edge):  Only allocate data if number of edges
exceeds given threshold value.
(af_glyph_hints_done): Updated.
This commit is contained in:
Behdad Esfahbod 2015-01-14 19:36:02 +01:00 committed by Werner Lemberg
parent 6f16b10019
commit 56ddafa01c
3 changed files with 76 additions and 8 deletions

View File

@ -1,3 +1,23 @@
2015-01-14 Behdad Esfahbod <behdad@behdad.org>
[autofit] Add embedded array of segments and edges.
Avoids multiple mallocs per typical glyphs.
With this and recent changes to avoid mallocs, the thread-safe
stack-based loader is now as fast as the previous model that had one
cached singleton.
* src/autofit/afhints.h (AF_SEGMENTS_EMBEDDED, AF_EDGES_EMBEDDED):
New macros.
(AF_AxisHintsRec): Add two arrays for segments and edges.
* src/autofit/afhints.c (af_axis_hints_new_segment): Only allocate
data if number of segments exceeds given threshold value.
(af_axis_hints_new_edge): Only allocate data if number of edges
exceeds given threshold value.
(af_glyph_hints_done): Updated.
2015-01-14 Behdad Esfahbod <behdad@behdad.org>
[autofit] Add embedded arrays for points and contours.

View File

@ -43,7 +43,15 @@
AF_Segment segment = NULL;
if ( axis->num_segments >= axis->max_segments )
if ( axis->num_segments < AF_SEGMENTS_EMBEDDED )
{
if ( axis->segments == NULL )
{
axis->segments = axis->embedded.segments;
axis->max_segments = AF_SEGMENTS_EMBEDDED;
}
}
else if ( axis->num_segments >= axis->max_segments )
{
FT_Int old_max = axis->max_segments;
FT_Int new_max = old_max;
@ -60,8 +68,18 @@
if ( new_max < old_max || new_max > big_max )
new_max = big_max;
if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
goto Exit;
if ( axis->segments == axis->embedded.segments )
{
if ( FT_NEW_ARRAY( axis->segments, new_max ) )
goto Exit;
ft_memcpy( axis->segments, axis->embedded.segments,
sizeof ( axis->embedded.segments ) );
}
else
{
if ( FT_RENEW_ARRAY( axis->segments, old_max, new_max ) )
goto Exit;
}
axis->max_segments = new_max;
}
@ -89,7 +107,15 @@
AF_Edge edges;
if ( axis->num_edges >= axis->max_edges )
if ( axis->num_edges < AF_EDGES_EMBEDDED )
{
if ( axis->edges == NULL )
{
axis->edges = axis->embedded.edges;
axis->max_edges = AF_EDGES_EMBEDDED;
}
}
else if ( axis->num_edges >= axis->max_edges )
{
FT_Int old_max = axis->max_edges;
FT_Int new_max = old_max;
@ -106,8 +132,18 @@
if ( new_max < old_max || new_max > big_max )
new_max = big_max;
if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
goto Exit;
if ( axis->edges == axis->embedded.edges )
{
if ( FT_NEW_ARRAY( axis->edges, new_max ) )
goto Exit;
ft_memcpy( axis->edges, axis->embedded.edges,
sizeof ( axis->embedded.edges ) );
}
else
{
if ( FT_RENEW_ARRAY( axis->edges, old_max, new_max ) )
goto Exit;
}
axis->max_edges = new_max;
}
@ -515,11 +551,13 @@
axis->num_segments = 0;
axis->max_segments = 0;
FT_FREE( axis->segments );
if ( axis->segments != axis->embedded.segments )
FT_FREE( axis->segments );
axis->num_edges = 0;
axis->max_edges = 0;
FT_FREE( axis->edges );
if ( axis->edges != axis->embedded.edges )
FT_FREE( axis->edges );
}
if ( hints->contours != hints->embedded.contours )

View File

@ -305,6 +305,8 @@ FT_BEGIN_HEADER
} AF_EdgeRec;
#define AF_SEGMENTS_EMBEDDED 18 /* number of embedded segments */
#define AF_EDGES_EMBEDDED 12 /* number of embedded edges */
typedef struct AF_AxisHintsRec_
{
@ -321,6 +323,14 @@ FT_BEGIN_HEADER
AF_Direction major_dir; /* either vertical or horizontal */
/* two arrays to avoid allocation penalty */
struct
{
AF_SegmentRec segments[AF_SEGMENTS_EMBEDDED];
AF_EdgeRec edges[AF_EDGES_EMBEDDED];
} embedded;
} AF_AxisHintsRec, *AF_AxisHints;