Bug 1125750 - Check the overflow region direction to avoid unnecesary reflow for scrollable frame. r=dbaron

--HG--
extra : rebase_source : f95ce49ad13e9c26ad225d5135d9dd545485b6e8
This commit is contained in:
Ethan Lin 2015-02-08 18:57:00 +01:00
Родитель 793d15a613
Коммит f9723b32cf
2 изменённых файлов: 50 добавлений и 3 удалений

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

@ -80,6 +80,21 @@ BuildScrollContainerLayers()
return !sContainerlessScrollingEnabled;
}
static uint32_t
GetOverflowChange(const nsRect& aCurScrolledRect, const nsRect& aPrevScrolledRect)
{
uint32_t result = 0;
if (aPrevScrolledRect.x != aCurScrolledRect.x ||
aPrevScrolledRect.width != aCurScrolledRect.width) {
result |= nsIScrollableFrame::HORIZONTAL;
}
if (aPrevScrolledRect.y != aCurScrolledRect.y ||
aPrevScrolledRect.height != aCurScrolledRect.height) {
result |= nsIScrollableFrame::VERTICAL;
}
return result;
}
//----------------------------------------------------------------------
//----------nsHTMLScrollFrame-------------------------------------------
@ -914,6 +929,8 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext,
mHelper.PostScrolledAreaEvent();
}
mHelper.UpdatePrevScrolledRect();
aStatus = NS_FRAME_COMPLETE;
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
mHelper.PostOverflowEvent();
@ -4525,6 +4542,8 @@ nsXULScrollFrame::Layout(nsBoxLayoutState& aState)
f->SetRect(clippedRect);
}
mHelper.UpdatePrevScrolledRect();
mHelper.PostOverflowEvent();
return NS_OK;
}
@ -4668,9 +4687,27 @@ ScrollFrameHelper::UpdateOverflow()
nsIScrollableFrame* sf = do_QueryFrame(mOuter);
ScrollbarStyles ss = sf->GetScrollbarStyles();
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN ||
ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
GetScrollPosition() != nsPoint()) {
// Reflow when the change in overflow leads to one of our scrollbars
// changing or might require repositioning the scrolled content due to
// reduced extents.
nsRect scrolledRect = GetScrolledRect();
uint32_t overflowChange = GetOverflowChange(scrolledRect, mPrevScrolledRect);
mPrevScrolledRect = scrolledRect;
bool needReflow = false;
nsPoint scrollPosition = GetScrollPosition();
if (overflowChange & nsIScrollableFrame::HORIZONTAL) {
if (ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN || scrollPosition.x) {
needReflow = true;
}
}
if (overflowChange & nsIScrollableFrame::VERTICAL) {
if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN || scrollPosition.y) {
needReflow = true;
}
}
if (needReflow) {
// If there are scrollbars, or we're not at the beginning of the pane,
// the scroll position may change. In this case, mark the frame as
// needing reflow. Don't use NS_FRAME_IS_DIRTY as dirty as that means
@ -4699,6 +4736,12 @@ ScrollFrameHelper::UpdateSticky()
}
}
void
ScrollFrameHelper::UpdatePrevScrolledRect()
{
mPrevScrolledRect = GetScrolledRect();
}
void
ScrollFrameHelper::AdjustScrollbarRectForResizer(
nsIFrame* aFrame, nsPresContext* aPresContext,

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

@ -300,6 +300,8 @@ public:
void UpdateSticky();
void UpdatePrevScrolledRect();
bool IsRectNearlyVisible(const nsRect& aRect) const;
nsRect ExpandRectToNearlyVisible(const nsRect& aRect) const;
@ -422,6 +424,8 @@ public:
// The scroll position where we last updated image visibility.
nsPoint mLastUpdateImagesPos;
nsRect mPrevScrolledRect;
FrameMetrics::ViewID mScrollParentID;
bool mNeverHasVerticalScrollbar:1;