[gxvar] Cache shared-tuple scalar values.

GoogleSansFlex HB benchmark-font draw results:

  Before:  2.13ms
  After:   1.65ms
  Speedup: 22%

* src/truetype/ttgxvar.h (GX_BlendRec): Add `tuplescalars` field.

* src/truetype/ttgxvar.c (ft_var_load_gvar): Allocate `tuplescalars` array.
  (tt_set_mm_blend): Set its values.
  (TT_Vary_Apply_Glyph_Deltas): Use it.
  (tt_done_blend): Deallocate it.
This commit is contained in:
Behdad Esfahbod (بهداد اسفهبد) 2025-05-21 01:34:08 -06:00 committed by Werner Lemberg
parent 582de1a4b6
commit d7b6e947a3
2 changed files with 39 additions and 3 deletions

View file

@ -1831,6 +1831,10 @@
FT_TRACE5(( "]\n" ));
}
if ( FT_NEW_ARRAY( blend->tuplescalars,
gvar_head.globalCoordCount ) )
goto Fail2;
blend->tuplecount = gvar_head.globalCoordCount;
FT_TRACE5(( "\n" ));
@ -2951,6 +2955,9 @@
}
}
for ( i = 0 ; i < blend->tuplecount ; i++ )
blend->tuplescalars[i] = (FT_Fixed)-0x20000L;
Exit:
return error;
}
@ -4192,13 +4199,16 @@
tupleCount &= GX_TC_TUPLE_COUNT_MASK;
for ( i = 0; i < tupleCount; i++ )
{
FT_UInt tupleDataSize;
FT_UInt tupleIndex;
FT_Fixed apply;
FT_UInt tupleDataSize;
FT_UInt tupleIndex;
FT_Fixed apply;
FT_Fixed* tupleScalars;
FT_TRACE6(( " tuple %d:\n", i ));
tupleScalars = blend->tuplescalars;
/* Enter frame for four bytes. */
if ( stream->limit - stream->cursor < 4 )
{
@ -4214,11 +4224,24 @@
{
for ( j = 0; j < blend->num_axis; j++ )
peak_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
tuple_coords = peak_coords;
tupleScalars = NULL;
}
else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) < blend->tuplecount )
{
FT_Fixed scalar = tupleScalars[tupleIndex & GX_TI_TUPLE_INDEX_MASK];
if ( scalar != (FT_Fixed)-0x20000 )
{
apply = scalar;
goto apply_found;
}
tuple_coords = blend->tuplecoords +
( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) * blend->num_axis;
}
else
{
FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
@ -4234,6 +4257,8 @@
im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
for ( j = 0; j < blend->num_axis; j++ )
im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() );
tupleScalars = NULL;
}
apply = ft_var_apply_tuple( blend,
@ -4242,6 +4267,11 @@
im_start_coords,
im_end_coords );
if ( tupleScalars )
tupleScalars[tupleIndex & GX_TI_TUPLE_INDEX_MASK] = apply;
apply_found:
if ( apply == 0 ) /* tuple isn't active for our blend */
{
offsetToData += tupleDataSize;
@ -4624,6 +4654,7 @@
FT_FREE( blend->mvar_table );
}
FT_FREE( blend->tuplescalars );
FT_FREE( blend->tuplecoords );
FT_FREE( blend->glyphoffsets );
FT_FREE( blend );

View file

@ -255,6 +255,10 @@ FT_BEGIN_HEADER
* A two-dimensional array that holds the shared tuple coordinates
* in the `gvar' table.
*
* tuplescalars ::
* A one-dimensional array that holds the shared tuple
* scalars in the `gvar' table for current face coordinates.
*
* gv_glyphcnt ::
* The number of glyphs handled in the `gvar' table.
*
@ -293,6 +297,7 @@ FT_BEGIN_HEADER
FT_UInt tuplecount;
FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */
FT_Fixed* tuplescalars; /* tuplescalars[tuplecount] */
FT_UInt gv_glyphcnt;
FT_ULong* glyphoffsets; /* glyphoffsets[gv_glyphcnt + 1] */