Bug 1577258 - Streamline the shrink-wrapping resize reflow code. r=botond

Now that this code path is on its own, we can write more straight-forward code.



Depends on D43799

Differential Revision: https://phabricator.services.mozilla.com/D43800

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-09-12 21:27:06 +00:00
Родитель 86c41a5975
Коммит 8e44d6c57b
1 изменённых файлов: 49 добавлений и 104 удалений

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

@ -1913,8 +1913,19 @@ nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
return NS_OK;
}
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (!rootFrame) {
MOZ_ASSERT(!mPresContext->SuppressingResizeReflow(),
"Can't suppress resize reflow and shrink-wrap at the same time");
// Make sure that style is flushed before setting the pres context
// VisibleArea.
//
// Otherwise we may end up with bogus viewport units resolved against the
// unconstrained bsize, or restyling the whole document resolving viewport
// units against targetWidth, which may end up doing wasteful work.
mDocument->FlushPendingNotifications(FlushType::Frames);
nsIFrame* rootFrame = GetRootFrame();
if (mIsDestroying || !rootFrame) {
// If we don't have a root frame yet, that means we haven't had our initial
// reflow... If that's the case, and aWidth or aHeight is unconstrained,
// ignore them altogether.
@ -1931,68 +1942,25 @@ nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
}
WritingMode wm = rootFrame->GetWritingMode();
const bool shrinkToFit = !!(aOptions & ResizeReflowOptions::BSizeLimit);
MOZ_ASSERT(shrinkToFit ||
(wm.IsVertical() ? aWidth : aHeight) != NS_UNCONSTRAINEDSIZE,
"unconstrained bsize only usable with eBSizeLimit");
MOZ_ASSERT((wm.IsVertical() ? aHeight : aWidth) != NS_UNCONSTRAINEDSIZE,
"unconstrained isize not allowed");
bool isBSizeChanging =
wm.IsVertical() ? aOldWidth != aWidth : aOldHeight != aHeight;
nscoord targetWidth = aWidth;
nscoord targetHeight = aHeight;
if (shrinkToFit) {
if (wm.IsVertical()) {
targetWidth = NS_UNCONSTRAINEDSIZE;
} else {
targetHeight = NS_UNCONSTRAINEDSIZE;
}
isBSizeChanging = true;
}
const bool suppressingResizeReflow =
GetPresContext()->SuppressingResizeReflow();
RefPtr<nsViewManager> viewManager = mViewManager;
if (!suppressingResizeReflow && shrinkToFit) {
// Make sure that style is flushed before setting the pres context
// VisibleArea if we're shrinking to fit.
//
// Otherwise we may end up with bogus viewport units resolved against the
// unconstrained bsize, or restyling the whole document resolving viewport
// units against targetWidth, which may end up doing wasteful work.
mDocument->FlushPendingNotifications(FlushType::Frames);
}
if (!mIsDestroying) {
mPresContext->SetVisibleArea(nsRect(0, 0, targetWidth, targetHeight));
}
if (!mIsDestroying && !suppressingResizeReflow) {
if (!shrinkToFit) {
// Flush styles _now_ (with the correct visible area) if not computing the
// shrink-to-fit size.
//
// We've asserted above that sizes are not unconstrained, so this is going
// to be the final size, which means that we'll get the (correct) final
// styles now, and avoid a further potentially-wasteful full recascade on
// the next flush.
mDocument->FlushPendingNotifications(FlushType::Frames);
}
rootFrame = mFrameConstructor->GetRootFrame();
if (!mIsDestroying && rootFrame) {
// XXX Do a full invalidate at the beginning so that invalidates along
// the way don't have region accumulation issues?
if (isBSizeChanging) {
// For BSize changes driven by style, RestyleManager handles this.
// For height:auto BSizes (i.e. layout-controlled), descendant
// intrinsic sizes can't depend on them. So the only other case is
// viewport-controlled BSizes which we handle here.
nsLayoutUtils::MarkIntrinsicISizesDirtyIfDependentOnBSize(rootFrame);
}
{
nsAutoCauseReflowNotifier crNotifier(this);
@ -2000,12 +1968,11 @@ nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
// Kick off a top-down reflow
AUTO_LAYOUT_PHASE_ENTRY_POINT(GetPresContext(), Reflow);
nsViewManager::AutoDisableRefresh refreshBlocker(viewManager);
nsViewManager::AutoDisableRefresh refreshBlocker(mViewManager);
mDirtyRoots.Remove(rootFrame);
DoReflow(rootFrame, true, nullptr);
if (shrinkToFit) {
const bool reflowAgain =
wm.IsVertical() ? mPresContext->GetVisibleArea().width > aWidth
: mPresContext->GetVisibleArea().height > aHeight;
@ -2015,39 +1982,17 @@ nsresult PresShell::ResizeReflowIgnoreOverride(nscoord aWidth, nscoord aHeight,
DoReflow(rootFrame, true, nullptr);
}
}
}
// the first DoReflow above should've set our bsize if it was
// NS_UNCONSTRAINEDSIZE, and the isize shouldn't be NS_UNCONSTRAINEDSIZE
// anyway
NS_ASSERTION(mPresContext->GetVisibleArea().width != NS_UNCONSTRAINEDSIZE,
"width should not be NS_UNCONSTRAINEDSIZE after reflow");
NS_ASSERTION(
mPresContext->GetVisibleArea().height != NS_UNCONSTRAINEDSIZE,
"height should not be NS_UNCONSTRAINEDSIZE after reflow");
DidDoReflow(true);
}
}
rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
wm = rootFrame->GetWritingMode();
// reflow did not happen; if the reflow happened, our bsize should not be
// NS_UNCONSTRAINEDSIZE because DoReflow will fix it up to the same values
// as below
if (wm.IsVertical()) {
if (mPresContext->GetVisibleArea().width == NS_UNCONSTRAINEDSIZE) {
mPresContext->SetVisibleArea(
nsRect(0, 0, rootFrame->GetRect().width, aHeight));
}
} else {
if (mPresContext->GetVisibleArea().height == NS_UNCONSTRAINEDSIZE) {
mPresContext->SetVisibleArea(
nsRect(0, 0, aWidth, rootFrame->GetRect().height));
}
}
}
// the reflow above should've set our bsize if it was NS_UNCONSTRAINEDSIZE,
// and the isize shouldn't be NS_UNCONSTRAINEDSIZE anyway.
MOZ_DIAGNOSTIC_ASSERT(
mPresContext->GetVisibleArea().width != NS_UNCONSTRAINEDSIZE,
"width should not be NS_UNCONSTRAINEDSIZE after reflow");
MOZ_DIAGNOSTIC_ASSERT(
mPresContext->GetVisibleArea().height != NS_UNCONSTRAINEDSIZE,
"height should not be NS_UNCONSTRAINEDSIZE after reflow");
postResizeEventIfNeeded();
return NS_OK; // XXX this needs to be real. MMP