Huw Davies : gdi32: Reduce the number of memory allocations required for gdi paths.

Alexandre Julliard julliard at winehq.org
Fri Jul 15 09:07:05 CDT 2016


Module: wine
Branch: master
Commit: da8834609a8b5e2d9aab1e7d843f5b311c9bc171
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=da8834609a8b5e2d9aab1e7d843f5b311c9bc171

Author: Huw Davies <huw at codeweavers.com>
Date:   Thu Jul 14 14:28:14 2016 +0100

gdi32: Reduce the number of memory allocations required for gdi paths.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/gdi32/path.c | 62 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 41 insertions(+), 21 deletions(-)

diff --git a/dlls/gdi32/path.c b/dlls/gdi32/path.c
index 2ee113e..558bcf7 100644
--- a/dlls/gdi32/path.c
+++ b/dlls/gdi32/path.c
@@ -89,6 +89,8 @@ struct gdi_path
     int          allocated;
     BOOL         newStroke;
     POINT        pos;         /* current cursor position */
+    POINT        points_buf[NUM_ENTRIES_INITIAL];
+    BYTE         flags_buf[NUM_ENTRIES_INITIAL];
 };
 
 struct path_physdev
@@ -104,8 +106,8 @@ static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
 
 void free_gdi_path( struct gdi_path *path )
 {
-    HeapFree( GetProcessHeap(), 0, path->points );
-    HeapFree( GetProcessHeap(), 0, path->flags );
+    if (path->points != path->points_buf)
+        HeapFree( GetProcessHeap(), 0, path->points );
     HeapFree( GetProcessHeap(), 0, path );
 }
 
@@ -119,13 +121,22 @@ static struct gdi_path *alloc_gdi_path( int count )
         return NULL;
     }
     count = max( NUM_ENTRIES_INITIAL, count );
-    path->points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*path->points) );
-    path->flags = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*path->flags) );
-    if (!path->points || !path->flags)
+    if (count > NUM_ENTRIES_INITIAL)
     {
-        free_gdi_path( path );
-        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
-        return NULL;
+        path->points = HeapAlloc( GetProcessHeap(), 0,
+                                  count * (sizeof(path->points[0]) + sizeof(path->flags[0])) );
+        if (!path->points)
+        {
+            HeapFree( GetProcessHeap(), 0, path );
+            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+            return NULL;
+        }
+        path->flags = (BYTE *)(path->points + count);
+    }
+    else
+    {
+        path->points = path->points_buf;
+        path->flags = path->flags_buf;
     }
     path->count = 0;
     path->allocated = count;
@@ -179,30 +190,39 @@ static inline INT int_from_fixed(FIXED f)
  * been allocated; allocates larger arrays and copies the existing entries
  * to those arrays, if necessary. Returns TRUE if successful, else FALSE.
  */
-static BOOL PATH_ReserveEntries(struct gdi_path *pPath, INT count)
+static BOOL PATH_ReserveEntries(struct gdi_path *path, INT count)
 {
-    POINT *pPointsNew;
-    BYTE    *pFlagsNew;
+    POINT *pts_new;
+    int size;
 
     assert(count>=0);
 
     /* Do we have to allocate more memory? */
-    if(count > pPath->allocated)
+    if (count > path->allocated)
     {
         /* Find number of entries to allocate. We let the size of the array
          * grow exponentially, since that will guarantee linear time
          * complexity. */
-        count = max( pPath->allocated * 2, count );
-
-        pPointsNew = HeapReAlloc( GetProcessHeap(), 0, pPath->points, count * sizeof(POINT) );
-        if (!pPointsNew) return FALSE;
-        pPath->points = pPointsNew;
+        count = max( path->allocated * 2, count );
+        size = count * (sizeof(path->points[0]) + sizeof(path->flags[0]));
 
-        pFlagsNew = HeapReAlloc( GetProcessHeap(), 0, pPath->flags, count * sizeof(BYTE) );
-        if (!pFlagsNew) return FALSE;
-        pPath->flags = pFlagsNew;
+        if (path->points == path->points_buf)
+        {
+            pts_new = HeapAlloc( GetProcessHeap(), 0, size );
+            if (!pts_new) return FALSE;
+            memcpy( pts_new, path->points, path->count * sizeof(path->points[0]) );
+            memcpy( pts_new + count, path->flags, path->count * sizeof(path->flags[0]) );
+        }
+        else
+        {
+            pts_new = HeapReAlloc( GetProcessHeap(), 0, path->points, size );
+            if (!pts_new) return FALSE;
+            memmove( pts_new + count, pts_new + path->allocated, path->count * sizeof(path->flags[0]) );
+        }
 
-        pPath->allocated = count;
+        path->points = pts_new;
+        path->flags = (BYTE *)(pts_new + count);
+        path->allocated = count;
     }
     return TRUE;
 }




More information about the wine-cvs mailing list