Commit 747ae2c8aa3d8d3a5b731caf6aca9aae4ffb74fb

Behdad Esfahbod 2015-01-14T17:54:26

[smooth] Allocate render pool for smooth rasterizer on the stack. Instead of using the `render_pool' member of `FT_Library' that is provided down to the rasterizer, completely ignore that and allocate needed objects on the stack instead. With this patch, rasterizing glyphs from different faces from different threads doesn't crash in the smooth rasterizer. Bugs: https://bugzilla.redhat.com/show_bug.cgi?id=678397 https://bugzilla.redhat.com/show_bug.cgi?id=1004315 https://bugzilla.redhat.com/show_bug.cgi?id=1165471 https://bugs.freedesktop.org/show_bug.cgi?id=69034 * src/smooth/ftgrays.c (gray_TRaster): Remove `buffer', `buffer_size', `band_size', and `worker' members. (gray_raster_render): Create `buffer', `buffer_size', and `band_size' locally. (gray_raster_reset): Updated.

diff --git a/ChangeLog b/ChangeLog
index 5f34ee4..a85fbad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
 2015-01-14  Behdad Esfahbod  <behdad@behdad.org>
 
+	[smooth] Allocate render pool for smooth rasterizer on the stack.
+
+	Instead of using the `render_pool' member of `FT_Library' that is
+	provided down to the rasterizer, completely ignore that and allocate
+	needed objects on the stack instead.
+
+	With this patch, rasterizing glyphs from different faces from
+	different threads doesn't crash in the smooth rasterizer.
+
+	Bugs:
+
+	  https://bugzilla.redhat.com/show_bug.cgi?id=678397
+	  https://bugzilla.redhat.com/show_bug.cgi?id=1004315
+	  https://bugzilla.redhat.com/show_bug.cgi?id=1165471
+	  https://bugs.freedesktop.org/show_bug.cgi?id=69034
+
+	* src/smooth/ftgrays.c (gray_TRaster): Remove `buffer',
+	`buffer_size', `band_size', and `worker' members.
+
+	(gray_raster_render): Create `buffer', `buffer_size', and
+	`band_size' locally.
+	(gray_raster_reset): Updated.
+
+2015-01-14  Behdad Esfahbod  <behdad@behdad.org>
+
 	[truetype] Allocate TT_ExecContext in TT_Size instead of TT_Driver.
 
 	Previously the code had stipulation for using a per-TT_Size exec
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 131ad27..65eb64c 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -464,11 +464,7 @@ typedef ptrdiff_t  FT_PtrDist;
 
   typedef struct gray_TRaster_
   {
-    void*         buffer;
-    long          buffer_size;
-    int           band_size;
     void*         memory;
-    gray_PWorker  worker;
 
   } gray_TRaster, *gray_PRaster;
 
@@ -1918,12 +1914,17 @@ typedef ptrdiff_t  FT_PtrDist;
   gray_raster_render( gray_PRaster             raster,
                       const FT_Raster_Params*  params )
   {
-    const FT_Outline*  outline    = (const FT_Outline*)params->source;
-    const FT_Bitmap*   target_map = params->target;
-    gray_PWorker       worker;
+    const FT_Outline*  outline     = (const FT_Outline*)params->source;
+    const FT_Bitmap*   target_map  = params->target;
 
+    gray_TWorker  worker[1];
 
-    if ( !raster || !raster->buffer || !raster->buffer_size )
+    TCell  buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )];
+    long   buffer_size = sizeof ( buffer );
+    int    band_size   = (int)( buffer_size / ( sizeof ( TCell ) * 8 ) );
+
+
+    if ( !raster )
       return FT_THROW( Invalid_Argument );
 
     if ( !outline )
@@ -1940,8 +1941,6 @@ typedef ptrdiff_t  FT_PtrDist;
            outline->contours[outline->n_contours - 1] + 1 )
       return FT_THROW( Invalid_Outline );
 
-    worker = raster->worker;
-
     /* if direct mode is not set, we must have a target bitmap */
     if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
     {
@@ -1979,12 +1978,12 @@ typedef ptrdiff_t  FT_PtrDist;
       ras.clip_box.yMax =  32767L;
     }
 
-    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
+    gray_init_cells( RAS_VAR_ buffer, buffer_size );
 
     ras.outline        = *outline;
     ras.num_cells      = 0;
     ras.invalid        = 1;
-    ras.band_size      = raster->band_size;
+    ras.band_size      = band_size;
     ras.num_gray_spans = 0;
 
     if ( params->flags & FT_RASTER_FLAG_DIRECT )
@@ -2069,34 +2068,9 @@ typedef ptrdiff_t  FT_PtrDist;
                      char*      pool_base,
                      long       pool_size )
   {
-    gray_PRaster  rast = (gray_PRaster)raster;
-
-
-    if ( raster )
-    {
-      if ( pool_base && pool_size >= (long)sizeof ( gray_TWorker ) + 2048 )
-      {
-        gray_PWorker  worker = (gray_PWorker)pool_base;
-
-
-        rast->worker      = worker;
-        rast->buffer      = pool_base +
-                              ( ( sizeof ( gray_TWorker ) +
-                                  sizeof ( TCell ) - 1 )  &
-                                ~( sizeof ( TCell ) - 1 ) );
-        rast->buffer_size = (long)( ( pool_base + pool_size ) -
-                                    (char*)rast->buffer ) &
-                                      ~( sizeof ( TCell ) - 1 );
-        rast->band_size   = (int)( rast->buffer_size /
-                                     ( sizeof ( TCell ) * 8 ) );
-      }
-      else
-      {
-        rast->buffer      = NULL;
-        rast->buffer_size = 0;
-        rast->worker      = NULL;
-      }
-    }
+    FT_UNUSED( raster );
+    FT_UNUSED( pool_base );
+    FT_UNUSED( pool_size );
   }