Bug 812776. Reset InlineBackgroundData whenever there are no display lists extant. Frame trees can't change while there are display lists extant. r=mattwoodrow

This commit is contained in:
Robert O'Callahan 2012-11-19 23:54:41 +13:00
parent 28b9f823ec
commit e8a5527e77
3 changed files with 28 additions and 6 deletions

View File

@ -55,6 +55,8 @@
using namespace mozilla;
using namespace mozilla::css;
static int gFrameTreeLockCount = 0;
// To avoid storing this data on nsInlineFrame (bloat) and to avoid
// recalculating this for each frame in a continuation (perf), hold
// a cache of various coordinate information that we need in order
@ -162,6 +164,8 @@ protected:
void SetFrame(nsIFrame* aFrame)
{
NS_PRECONDITION(aFrame, "Need a frame");
NS_ASSERTION(gFrameTreeLockCount > 0,
"Can't call this when frame tree is not locked");
if (aFrame == mFrame) {
return;
@ -1149,9 +1153,19 @@ nsCSSRendering::FindBackground(nsPresContext* aPresContext,
}
void
nsCSSRendering::DidPaint()
nsCSSRendering::BeginFrameTreesLocked()
{
gInlineBGData->Reset();
++gFrameTreeLockCount;
}
void
nsCSSRendering::EndFrameTreesLocked()
{
NS_ASSERTION(gFrameTreeLockCount > 0, "Unbalanced EndFrameTreeLocked");
--gFrameTreeLockCount;
if (gFrameTreeLockCount == 0) {
gInlineBGData->Reset();
}
}
void

View File

@ -393,10 +393,16 @@ struct nsCSSRendering {
const nsStyleBackground::Layer& aLayer);
/**
* Called by the presShell when painting is finished, so we can clear our
* inline background data cache.
* Called when we start creating a display list. The frame tree will not
* change until a matching EndFrameTreeLocked is called.
*/
static void DidPaint();
static void BeginFrameTreesLocked();
/**
* Called when we've finished using a display list. When all
* BeginFrameTreeLocked calls have been balanced by an EndFrameTreeLocked,
* the frame tree may start changing again.
*/
static void EndFrameTreesLocked();
// Draw a border segment in the table collapsing border model without
// beveling corners

View File

@ -472,6 +472,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
}
}
nsCSSRendering::BeginFrameTreesLocked();
PR_STATIC_ASSERT(nsDisplayItem::TYPE_MAX < (1 << nsDisplayItem::TYPE_BITS));
}
@ -654,6 +655,8 @@ nsDisplayListBuilder::~nsDisplayListBuilder() {
"All presshells should have been exited");
NS_ASSERTION(!mCurrentTableItem, "No table item should be active");
nsCSSRendering::EndFrameTreesLocked();
PL_FreeArenaPool(&mPool);
PL_FinishArenaPool(&mPool);
MOZ_COUNT_DTOR(nsDisplayListBuilder);
@ -1155,7 +1158,6 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
FrameLayerBuilder::InvalidateAllLayers(layerManager);
}
nsCSSRendering::DidPaint();
layerManager->SetUserData(&gLayerManagerLayerBuilder, oldBuilder);
}