From 25ea2bc436829ff14b6f2fc14b3db6c816313d50 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Dec 2014 21:23:30 -0800 Subject: [PATCH] Bug 1113037 - Use stack allocation in DrawTargetCG::FillGlyphs() in the common case. r=mattwoodrow. When viewing about:memory in verbose mode this reduces the number of heap allocations by over 10%. --HG-- extra : rebase_source : 954962295dcd90d66d0e02f782998884de879f17 --- gfx/2d/DrawTargetCG.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/gfx/2d/DrawTargetCG.cpp b/gfx/2d/DrawTargetCG.cpp index d0e4ba404e7..761f28eb43b 100644 --- a/gfx/2d/DrawTargetCG.cpp +++ b/gfx/2d/DrawTargetCG.cpp @@ -2,6 +2,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + #include "BorrowedContext.h" #include "DataSurfaceHelpers.h" #include "DrawTargetCG.h" @@ -15,8 +16,9 @@ #include "MacIOSurface.h" #include "FilterNodeSoftware.h" #include "mozilla/Assertions.h" -#include "mozilla/Types.h" // for decltype #include "mozilla/FloatingPoint.h" +#include "mozilla/Types.h" // for decltype +#include "mozilla/Vector.h" using namespace std; @@ -1343,11 +1345,16 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa ScaledFontMac* macFont = static_cast(aFont); - //XXX: we should use a stack vector here when we have a class like that - std::vector glyphs; - std::vector positions; - glyphs.resize(aBuffer.mNumGlyphs); - positions.resize(aBuffer.mNumGlyphs); + // 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 64 elements, which is enough to typically avoid heap + // allocation in ~99% of cases. + Vector glyphs; + Vector positions; + if (!glyphs.resizeUninitialized(aBuffer.mNumGlyphs) || + !positions.resizeUninitialized(aBuffer.mNumGlyphs)) { + MOZ_CRASH("glyphs/positions allocation failed"); + } // Handle the flip CGContextScaleCTM(cg, 1, -1); @@ -1370,19 +1377,19 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) { CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs]; CTFontGetBoundingRectsForGlyphs(macFont->mCTFont, kCTFontDefaultOrientation, - &glyphs.front(), bboxes, aBuffer.mNumGlyphs); - extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, 1.0f); - ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(), - &positions.front(), aBuffer.mNumGlyphs, cg); + glyphs.begin(), bboxes, aBuffer.mNumGlyphs); + extents = ComputeGlyphsExtents(bboxes, positions.begin(), aBuffer.mNumGlyphs, 1.0f); + ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, glyphs.begin(), + positions.begin(), aBuffer.mNumGlyphs, cg); delete[] bboxes; } else { CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs]; - CGFontGetGlyphBBoxes(macFont->mFont, &glyphs.front(), aBuffer.mNumGlyphs, bboxes); - extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, macFont->mSize); + CGFontGetGlyphBBoxes(macFont->mFont, glyphs.begin(), aBuffer.mNumGlyphs, bboxes); + extents = ComputeGlyphsExtents(bboxes, positions.begin(), aBuffer.mNumGlyphs, macFont->mSize); CGContextSetFont(cg, macFont->mFont); CGContextSetFontSize(cg, macFont->mSize); - CGContextShowGlyphsAtPositions(cg, &glyphs.front(), &positions.front(), + CGContextShowGlyphsAtPositions(cg, glyphs.begin(), positions.begin(), aBuffer.mNumGlyphs); delete[] bboxes; } @@ -1394,13 +1401,13 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa CGContextSetTextDrawingMode(cg, kCGTextFill); SetFillFromPattern(cg, mColorSpace, aPattern); if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) { - ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(), - &positions.front(), + ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, glyphs.begin(), + positions.begin(), aBuffer.mNumGlyphs, cg); } else { CGContextSetFont(cg, macFont->mFont); CGContextSetFontSize(cg, macFont->mSize); - CGContextShowGlyphsAtPositions(cg, &glyphs.front(), &positions.front(), + CGContextShowGlyphsAtPositions(cg, glyphs.begin(), positions.begin(), aBuffer.mNumGlyphs); } }