https://bugs.webkit.org/show_bug.cgi?id=134623
<rdar://problem/
17513223>
Reviewed by Simon Fraser.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::viewStateDidChange):
Add an argument to viewStateDidChange that allows callers (-[WKContentView _applicationWillEnterForeground:])
to force us to wait for a synchronous reply from the Web process after performing a view state change.
(WebKit::WebPageProxy::dispatchViewStateChange):
Move the has-been-in-window-and-now-is-newly-in-window check into dispatchViewStateChange.
Adjust the logic surrounding going into/out of window by factoring out the IsInWindow-did-change check, for clarity.
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView _applicationWillEnterForeground:]):
As previously mentioned, wait for a reply when foregrounding.
* WebProcess/WebPage/DrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlushImmediately):
(WebKit::RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlush):
(WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
Make sure to schedule a commit immediately if the UI process is waiting for a reply.
Previously we assumed that a commit would be scheduled anyway because we would have to reparent the
layer tree, but that doesn't happen in the suspension-without-unparenting case. Also, we want to skip
all throttling in this case.
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlushImmediately):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170787
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-07-04 Timothy Horton <timothy_horton@apple.com>
+
+ [iOS][WK2] Black web view after un-suspending process
+ https://bugs.webkit.org/show_bug.cgi?id=134623
+ <rdar://problem/17513223>
+
+ Reviewed by Simon Fraser.
+
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::viewStateDidChange):
+ Add an argument to viewStateDidChange that allows callers (-[WKContentView _applicationWillEnterForeground:])
+ to force us to wait for a synchronous reply from the Web process after performing a view state change.
+
+ (WebKit::WebPageProxy::dispatchViewStateChange):
+ Move the has-been-in-window-and-now-is-newly-in-window check into dispatchViewStateChange.
+ Adjust the logic surrounding going into/out of window by factoring out the IsInWindow-did-change check, for clarity.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView _applicationWillEnterForeground:]):
+ As previously mentioned, wait for a reply when foregrounding.
+
+ * WebProcess/WebPage/DrawingArea.h:
+ * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+ * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+ (WebKit::RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlushImmediately):
+ (WebKit::RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlush):
+ (WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
+ Make sure to schedule a commit immediately if the UI process is waiting for a reply.
+ Previously we assumed that a commit would be scheduled anyway because we would have to reparent the
+ layer tree, but that doesn't happen in the suspension-without-unparenting case. Also, we want to skip
+ all throttling in this case.
+
+ * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
+ * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+ (WebKit::TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlushImmediately):
+
2014-07-03 Gavin Barraclough <baraclough@apple.com>
Should not take background task assertion for NetworkProcess
, m_navigationID(0)
, m_configurationPreferenceValues(configuration.preferenceValues)
, m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
- , m_viewStateChangeWantsReply(WantsReplyOrNot::DoesNotWantReply)
+ , m_viewStateChangeWantsReply(false)
{
if (m_process->state() == WebProcessProxy::State::Running) {
if (m_userContentController)
m_viewState |= ViewState::IsVisuallyIdle;
}
-void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged)
+void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsReply)
{
- bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
-
m_potentiallyChangedViewStateFlags |= mayHaveChanged;
- m_viewStateChangeWantsReply = ((m_viewWasEverInWindow && isNewlyInWindow) || m_viewStateChangeWantsReply == WantsReplyOrNot::DoesWantReply) ? WantsReplyOrNot::DoesWantReply : WantsReplyOrNot::DoesNotWantReply;
+ m_viewStateChangeWantsReply = m_viewStateChangeWantsReply || wantsReply;
#if PLATFORM(COCOA)
- if (isNewlyInWindow) {
+ if (!isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow()) {
dispatchViewStateChange();
return;
}
#endif
}
+void WebPageProxy::viewDidLeaveWindow()
+{
+#if ENABLE(INPUT_TYPE_COLOR_POPOVER)
+ // When leaving the current page, close the popover color well.
+ if (m_colorPicker)
+ endColorPicker();
+#endif
+#if PLATFORM(IOS)
+ // When leaving the current page, close the video fullscreen.
+ if (m_videoFullscreenManager)
+ m_videoFullscreenManager->requestHideAndExitFullscreen();
+#endif
+}
+
+void WebPageProxy::viewDidEnterWindow()
+{
+ LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
+ if (m_layerHostingMode != layerHostingMode) {
+ m_layerHostingMode = layerHostingMode;
+ m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
+ }
+}
+
void WebPageProxy::dispatchViewStateChange()
{
#if PLATFORM(COCOA)
updateViewState(m_potentiallyChangedViewStateFlags);
ViewState::Flags changed = m_viewState ^ previousViewState;
+ // We always want to wait for the Web process to reply if we've been in-window before and are coming back in-window.
+ if (m_viewWasEverInWindow && (changed & ViewState::IsInWindow) && isInWindow())
+ m_viewStateChangeWantsReply = true;
+
if (changed)
- m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply == WantsReplyOrNot::DoesWantReply), m_pageID);
+ m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply), m_pageID);
// This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
updateActivityToken();
if ((changed & ViewState::IsVisible) && !isViewVisible())
m_process->responsivenessTimer()->stop();
- if ((m_potentiallyChangedViewStateFlags & ViewState::IsInWindow) && (m_viewState & ViewState::IsInWindow)) {
- LayerHostingMode layerHostingMode = m_pageClient.viewLayerHostingMode();
- if (m_layerHostingMode != layerHostingMode) {
- m_layerHostingMode = layerHostingMode;
- m_process->send(Messages::WebPage::SetLayerHostingMode(static_cast<unsigned>(layerHostingMode)), m_pageID);
- }
- }
-
- if ((m_potentiallyChangedViewStateFlags & ViewState::IsInWindow) && !(m_viewState & ViewState::IsInWindow)) {
-#if ENABLE(INPUT_TYPE_COLOR_POPOVER)
- // When leaving the current page, close the popover color well.
- if (m_colorPicker)
- endColorPicker();
-#endif
-#if PLATFORM(IOS)
- // When leaving the current page, close the video fullscreen.
- if (m_videoFullscreenManager)
- m_videoFullscreenManager->requestHideAndExitFullscreen();
-#endif
+ if (changed & ViewState::IsInWindow) {
+ if (isInWindow())
+ viewDidEnterWindow();
+ else
+ viewDidLeaveWindow();
}
updateBackingStoreDiscardableState();
- if (m_viewStateChangeWantsReply == WantsReplyOrNot::DoesWantReply)
+ if (m_viewStateChangeWantsReply)
waitForDidUpdateViewState();
m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
- m_viewStateChangeWantsReply = WantsReplyOrNot::DoesNotWantReply;
+ m_viewStateChangeWantsReply = false;
}
void WebPageProxy::updateActivityToken()
void setDelegatesScrolling(bool delegatesScrolling) { m_delegatesScrolling = delegatesScrolling; }
bool delegatesScrolling() const { return m_delegatesScrolling; }
- enum class WantsReplyOrNot { DoesNotWantReply, DoesWantReply };
- void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged);
+ void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, bool wantsReply = false);
bool isInWindow() const { return m_viewState & WebCore::ViewState::IsInWindow; }
void waitForDidUpdateViewState();
void didUpdateViewState() { m_waitingForDidUpdateViewState = false; }
WebPreferencesStore preferencesStore() const;
void dispatchViewStateChange();
+ void viewDidLeaveWindow();
+ void viewDidEnterWindow();
PageClient& m_pageClient;
std::unique_ptr<API::LoaderClient> m_loaderClient;
WebPreferencesStore::ValueMap m_configurationPreferenceValues;
WebCore::ViewState::Flags m_potentiallyChangedViewStateFlags;
- WantsReplyOrNot m_viewStateChangeWantsReply;
+ bool m_viewStateChangeWantsReply;
};
} // namespace WebKit
- (void)_applicationWillEnterForeground:(NSNotification*)notification
{
_page->applicationWillEnterForeground();
- _page->viewStateDidChange(ViewState::AllFlags & ~ViewState::IsInWindow);
+ _page->viewStateDidChange(ViewState::AllFlags & ~ViewState::IsInWindow, true);
}
- (void)_applicationDidBecomeActive:(NSNotification*)notification
virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() { return nullptr; }
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) = 0;
virtual void scheduleCompositingLayerFlush() = 0;
+ virtual void scheduleCompositingLayerFlushImmediately() = 0;
#if USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
virtual PassRefPtr<WebCore::DisplayRefreshMonitor> createDisplayRefreshMonitor(PlatformDisplayID);
virtual WebCore::GraphicsLayerFactory* graphicsLayerFactory() override;
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
virtual void scheduleCompositingLayerFlush() override;
+ virtual void scheduleCompositingLayerFlushImmediately() override;
virtual void addTransactionCallbackID(uint64_t callbackID) override;
return frameView ? frameView->tiledBacking() : nullptr;
}
+void RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlushImmediately()
+{
+ m_layerFlushTimer.startOneShot(0_ms);
+}
+
void RemoteLayerTreeDrawingArea::scheduleCompositingLayerFlush()
{
if (m_isFlushingSuspended) {
}
if (m_isLayerFlushThrottlingTemporarilyDisabledForInteraction) {
m_isLayerFlushThrottlingTemporarilyDisabledForInteraction = false;
- m_layerFlushTimer.startOneShot(0_ms);
+ scheduleCompositingLayerFlushImmediately();
return;
}
void RemoteLayerTreeDrawingArea::viewStateDidChange(ViewState::Flags, bool wantsDidUpdateViewState)
{
// FIXME: Should we suspend painting while not visible, like TiledCoreAnimationDrawingArea? Probably.
+
+ if (wantsDidUpdateViewState)
+ scheduleCompositingLayerFlushImmediately();
}
void RemoteLayerTreeDrawingArea::addTransactionCallbackID(uint64_t callbackID)
virtual bool layerTreeStateIsFrozen() const override;
virtual void setRootCompositingLayer(WebCore::GraphicsLayer*) override;
virtual void scheduleCompositingLayerFlush() override;
+ virtual void scheduleCompositingLayerFlushImmediately() override;
virtual void updatePreferences(const WebPreferencesStore&) override;
virtual void mainFrameContentSizeChanged(const WebCore::IntSize&) override;
m_layerFlushScheduler.schedule();
}
+void TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlushImmediately()
+{
+ scheduleCompositingLayerFlush();
+}
+
void TiledCoreAnimationDrawingArea::updatePreferences(const WebPreferencesStore&)
{
Settings& settings = m_webPage.corePage()->settings();