Bug 1177155 part 1 - Defer resize reflow and freeze refresh driver during window fullscreen change. r=smaug

This commit is contained in:
Xidorn Quan 2015-08-27 23:14:49 +10:00
parent 9f820944f5
commit 3101be7350
5 changed files with 59 additions and 9 deletions

View File

@ -6383,7 +6383,8 @@ FullscreenTransitionTask::Run()
mWindow->mFullScreen = mFullscreen;
}
// Toggle the fullscreen state on the widget
mWidget->MakeFullScreen(mFullscreen, mScreen);
mWindow->SetWidgetFullscreen(nsPIDOMWindow::eForFullscreenAPI,
mFullscreen, mWidget, mScreen);
// Set observer for the next content paint.
nsCOMPtr<nsIObserver> observer = new Observer(this);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
@ -6462,13 +6463,7 @@ MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRHMDInfo* aHMD,
}
nsCOMPtr<nsIScreen> screen = aHMD ? aHMD->GetScreen() : nullptr;
if (!performTransition) {
if (aReason == nsPIDOMWindow::eForFullscreenMode) {
// If we enter fullscreen for fullscreen mode, we want
// the native system behavior.
widget->MakeFullScreenWithNativeTransition(aFullscreen, screen);
} else {
widget->MakeFullScreen(aFullscreen, screen);
}
aWindow->SetWidgetFullscreen(aReason, aFullscreen, widget, screen);
} else {
nsCOMPtr<nsIRunnable> task =
new FullscreenTransitionTask(duration, aWindow, aFullscreen,
@ -6572,6 +6567,27 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason,
return NS_OK;
}
void
nsGlobalWindow::SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
nsIWidget* aWidget, nsIScreen* aScreen)
{
MOZ_ASSERT(IsOuterWindow());
MOZ_ASSERT(this == GetTop(), "Only topmost window should call this");
MOZ_ASSERT(!GetFrameElementInternal(), "Content window should not call this");
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell()) {
presShell->SetIsInFullscreenChange(true);
}
if (aReason == nsPIDOMWindow::eForFullscreenMode) {
// If we enter fullscreen for fullscreen mode, we want
// the native system behavior.
aWidget->MakeFullScreenWithNativeTransition(aIsFullscreen, aScreen);
} else {
aWidget->MakeFullScreen(aIsFullscreen, aScreen);
}
}
/* virtual */ void
nsGlobalWindow::FinishFullscreenChange(bool aIsFullscreen)
{
@ -6604,6 +6620,11 @@ nsGlobalWindow::FinishFullscreenChange(bool aIsFullscreen)
// respond visually if we are kicked into full screen mode
DispatchCustomEvent(NS_LITERAL_STRING("fullscreen"));
if (nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell()) {
MOZ_ASSERT(presShell->IsInFullscreenChange());
presShell->SetIsInFullscreenChange(false);
}
if (!mWakeLock && mFullScreen) {
nsRefPtr<power::PowerManagerService> pmService =
power::PowerManagerService::GetInstance();

View File

@ -498,6 +498,8 @@ public:
FullscreenReason aReason, bool aIsFullscreen,
mozilla::gfx::VRHMDInfo *aHMD = nullptr) override final;
virtual void FinishFullscreenChange(bool aIsFullscreen) override final;
void SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,
nsIWidget* aWidget, nsIScreen* aScreen);
bool FullScreen() const;
// Inner windows only.

View File

@ -1589,6 +1589,9 @@ public:
nsresult HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
bool* aRetVal);
bool IsInFullscreenChange() const { return mIsInFullscreenChange; }
void SetIsInFullscreenChange(bool aValue);
/**
* Refresh observer management.
*/
@ -1770,6 +1773,11 @@ protected:
bool mIsZombie : 1;
bool mIsReflowing : 1;
// Indicates that the whole document is performing fullscreen change,
// in which case, we need to defer dispatching resize event and freeze
// the refresh driver to avoid unnecessary reflow.
bool mIsInFullscreenChange : 1;
// For all documents we initially lock down painting.
bool mPaintingSuppressed : 1;

View File

@ -10956,3 +10956,21 @@ nsIPresShell::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
*aRetVal = mStyleSet->HasRuleProcessorUsedByMultipleStyleSets(type);
return NS_OK;
}
void
nsIPresShell::SetIsInFullscreenChange(bool aValue)
{
if (mIsInFullscreenChange == aValue) {
NS_WARNING(aValue ? "Pres shell has been in fullscreen change?" :
"Pres shell is not in fullscreen change?");
return;
}
mIsInFullscreenChange = aValue;
if (nsRefreshDriver* rd = mPresContext->RefreshDriver()) {
if (aValue) {
rd->Freeze();
} else {
rd->Thaw();
}
}
}

View File

@ -197,7 +197,8 @@ void
nsViewManager::SetWindowDimensions(nscoord aWidth, nscoord aHeight)
{
if (mRootView) {
if (mRootView->IsEffectivelyVisible() && mPresShell && mPresShell->IsVisible()) {
if (mRootView->IsEffectivelyVisible() && mPresShell &&
mPresShell->IsVisible() && !mPresShell->IsInFullscreenChange()) {
if (mDelayedResize != nsSize(NSCOORD_NONE, NSCOORD_NONE) &&
mDelayedResize != nsSize(aWidth, aHeight)) {
// We have a delayed resize; that now obsolete size may already have