Bug 1474883 - Ensure D2D glyph cache is pruned after rendering 1000 transformed glyphs. r=bas

Rendering glyphs at many different rotations was causing the D2D glyph
cache to grow very large. Calling EndDraw/BeginDraw will prune the
cache, but is costly, so only do it for every 1000 glyphs.

MozReview-Commit-ID: HUFpxDvYAzQ

--HG--
extra : rebase_source : de283c5e687da07e5417e0d221d7f45b992080d5
This commit is contained in:
Jamie Nicol 2018-07-26 15:23:19 +01:00
parent 78157f60ff
commit 35e92591dd
2 changed files with 12 additions and 1 deletions

View File

@ -48,6 +48,7 @@ DrawTargetD2D1::DrawTargetD2D1()
: mPushedLayers(1)
, mSnapshotLock(make_shared<Mutex>("DrawTargetD2D1::mSnapshotLock"))
, mUsedCommandListsSincePurge(0)
, mTransformedGlyphsSinceLastPurge(0)
, mComplexBlendsWithListInList(0)
, mDeviceSeq(0)
{
@ -164,6 +165,9 @@ DrawTargetD2D1::IntoLuminanceSource(LuminanceType aLuminanceType, float aOpacity
// are expensive though, especially relatively when little work is done, so
// we try to reduce the amount of times we execute these purges.
static const uint32_t kPushedLayersBeforePurge = 25;
// Rendering glyphs with different transforms causes the glyph cache to grow
// very large (see bug 1474883) so we must call EndDraw every so often.
static const uint32_t kTransformedGlyphsBeforePurge = 1000;
void
DrawTargetD2D1::Flush()
@ -730,6 +734,10 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont,
mDC->DrawGlyphRun(D2D1::Point2F(), &autoRun, brush);
}
if (mTransform.HasNonTranslation()) {
mTransformedGlyphsSinceLastPurge += aBuffer.mNumGlyphs;
}
if (needsRepushedLayers) {
PopClipsFromDC(mDC);
@ -1285,7 +1293,8 @@ void
DrawTargetD2D1::FlushInternal(bool aHasDependencyMutex /* = false */)
{
if (IsDeviceContextValid()) {
if ((mUsedCommandListsSincePurge >= kPushedLayersBeforePurge) &&
if ((mUsedCommandListsSincePurge >= kPushedLayersBeforePurge ||
mTransformedGlyphsSinceLastPurge >= kTransformedGlyphsBeforePurge) &&
mPushedLayers.size() == 1) {
// It's important to pop all clips as otherwise layers can forget about
// their clip when doing an EndDraw. When we have layers pushed we cannot
@ -1293,6 +1302,7 @@ DrawTargetD2D1::FlushInternal(bool aHasDependencyMutex /* = false */)
// layers pushed.
PopAllClips();
mUsedCommandListsSincePurge = 0;
mTransformedGlyphsSinceLastPurge = 0;
mDC->EndDraw();
mDC->BeginDraw();
}

View File

@ -289,6 +289,7 @@ private:
TargetSet mDependingOnTargets;
uint32_t mUsedCommandListsSincePurge;
uint32_t mTransformedGlyphsSinceLastPurge;
// When a BlendEffect has been drawn to a command list, and that command list is
// subsequently used -again- as an input to a blend effect for a command list,
// this causes an infinite recursion inside D2D as it tries to resolve the bounds.