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
This commit is contained in:
Nicholas Nethercote 2014-12-18 21:23:30 -08:00
parent ce369b69d7
commit 25ea2bc436

View File

@ -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<ScaledFontMac*>(aFont);
//XXX: we should use a stack vector here when we have a class like that
std::vector<CGGlyph> glyphs;
std::vector<CGPoint> 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<CGGlyph, 64> glyphs;
Vector<CGPoint, 64> 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);
}
}