Bug 1563133 - limit GlyphBuffer capacity. r=jfkthame a=abillings
authorLee Salzman <lsalzman@mozilla.com>
Thu, 18 Jul 2019 21:44:57 +0000
changeset 544641 b5b868d520a2ee6043adaddffb893bae932c24b3
parent 544640 37409ab4ab9074431017ad70866a57d55ecbae61
child 544642 7aee03d62b0ce63de493cdcfb0d8ae5cc672b170
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame, abillings
bugs1563133
milestone69.0
Bug 1563133 - limit GlyphBuffer capacity. r=jfkthame a=abillings Differential Revision: https://phabricator.services.mozilla.com/D38214
gfx/thebes/gfxFont.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1569,44 +1569,53 @@ class GlyphBufferAzure {
       FlushGlyphs();
     }
 
     if (mBuffer != *mAutoBuffer.addr()) {
       free(mBuffer);
     }
   }
 
-  // Ensure the buffer has enough space for aGlyphCount glyphs to be added.
+  // Ensure the buffer has enough space for aGlyphCount glyphs to be added,
+  // considering the supplied strike multipler aStrikeCount.
   // This MUST be called before OutputGlyph is used to actually store glyph
   // records in the buffer. It may be called repeated to add further capacity
   // in case we don't know up-front exactly what will be needed.
-  void AddCapacity(uint32_t aGlyphCount) {
+  void AddCapacity(uint32_t aGlyphCount, uint32_t aStrikeCount) {
+    // Calculate the new capacity and ensure it will fit within the maximum
+    // allowed capacity.
+    static const uint64_t kMaxCapacity = 64 * 1024;
+    mCapacity = uint32_t(std::min(
+        kMaxCapacity,
+        uint64_t(mCapacity) + uint64_t(aGlyphCount) * uint64_t(aStrikeCount)));
     // See if the required capacity fits within the already-allocated space
-    if (mCapacity + aGlyphCount <= mBufSize) {
-      mCapacity += aGlyphCount;
+    if (mCapacity <= mBufSize) {
       return;
     }
     // We need to grow the buffer: determine a new size, allocate, and
     // copy the existing data over if we didn't use realloc (which would
     // do it automatically).
-    mBufSize = std::max(mCapacity + aGlyphCount, mBufSize * 2);
+    mBufSize = std::max(mCapacity, mBufSize * 2);
     if (mBuffer == *mAutoBuffer.addr()) {
       // switching from autobuffer to malloc, so we need to copy
       mBuffer = reinterpret_cast<Glyph*>(moz_xmalloc(mBufSize * sizeof(Glyph)));
       std::memcpy(mBuffer, *mAutoBuffer.addr(), mNumGlyphs * sizeof(Glyph));
     } else {
       mBuffer = reinterpret_cast<Glyph*>(
           moz_xrealloc(mBuffer, mBufSize * sizeof(Glyph)));
     }
-    mCapacity += aGlyphCount;
   }
 
   void OutputGlyph(uint32_t aGlyphID, const gfx::Point& aPt) {
-    // Check that AddCapacity has been used appropriately!
-    MOZ_ASSERT(mNumGlyphs < mCapacity);
+    // If the buffer is full, flush to make room for the new glyph.
+    if (mNumGlyphs >= mCapacity) {
+      // Check that AddCapacity has been used appropriately!
+      MOZ_ASSERT(mCapacity > 0 && mNumGlyphs == mCapacity);
+      Flush();
+    }
     Glyph* glyph = mBuffer + mNumGlyphs++;
     glyph->mIndex = aGlyphID;
     glyph->mPosition = aPt;
   }
 
   void Flush() {
     if (mNumGlyphs > 0) {
       FlushGlyphs();
@@ -1804,17 +1813,17 @@ bool gfxFont::DrawGlyphs(const gfxShaped
   if (S == SpacingT::HasSpacing) {
     float space = aBuffer.mRunParams.spacing[0].mBefore *
                   aBuffer.mFontParams.advanceDirection;
     inlineCoord += space;
   }
 
   // Allocate buffer space for the run, assuming all simple glyphs.
   uint32_t capacityMult = 1 + aBuffer.mFontParams.extraStrikes;
-  aBuffer.AddCapacity(capacityMult * aCount);
+  aBuffer.AddCapacity(aCount, capacityMult);
 
   bool emittedGlyphs = false;
 
   for (uint32_t i = 0; i < aCount; ++i, ++glyphData) {
     if (glyphData->IsSimpleGlyph()) {
       float advance =
           glyphData->GetSimpleAdvance() * aBuffer.mFontParams.advanceDirection;
       if (aBuffer.mRunParams.isRTL) {
@@ -1824,17 +1833,17 @@ bool gfxFont::DrawGlyphs(const gfxShaped
                        &emittedGlyphs);
       if (!aBuffer.mRunParams.isRTL) {
         inlineCoord += advance;
       }
     } else {
       uint32_t glyphCount = glyphData->GetGlyphCount();
       if (glyphCount > 0) {
         // Add extra buffer capacity to allow for multiple-glyph entry.
-        aBuffer.AddCapacity(capacityMult * (glyphCount - 1));
+        aBuffer.AddCapacity(glyphCount - 1, capacityMult);
         const gfxShapedText::DetailedGlyph* details =
             aShapedText->GetDetailedGlyphs(aOffset + i);
         MOZ_ASSERT(details, "missing DetailedGlyph!");
         for (uint32_t j = 0; j < glyphCount; ++j, ++details) {
           float advance =
               details->mAdvance * aBuffer.mFontParams.advanceDirection;
           if (aBuffer.mRunParams.isRTL) {
             inlineCoord += advance;