From 89bc8d4de7bf93336e182bd42507851f5b46f66f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 14 Jan 2015 16:01:19 +0100 Subject: [PATCH] [autofit] Allocate AF_Loader on the stack instead of AF_Module. Stop sharing a global `AF_Loader'. Allocate one on the stack during glyph load. Right now this results in about 25% slowdown, to be fixed in a following commit. With this patch loading glyphs from different faces from different threads doesn't immediately crash in the autohinting loader code. Bugs: https://bugzilla.redhat.com/show_bug.cgi?id=1164941 * src/autofit/afloader.c (af_loader_init): Pass `AF_Loader' and `FT_Memory' instead of `AF_Module' as arguments. (af_loader_reset, af_loader_load_glyph): Also pass `loader' as argument. (af_loader_done): Use `AF_Loader' instead of `AF_Module' as argument. * src/autofit/afmodule.c (af_autofitter_init): Don't call `af_loader_init'. (af_autofitter_done): Don't call `af_loader_done'. (af_autofitter_load_glyph): Use a local `AF_Loader' object. * src/autofit/afloader.h: Include `afmodule.h'. Update prototypes. Move typedef for `AF_Module' to... * src/autofit/afmodule.h: ... this place. No longer include `afloader.h'. --- ChangeLog | 36 ++++++++++++++++++++++++++++++++++++ src/autofit/afloader.c | 24 +++++++++--------------- src/autofit/afloader.h | 14 ++++++++------ src/autofit/afmodule.c | 21 +++++++++++++++------ src/autofit/afmodule.h | 10 ++-------- 5 files changed, 70 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9de08bb98..bc8c72561 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,39 @@ +2015-01-14 Behdad Esfahbod + + [autofit] Allocate AF_Loader on the stack instead of AF_Module. + + Stop sharing a global `AF_Loader'. Allocate one on the stack during + glyph load. + + Right now this results in about 25% slowdown, to be fixed in a + following commit. + + With this patch loading glyphs from different faces from different + threads doesn't immediately crash in the autohinting loader code. + + Bugs: + + https://bugzilla.redhat.com/show_bug.cgi?id=1164941 + + * src/autofit/afloader.c (af_loader_init): Pass + `AF_Loader' and `FT_Memory' instead of `AF_Module' as arguments. + (af_loader_reset, af_loader_load_glyph): Also pass `loader' as + argument. + (af_loader_done): Use `AF_Loader' instead of `AF_Module' as + argument. + + * src/autofit/afmodule.c (af_autofitter_init): Don't call + `af_loader_init'. + (af_autofitter_done): Don't call `af_loader_done'. + (af_autofitter_load_glyph): Use a local `AF_Loader' object. + + * src/autofit/afloader.h: Include `afmodule.h'. + Update prototypes. + Move typedef for `AF_Module' to... + + * src/autofit/afmodule.h: ... this place. + No longer include `afloader.h'. + 2015-01-14 Behdad Esfahbod * src/type42/t42objs.h (T42_DriverRec): Remove unused member. diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c index fb15c87f0..612103cdb 100644 --- a/src/autofit/afloader.c +++ b/src/autofit/afloader.c @@ -27,12 +27,9 @@ /* Initialize glyph loader. */ FT_LOCAL_DEF( FT_Error ) - af_loader_init( AF_Module module ) + af_loader_init( AF_Loader loader, + FT_Memory memory ) { - AF_Loader loader = module->loader; - FT_Memory memory = module->root.library->memory; - - FT_ZERO( loader ); af_glyph_hints_init( &loader->hints, memory ); @@ -46,11 +43,11 @@ /* Reset glyph loader and compute globals if necessary. */ FT_LOCAL_DEF( FT_Error ) - af_loader_reset( AF_Module module, + af_loader_reset( AF_Loader loader, + AF_Module module, FT_Face face ) { - FT_Error error = FT_Err_Ok; - AF_Loader loader = module->loader; + FT_Error error = FT_Err_Ok; loader->face = face; @@ -77,11 +74,8 @@ /* Finalize glyph loader. */ FT_LOCAL_DEF( void ) - af_loader_done( AF_Module module ) + af_loader_done( AF_Loader loader ) { - AF_Loader loader = module->loader; - - af_glyph_hints_done( &loader->hints ); loader->face = NULL; @@ -496,14 +490,14 @@ /* Load a glyph. */ FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Module module, + af_loader_load_glyph( AF_Loader loader, + AF_Module module, FT_Face face, FT_UInt gindex, FT_Int32 load_flags ) { FT_Error error; FT_Size size = face->size; - AF_Loader loader = module->loader; AF_ScalerRec scaler; @@ -521,7 +515,7 @@ scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); scaler.flags = 0; /* XXX: fix this */ - error = af_loader_reset( module, face ); + error = af_loader_reset( loader, module, face ); if ( !error ) { AF_StyleMetrics metrics; diff --git a/src/autofit/afloader.h b/src/autofit/afloader.h index 9601e24fc..5987b278f 100644 --- a/src/autofit/afloader.h +++ b/src/autofit/afloader.h @@ -20,13 +20,12 @@ #define __AFLOADER_H__ #include "afhints.h" +#include "afmodule.h" #include "afglobal.h" FT_BEGIN_HEADER - typedef struct AF_ModuleRec_* AF_Module; - /* * The autofitter module's (global) data structure to communicate with * actual fonts. If necessary, `local' data like the current face, the @@ -56,20 +55,23 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - af_loader_init( AF_Module module ); + af_loader_init( AF_Loader loader, + FT_Memory memory ); FT_LOCAL( FT_Error ) - af_loader_reset( AF_Module module, + af_loader_reset( AF_Loader loader, + AF_Module module, FT_Face face ); FT_LOCAL( void ) - af_loader_done( AF_Module module ); + af_loader_done( AF_Loader loader ); FT_LOCAL( FT_Error ) - af_loader_load_glyph( AF_Module module, + af_loader_load_glyph( AF_Loader loader, + AF_Module module, FT_Face face, FT_UInt gindex, FT_Int32 load_flags ); diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 641e03ea2..77e484941 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -253,7 +253,7 @@ module->fallback_style = AF_STYLE_FALLBACK; module->default_script = AF_SCRIPT_DEFAULT; - return af_loader_init( module ); + return FT_Err_Ok; } @@ -261,9 +261,6 @@ af_autofitter_done( FT_Module ft_module ) /* AF_Module */ { AF_Module module = (AF_Module)ft_module; - - - af_loader_done( module ); } @@ -274,10 +271,22 @@ FT_UInt glyph_index, FT_Int32 load_flags ) { + FT_Error error = FT_Err_Ok; + AF_LoaderRec loader[1]; + FT_UNUSED( size ); - return af_loader_load_glyph( module, slot->face, - glyph_index, load_flags ); + + error = af_loader_init( loader, module->root.library->memory ); + if ( error ) + return error; + + error = af_loader_load_glyph( loader, module, slot->face, + glyph_index, load_flags ); + + af_loader_done( loader ); + + return error; } diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h index 20b7b9f66..4f73d1d53 100644 --- a/src/autofit/afmodule.h +++ b/src/autofit/afmodule.h @@ -23,17 +23,13 @@ #include FT_INTERNAL_OBJECTS_H #include FT_MODULE_H -#include "afloader.h" - FT_BEGIN_HEADER /* * This is the `extended' FT_Module structure which holds the - * autofitter's global data. Right before hinting a glyph, the data - * specific to the glyph's face (blue zones, stem widths, etc.) are - * loaded into `loader' (see function `af_loader_reset'). + * autofitter's global data. */ typedef struct AF_ModuleRec_ @@ -43,9 +39,7 @@ FT_BEGIN_HEADER FT_UInt fallback_style; FT_UInt default_script; - AF_LoaderRec loader[1]; - - } AF_ModuleRec; + } AF_ModuleRec, *AF_Module; FT_DECLARE_MODULE(autofit_module_class)