Bug 913444. Track restyling of margins and treat such nodes as active scrolled roots. r=mattwoodrow

Restyling margin-top and margin-bottom will typically require reflow and cause
sibling elements to be moved and invalidated, so it's not a big win to layerize
such nodes. However, layerizing them should be relatively harmless.

--HG--
extra : rebase_source : 659593b6b6990aa859144641eb23e7ccf384a82a
This commit is contained in:
Robert O'Callahan 2013-09-09 17:08:42 -07:00
parent e8504f01a9
commit 68cb18ba63
5 changed files with 29 additions and 8 deletions

View File

@ -29,6 +29,14 @@ public:
: mFrame(aFrame)
, mOpacityRestyleCount(0)
, mTransformRestyleCount(0)
, mLeftRestyleCount(0)
, mTopRestyleCount(0)
, mRightRestyleCount(0)
, mBottomRestyleCount(0)
, mMarginLeftRestyleCount(0)
, mMarginTopRestyleCount(0)
, mMarginRightRestyleCount(0)
, mMarginBottomRestyleCount(0)
, mContentActive(false)
{}
~LayerActivity();
@ -42,6 +50,10 @@ public:
case eCSSProperty_top: return mTopRestyleCount;
case eCSSProperty_right: return mRightRestyleCount;
case eCSSProperty_bottom: return mBottomRestyleCount;
case eCSSProperty_margin_left: return mMarginLeftRestyleCount;
case eCSSProperty_margin_top: return mMarginTopRestyleCount;
case eCSSProperty_margin_right: return mMarginRightRestyleCount;
case eCSSProperty_margin_bottom: return mMarginBottomRestyleCount;
default: MOZ_ASSERT(false); return mOpacityRestyleCount;
}
}
@ -55,6 +67,10 @@ public:
uint8_t mTopRestyleCount;
uint8_t mRightRestyleCount;
uint8_t mBottomRestyleCount;
uint8_t mMarginLeftRestyleCount;
uint8_t mMarginTopRestyleCount;
uint8_t mMarginRightRestyleCount;
uint8_t mMarginBottomRestyleCount;
bool mContentActive;
};
@ -203,14 +219,18 @@ ActiveLayerTracker::IsStyleAnimated(nsIFrame* aFrame, nsCSSProperty aProperty)
}
/* static */ bool
ActiveLayerTracker::IsOffsetStyleAnimated(nsIFrame* aFrame)
ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(nsIFrame* aFrame)
{
LayerActivity* layerActivity = GetLayerActivity(aFrame);
if (layerActivity) {
if (layerActivity->mLeftRestyleCount >= 2 ||
layerActivity->mTopRestyleCount >= 2 ||
layerActivity->mRightRestyleCount >= 2 ||
layerActivity->mBottomRestyleCount >= 2) {
layerActivity->mBottomRestyleCount >= 2 ||
layerActivity->mMarginLeftRestyleCount >= 2 ||
layerActivity->mMarginTopRestyleCount >= 2 ||
layerActivity->mMarginRightRestyleCount >= 2 ||
layerActivity->mMarginBottomRestyleCount >= 2) {
return true;
}
}

View File

@ -63,7 +63,7 @@ public:
* Return true if any of aFrame's offset property styles should be considered
* as being animated for constructing active layers.
*/
static bool IsOffsetStyleAnimated(nsIFrame* aFrame);
static bool IsOffsetOrMarginStyleAnimated(nsIFrame* aFrame);
/*
* We track modifications to the content of certain frames (i.e. canvas frames)

View File

@ -1207,7 +1207,7 @@ nsLayoutUtils::GetActiveScrolledRootFor(nsIFrame* aFrame,
while (f != aStopAtAncestor) {
if (IsPopup(f))
break;
if (ActiveLayerTracker::IsOffsetStyleAnimated(f))
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(f))
break;
nsIFrame* parent = GetCrossDocParentFrame(f);
if (!parent)

View File

@ -180,7 +180,9 @@ nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
// this is scripted animation.
if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform ||
aPropID == eCSSProperty_left || aPropID == eCSSProperty_top ||
aPropID == eCSSProperty_right || aPropID == eCSSProperty_bottom) {
aPropID == eCSSProperty_right || aPropID == eCSSProperty_bottom ||
aPropID == eCSSProperty_margin_left || aPropID == eCSSProperty_margin_top ||
aPropID == eCSSProperty_margin_right || aPropID == eCSSProperty_margin_bottom) {
nsIFrame* frame = mElement->GetPrimaryFrame();
if (frame) {
ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID);

View File

@ -315,9 +315,8 @@ nsChangeHint nsStyleMargin::CalcDifference(const nsStyleMargin& aOther) const
}
// Margin differences can't affect descendant intrinsic sizes and
// don't need to force children to reflow.
return NS_SubtractHint(NS_STYLE_HINT_REFLOW,
NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
nsChangeHint_NeedDirtyReflow));
return NS_CombineHint(nsChangeHint_NeedReflow,
nsChangeHint_ClearAncestorIntrinsics);
}
nsStylePadding::nsStylePadding() {