Bug 1344386 - Don't look for overlapping change hints in stylo documents. r=emilio

MozReview-Commit-ID: 9wK8TTXolPM
This commit is contained in:
Bobby Holley 2017-03-03 14:42:51 -08:00
parent 9913356b39
commit 09bc17720b
7 changed files with 44 additions and 10 deletions

View File

@ -3472,7 +3472,7 @@ GeckoRestyleManager::ComputeAndProcessStyleChange(
const RestyleHintData& aRestyleHintData)
{
MOZ_ASSERT(mReframingStyleContexts, "should have rsc");
nsStyleChangeList changeList;
nsStyleChangeList changeList(StyleBackendType::Gecko);
nsTArray<ElementRestyler::ContextToClear> contextsToClear;
// swappedStructOwners needs to be kept alive until after
@ -3517,7 +3517,7 @@ GeckoRestyleManager::ComputeAndProcessStyleChange(
// ProcessRestyledFrames and ClearCachedInheritedStyleDataOnDescendants
// calls; see comment in ElementRestyler::Restyle.
nsTArray<RefPtr<nsStyleContext>> swappedStructOwners;
nsStyleChangeList changeList;
nsStyleChangeList changeList(StyleBackendType::Gecko);
ElementRestyler r(frame->PresContext(), aElement, &changeList, aMinChange,
aRestyleTracker, selectorsForDescendants, treeMatchContext,
visibleKidsOfHiddenElement, contextsToClear,

View File

@ -2943,7 +2943,7 @@ PresShell::RecreateFramesFor(nsIContent* aContent)
nsAutoScriptBlocker scriptBlocker;
nsStyleChangeList changeList;
nsStyleChangeList changeList(mPresContext->StyleSet()->BackendType());
changeList.AppendChange(nullptr, aContent, nsChangeHint_ReconstructFrame);
// Mark ourselves as not safe to flush while we're doing frame construction.
@ -9585,7 +9585,7 @@ PresShell::Observe(nsISupports* aSubject,
// Because "chrome:" URL equality is messy, reframe image box
// frames (hack!).
nsStyleChangeList changeList;
nsStyleChangeList changeList(mPresContext->StyleSet()->BackendType());
WalkFramesThroughPlaceholders(mPresContext, rootFrame,
ReframeImageBoxes, &changeList);
// Mark ourselves as not safe to flush while we're doing frame

View File

@ -98,7 +98,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
(primaryFrame ||
(aChangeHint & nsChangeHint_ReconstructFrame))) {
// Don't need to recompute style; just apply the hint
nsStyleChangeList changeList;
nsStyleChangeList changeList(StyleBackendType::Gecko);
changeList.AppendChange(primaryFrame, aElement, aChangeHint);
mRestyleManager->ProcessRestyledFrames(changeList);
}

View File

@ -387,7 +387,7 @@ ServoRestyleManager::ProcessPendingRestyles()
// Recreate style contexts, and queue up change hints (which also handle
// lazy frame construction).
nsStyleChangeList currentChanges;
nsStyleChangeList currentChanges(StyleBackendType::Servo);
DocumentStyleRootIterator iter(doc);
while (Element* root = iter.GetNextStyleRoot()) {
ProcessPostTraversal(root, nullptr, styleSet, currentChanges);

View File

@ -41,9 +41,17 @@ nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChange
(aHint & nsChangeHint_NeedReflow),
"Reflow hint bits set without actually asking for a reflow");
// Filter out all other changes for same content
if (!IsEmpty() && (aHint & nsChangeHint_ReconstructFrame)) {
if (aContent) {
// If Servo fires reconstruct at a node, it is the only change hint fired at
// that node.
if (IsServo()) {
for (size_t i = 0; i < Length(); ++i) {
MOZ_ASSERT_IF(aContent && ((aHint | (*this)[i].mHint) & nsChangeHint_ReconstructFrame),
(*this)[i].mContent != aContent);
}
} else {
// Filter out all other changes for same content for Gecko (Servo asserts against this
// case above).
if (aContent && (aHint & nsChangeHint_ReconstructFrame)) {
// NOTE: This is captured by reference to please static analysis.
// Capturing it by value as a pointer should be fine in this case.
RemoveElementsBy([&](const nsStyleChangeData& aData) {

View File

@ -12,6 +12,7 @@
#define nsStyleChangeList_h___
#include "mozilla/Attributes.h"
#include "mozilla/StyleBackendType.h"
#include "nsChangeHint.h"
#include "nsCOMPtr.h"
@ -39,9 +40,29 @@ public:
using base_type::Length;
using base_type::operator[];
nsStyleChangeList() { MOZ_COUNT_CTOR(nsStyleChangeList); }
nsStyleChangeList(mozilla::StyleBackendType aType) :
mType(aType) { MOZ_COUNT_CTOR(nsStyleChangeList); }
~nsStyleChangeList() { MOZ_COUNT_DTOR(nsStyleChangeList); }
void AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint);
// Starting from the end of the list, removes all changes until the list is
// empty or an element with |mContent != aContent| is found.
void PopChangesForContent(nsIContent* aContent)
{
while (Length() > 0) {
if (LastElement().mContent == aContent) {
RemoveElementAt(Length() - 1);
} else {
break;
}
}
}
bool IsGecko() const { return mType == mozilla::StyleBackendType::Gecko; }
bool IsServo() const { return mType == mozilla::StyleBackendType::Servo; }
private:
mozilla::StyleBackendType mType;
};
#endif /* nsStyleChangeList_h___ */

View File

@ -10087,6 +10087,11 @@ nsFrame::UpdateStyleOfChildAnonBox(nsIFrame* aChildFrame,
&equalStructs,
&samePointerStructs);
if (childHint) {
if (childHint & nsChangeHint_ReconstructFrame) {
// If we generate a reconstruct here, remove any non-reconstruct hints we
// may have already generated for this content.
aChangeList.PopChangesForContent(aChildFrame->GetContent());
}
aChangeList.AppendChange(aChildFrame, aChildFrame->GetContent(), childHint);
}