Allocate initial array of RegionInfo on the stack.
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 21 Nov 2008 01:20:38 +0000 (01:20 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 20 Dec 2008 16:55:09 +0000 (16:55 +0000)
The region validate() code is frequently called by cairo as it is used to
extract regions from the trapezoids for fast-paths through the drawing
code and also for fast-path clipping and the RegionInfo allocation (as
well as the pixman_rect_alloc during the final union) appears as a hot
spot on application memory profiles.

pixman/pixman-region.c

index 3718d65..01a28be 100644 (file)
@@ -1330,6 +1330,8 @@ validate (region_type_t * badreg,
        int         curBand;
     } RegionInfo;
 
+    RegionInfo stack_regions[64];
+
             int        numRects;   /* Original numRects for badreg         */
             RegionInfo *ri;        /* Array of current regions             */
             int        numRI;      /* Number of entries used in ri         */
@@ -1379,10 +1381,8 @@ validate (region_type_t * badreg,
 
     /* Set up the first region to be the first rectangle in badreg */
     /* Note that step 2 code will never overflow the ri[0].reg rects array */
-    ri = (RegionInfo *) pixman_malloc_ab (4, sizeof(RegionInfo));
-    if (!ri)
-       return pixman_break (badreg);
-    sizeRI = 4;
+    ri = stack_regions;
+    sizeRI = sizeof (stack_regions) / sizeof (stack_regions[0]);
     numRI = 1;
     ri[0].prevBand = 0;
     ri[0].curBand = 0;
@@ -1451,9 +1451,16 @@ validate (region_type_t * badreg,
             data_size = sizeRI * sizeof(RegionInfo);
             if (data_size / sizeRI != sizeof(RegionInfo))
                 goto bail;
-            rit = (RegionInfo *) realloc(ri, data_size);
-           if (!rit)
-               goto bail;
+           if (ri == stack_regions) {
+               rit = malloc (data_size);
+               if (!rit)
+                   goto bail;
+               memcpy (rit, ri, numRI * sizeof (RegionInfo));
+           } else {
+               rit = (RegionInfo *) realloc(ri, data_size);
+               if (!rit)
+                   goto bail;
+           }
            ri = rit;
            rit = &ri[numRI];
        }
@@ -1509,13 +1516,15 @@ NextRect: ;
            goto bail;
     }
     *badreg = ri[0].reg;
-    free(ri);
+    if (ri != stack_regions)
+       free(ri);
     good(badreg);
     return ret;
 bail:
     for (i = 0; i < numRI; i++)
        freeData(&ri[i].reg);
-    free (ri);
+    if (ri != stack_regions)
+       free (ri);
 
     return pixman_break (badreg);
 }