Bug 1172239. Use nsChangeHint_UpdateComputedBSize to only dirty intrinsic sizes when necessary. r=bz

--HG--
extra : commitid : 48WN0ELkG8f
extra : rebase_source : 25524e9b82251263a88584d81b31f522a3ab5709
This commit is contained in:
Robert O'Callahan 2015-07-22 16:36:56 +12:00
Родитель 501665ec2f
Коммит 148e0aa769
4 изменённых файлов: 38 добавлений и 11 удалений

Просмотреть файл

@ -550,6 +550,17 @@ RestyleManager::RecomputePosition(nsIFrame* aFrame)
return false;
}
static bool
HasBoxAncestor(nsIFrame* aFrame)
{
for (nsIFrame* f = aFrame; f; f = f->GetParent()) {
if (f->IsBoxFrame()) {
return true;
}
}
return false;
}
void
RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
{
@ -557,9 +568,19 @@ RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
if (aHint & nsChangeHint_ClearDescendantIntrinsics) {
NS_ASSERTION(aHint & nsChangeHint_ClearAncestorIntrinsics,
"Please read the comments in nsChangeHint.h");
NS_ASSERTION(aHint & nsChangeHint_NeedDirtyReflow,
"ClearDescendantIntrinsics requires NeedDirtyReflow");
dirtyType = nsIPresShell::eStyleChange;
} else if ((aHint & nsChangeHint_UpdateComputedBSize) &&
aFrame->HasAnyStateBits(NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE)) {
dirtyType = nsIPresShell::eStyleChange;
} else if (aHint & nsChangeHint_ClearAncestorIntrinsics) {
dirtyType = nsIPresShell::eTreeChange;
} else if ((aHint & nsChangeHint_UpdateComputedBSize) &&
HasBoxAncestor(aFrame)) {
// The frame's computed BSize is changing, and we have a box ancestor
// whose cached intrinsic height may need to be updated.
dirtyType = nsIPresShell::eTreeChange;
} else {
dirtyType = nsIPresShell::eResize;
}
@ -567,7 +588,8 @@ RestyleManager::StyleChangeReflow(nsIFrame* aFrame, nsChangeHint aHint)
nsFrameState dirtyBits;
if (aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) {
dirtyBits = nsFrameState(0);
} else if (aHint & nsChangeHint_NeedDirtyReflow) {
} else if ((aHint & nsChangeHint_NeedDirtyReflow) ||
dirtyType == nsIPresShell::eStyleChange) {
dirtyBits = NS_FRAME_IS_DIRTY;
} else {
dirtyBits = NS_FRAME_HAS_DIRTY_CHILDREN;
@ -4245,7 +4267,7 @@ RestyleManager::ChangeHintToString(nsChangeHint aHint)
"ChildrenOnlyTransform", "RecomputePosition", "AddOrRemoveTransform",
"BorderStyleNoneChange", "UpdateTextPath", "SchedulePaint",
"NeutralChange", "InvalidateRenderingObservers",
"ReflowChangesSizeOrPosition"
"ReflowChangesSizeOrPosition", "UpdateComputedBSize"
};
uint32_t hint = aHint & ((1 << ArrayLength(names)) - 1);
uint32_t rest = aHint & ~((1 << ArrayLength(names)) - 1);

Просмотреть файл

@ -176,6 +176,11 @@ enum nsChangeHint {
*/
nsChangeHint_ReflowChangesSizeOrPosition = 0x800000,
/**
* Indicates that the style changes the computed BSize --- e.g. 'height'.
*/
nsChangeHint_UpdateComputedBSize = 0x1000000,
// IMPORTANT NOTE: When adding new hints, consider whether you need to
// add them to NS_HintsNotHandledForDescendantsIn() below. Please also
// add them to RestyleManager::ChangeHintToString.
@ -283,7 +288,8 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight)
nsChangeHint_BorderStyleNoneChange | \
nsChangeHint_NeedReflow | \
nsChangeHint_ReflowChangesSizeOrPosition | \
nsChangeHint_ClearAncestorIntrinsics)
nsChangeHint_ClearAncestorIntrinsics | \
nsChangeHint_UpdateComputedBSize)
inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) {
nsChangeHint result = nsChangeHint(aChangeHint & (
@ -297,7 +303,8 @@ inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint)
nsChangeHint_ChildrenOnlyTransform |
nsChangeHint_RecomputePosition |
nsChangeHint_AddOrRemoveTransform |
nsChangeHint_BorderStyleNoneChange));
nsChangeHint_BorderStyleNoneChange |
nsChangeHint_UpdateComputedBSize));
if (!NS_IsHintSubset(nsChangeHint_NeedDirtyReflow, aChangeHint)) {
if (NS_IsHintSubset(nsChangeHint_NeedReflow, aChangeHint)) {

Просмотреть файл

@ -1598,13 +1598,10 @@ nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) cons
mMaxHeight != aOther.mMaxHeight) {
// Height changes can affect descendant intrinsic sizes due to replaced
// elements with percentage heights in descendants which also have
// percentage heights. And due to our not-so-great computation of mVResize
// in nsHTMLReflowState, they do need to force reflow of the whole subtree.
// XXXbz due to XUL caching heights as well, height changes also need to
// clear ancestor intrinsics!
// percentage heights. This is handled via nsChangeHint_UpdateComputedBSize
// which clears intrinsic sizes for frames that have such replaced elements.
return NS_CombineHint(hint, nsChangeHint_NeedReflow |
nsChangeHint_ClearAncestorIntrinsics |
nsChangeHint_ClearDescendantIntrinsics |
nsChangeHint_UpdateComputedBSize |
nsChangeHint_ReflowChangesSizeOrPosition);
}

Просмотреть файл

@ -1355,7 +1355,8 @@ struct nsStylePosition {
static nsChangeHint MaxDifference() {
return NS_CombineHint(NS_STYLE_HINT_REFLOW,
nsChangeHint(nsChangeHint_RecomputePosition |
nsChangeHint_UpdateParentOverflow));
nsChangeHint_UpdateParentOverflow |
nsChangeHint_UpdateComputedBSize));
}
static nsChangeHint DifferenceAlwaysHandledForDescendants() {
// CalcDifference can return all of the reflow hints that are