зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1203766 - Part 6: Cache resolved style contexts on nsComputedDOMStyle to avoid re-resolving if styles haven't changed. r=bzbarsky
This commit is contained in:
Родитель
88572918f6
Коммит
c6d52eae0d
|
@ -222,7 +222,9 @@ nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
|
|||
: mDocumentWeak(nullptr), mOuterFrame(nullptr),
|
||||
mInnerFrame(nullptr), mPresShell(nullptr),
|
||||
mStyleType(aStyleType),
|
||||
mExposeVisitedStyle(false)
|
||||
mStyleContextGeneration(0),
|
||||
mExposeVisitedStyle(false),
|
||||
mResolvedStyleContext(false)
|
||||
{
|
||||
MOZ_ASSERT(aElement && aPresShell);
|
||||
|
||||
|
@ -572,10 +574,10 @@ nsComputedDOMStyle::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv
|
|||
void
|
||||
nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
||||
{
|
||||
MOZ_ASSERT(!mStyleContext);
|
||||
|
||||
nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
|
||||
if (!document) {
|
||||
mResolvedStyleContext = false;
|
||||
mStyleContext = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -593,9 +595,24 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
|||
|
||||
mPresShell = document->GetShell();
|
||||
if (!mPresShell || !mPresShell->GetPresContext()) {
|
||||
mResolvedStyleContext = false;
|
||||
mStyleContext = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t currentGeneration =
|
||||
mPresShell->GetPresContext()->GetRestyleGeneration();
|
||||
|
||||
if (mStyleContext) {
|
||||
if (mStyleContextGeneration == currentGeneration) {
|
||||
// Our cached style context is still valid.
|
||||
return;
|
||||
}
|
||||
// We've processed some restyles, so the cached style context might
|
||||
// be out of date.
|
||||
mStyleContext = nullptr;
|
||||
}
|
||||
|
||||
// XXX the !mContent->IsHTMLElement(nsGkAtoms::area)
|
||||
// check is needed due to bug 135040 (to avoid using
|
||||
// mPrimaryFrame). Remove it once that's fixed.
|
||||
|
@ -616,6 +633,7 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
|||
}
|
||||
|
||||
mStyleContext = mInnerFrame->StyleContext();
|
||||
mResolvedStyleContext = false;
|
||||
NS_ASSERTION(mStyleContext, "Frame without style context?");
|
||||
}
|
||||
}
|
||||
|
@ -649,9 +667,19 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
|||
mPresShell,
|
||||
mStyleType);
|
||||
if (!mStyleContext) {
|
||||
mResolvedStyleContext = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to re-get the generation, even though GetStyleContextForElement
|
||||
// will flush, since we flushed style at the top of this function.
|
||||
NS_ASSERTION(mPresShell &&
|
||||
currentGeneration ==
|
||||
mPresShell->GetPresContext()->GetRestyleGeneration(),
|
||||
"why should we have flushed style again?");
|
||||
|
||||
mResolvedStyleContext = true;
|
||||
mStyleContextGeneration = currentGeneration;
|
||||
NS_ASSERTION(mPseudo || !mStyleContext->HasPseudoElementData(),
|
||||
"should not have pseudo-element data");
|
||||
}
|
||||
|
@ -675,9 +703,12 @@ nsComputedDOMStyle::ClearCurrentStyleSources()
|
|||
mInnerFrame = nullptr;
|
||||
mPresShell = nullptr;
|
||||
|
||||
// Release the current style context for it should be re-resolved
|
||||
// whenever a frame is not available.
|
||||
// Release the current style context if we got it off the frame.
|
||||
// For a style context we resolved, keep it around so that we
|
||||
// can re-use it next time this object is queried.
|
||||
if (!mResolvedStyleContext) {
|
||||
mStyleContext = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<CSSValue>
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#define nsComputedDOMStyle_h__
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/ArenaRefPtr.h"
|
||||
#include "mozilla/ArenaRefPtrInlines.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nscore.h"
|
||||
|
@ -595,12 +597,23 @@ private:
|
|||
nsWeakPtr mDocumentWeak;
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
|
||||
/*
|
||||
* Strong reference to the style context while we're accessing the data from
|
||||
* it. This can be either a style context we resolved ourselves or a style
|
||||
* context we got from our frame.
|
||||
/**
|
||||
* Strong reference to the style context we access data from. This can be
|
||||
* either a style context we resolved ourselves or a style context we got
|
||||
* from our frame.
|
||||
*
|
||||
* If we got the style context from the frame, we clear out mStyleContext
|
||||
* in ClearCurrentStyleSources. If we resolved one ourselves, then
|
||||
* ClearCurrentStyleSources leaves it in mStyleContext for use the next
|
||||
* time this nsComputedDOMStyle object is queried. UpdateCurrentStyleSources
|
||||
* in this case will check that the style context is still valid to be used,
|
||||
* by checking whether flush styles results in any restyles having been
|
||||
* processed.
|
||||
*
|
||||
* Since an ArenaRefPtr is used to hold the style context, it will be cleared
|
||||
* if the pres arena from which it was allocated goes away.
|
||||
*/
|
||||
nsRefPtr<nsStyleContext> mStyleContext;
|
||||
mozilla::ArenaRefPtr<nsStyleContext> mStyleContext;
|
||||
nsCOMPtr<nsIAtom> mPseudo;
|
||||
|
||||
/*
|
||||
|
@ -626,8 +639,20 @@ private:
|
|||
*/
|
||||
StyleType mStyleType;
|
||||
|
||||
/**
|
||||
* The nsComputedDOMStyle generation at the time we last resolved a style
|
||||
* context and stored it in mStyleContext.
|
||||
*/
|
||||
uint64_t mStyleContextGeneration;
|
||||
|
||||
bool mExposeVisitedStyle;
|
||||
|
||||
/**
|
||||
* Whether we resolved a style context last time we called
|
||||
* UpdateCurrentStyleSources. Initially false.
|
||||
*/
|
||||
bool mResolvedStyleContext;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mFlushedPendingReflows;
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче