Bug 1113037 - Use stack allocation in DrawTargetCairo::FillGlyphs() in the common case. r=mattwoodrow.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 18 Dec 2014 21:23:28 -0800
changeset 220567 0f5e9c234a1c28918a6de27102e4fef41392628a
parent 220566 2c91a808c506c5ada7e92bf3ec52c6fbf0b361ea
child 220568 58f4ba516bbabad3d7a24c7c6aa307001604db94
push id10503
push userryanvm@gmail.com
push dateFri, 19 Dec 2014 20:13:42 +0000
treeherderfx-team@98ee95ac6be5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1113037
milestone37.0a1
Bug 1113037 - Use stack allocation in DrawTargetCairo::FillGlyphs() in the common case. r=mattwoodrow.
gfx/2d/DrawTargetCairo.cpp
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -7,16 +7,17 @@
 
 #include "SourceSurfaceCairo.h"
 #include "PathCairo.h"
 #include "HelpersCairo.h"
 #include "ScaledFontBase.h"
 #include "BorrowedContext.h"
 #include "FilterNodeSoftware.h"
 #include "mozilla/Scoped.h"
+#include "mozilla/Vector.h"
 
 #include "cairo.h"
 #include "cairo-tee.h"
 #include <string.h>
 
 #include "Blur.h"
 #include "Logging.h"
 #include "Tools.h"
@@ -1143,18 +1144,26 @@ DrawTargetCairo::FillGlyphs(ScaledFont *
   if (!pat)
     return;
 
   cairo_set_source(mContext, pat);
   cairo_pattern_destroy(pat);
 
   cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode));
 
-  // Convert our GlyphBuffer into an array of Cairo glyphs.
-  std::vector<cairo_glyph_t> glyphs(aBuffer.mNumGlyphs);
+  // Convert our GlyphBuffer into a vector of Cairo glyphs. This code can
+  // execute millions of times in short periods, so we want to avoid heap
+  // allocation whenever possible. So we use an inline vector capacity of 1024
+  // bytes (the maximum allowed by mozilla::Vector), which gives an inline
+  // length of 1024 / 24 = 42 elements, which is enough to typically avoid heap
+  // allocation in ~99% of cases.
+  Vector<cairo_glyph_t, 1024 / sizeof(cairo_glyph_t)> glyphs;
+  if (!glyphs.resizeUninitialized(aBuffer.mNumGlyphs)) {
+    MOZ_CRASH("glyphs allocation failed");
+  }
   for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) {
     glyphs[i].index = aBuffer.mGlyphs[i].mIndex;
     glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x;
     glyphs[i].y = aBuffer.mGlyphs[i].mPosition.y;
   }
 
   cairo_show_glyphs(mContext, &glyphs[0], aBuffer.mNumGlyphs);
 }