зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
501665ec2f
Коммит
148e0aa769
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче