WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-150515-20151212000522.patch (text/plain), 19.24 KB, created by
Kat Graff
on 2015-12-12 00:05:56 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Kat Graff
Created:
2015-12-12 00:05:56 PST
Size:
19.24 KB
patch
obsolete
>Subversion Revision: 193642 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1d000212b8055436cd5eb51fb1629202179e7def..08ae755481e62a05c677ea3405d653ecf2c12bd3 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,36 @@ >+2015-12-11 Katlyn Graff <kgraff@apple.com> >+ >+ Safari background tabs should be fully suspended where possible. >+ https://bugs.webkit.org/show_bug.cgi?id=150515 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Support for tab suspension for Mac, enabled by defaults writing to WebKitTabSuspension. >+ Page-down suspension consolidated with PageCache suspension code in Document:: >+ suspend and Document::resume. Pages canTabSuspend if cacheable, nonvisible, nonprerender, >+ and nonactive. >+ >+ * dom/Document.cpp: moved scrollbar handling from setInPageCache to suspend/resume >+ (WebCore::Document::suspend): moved scrollbar, dom, animation, timer, and visual update suspending into here >+ (WebCore::Document::resume): moved scrollbar, dom, animation, timer, and visual update resuming into here >+ * dom/Document.h: added m_isSuspended to prevent repeat calls from PageCache/Tab Suspension contention >+ * history/CachedFrame.cpp: moved dom, animation, and timer suspension into Document::suspend >+ (WebCore::CachedFrame::CachedFrame): >+ * history/PageCache.cpp: Added a few nullchecks to prevent crashes if canCacheFrame is called but document is null >+ (WebCore::PageCache::canCacheFrame): >+ * page/Page.cpp: >+ (WebCore::Page::Page): Added timer to fire delayed suspension >+ (WebCore::Page::setPageActivityState): Added a call to schedule tab suspension >+ (WebCore::Page::setIsVisibleInternal): Added a call to schedule tab suspension >+ (WebCore::Page::canTabSuspend): Added support for suspending if cacheable, nonvisible, nonprerender, and nonactive >+ (WebCore::Page::setIsTabSuspended): Added a function to suspend or resume tabs >+ (WebCore::Page::setTabSuspensionEnabled): Added support for a defaults write enable >+ (WebCore::Page::scheduleTabSuspension): Added ability to schedule the suspension timer to fire or resume >+ (WebCore::Page::timerFired): Added a suspension timer >+ * page/Page.h: >+ * page/PageThrottler.h: >+ (WebCore::PageThrottler::activityState): Added access to m_activityState for canTabSuspend >+ > 2015-12-07 Nikos Andronikos <nikos.andronikos-webkit@cisra.canon.com.au> > > Update Objective-C code generator to pass a reference to calling object for partial interfaces >diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog >index f7ee9acbccccee5ef4dba4f00dc9956ad86275b1..aa3fd327c2886901ba62a84692afa075fd633501 100644 >--- a/Source/WebKit2/ChangeLog >+++ b/Source/WebKit2/ChangeLog >@@ -1,3 +1,23 @@ >+2015-12-11 Katlyn Graff <kgraff@apple.com> >+ >+ Safari background tabs should be fully suspended where possible. >+ https://bugs.webkit.org/show_bug.cgi?id=150515 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Added a runtime flag enabling tab suspension, default off. >+ >+ * Shared/WebProcessCreationParameters.cpp: >+ (WebKit::WebProcessCreationParameters::WebProcessCreationParameters): >+ (WebKit::WebProcessCreationParameters::encode): >+ (WebKit::WebProcessCreationParameters::decode): >+ * Shared/WebProcessCreationParameters.h: >+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm: >+ (WebKit::registerUserDefaultsIfNeeded): >+ (WebKit::WebProcessPool::platformInitializeWebProcess): >+ * WebProcess/cocoa/WebProcessCocoa.mm: >+ (WebKit::WebProcess::platformInitializeWebProcess): >+ > 2015-12-07 Philippe Normand <pnormand@igalia.com> > > [GTK][Mac] socketpair assertion failure >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index 00ab223485ca756eb1969fcf966ceb683dd4b5f6..8686553a5bcc4da108f66b635919dc86b7c683b7 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -4470,9 +4470,6 @@ void Document::setInPageCache(bool flag) > FrameView* v = view(); > Page* page = this->page(); > >- if (page) >- page->lockAllOverlayScrollbarsToHidden(flag); >- > if (flag) { > if (v) { > // FIXME: There is some scrolling related work that needs to happen whenever a page goes into the >@@ -4505,6 +4502,9 @@ void Document::documentWillBecomeInactive() > > void Document::suspend() > { >+ if (m_isSuspended) >+ return; >+ > documentWillBecomeInactive(); > > for (auto* element : m_documentSuspensionCallbackElements) >@@ -4516,14 +4516,31 @@ void Document::suspend() > m_didDispatchViewportPropertiesChanged = false; > #endif > >+ ASSERT(page()); >+ page()->lockAllOverlayScrollbarsToHidden(true); >+ > if (RenderView* view = renderView()) { > if (view->usesCompositing()) > view->compositor().cancelCompositingLayerUpdate(); > } >+ >+ suspendScriptedAnimationControllerCallbacks(); >+ suspendActiveDOMObjects(ActiveDOMObject::PageCache); >+ >+ ASSERT(m_frame); >+ m_frame->clearTimers(); >+ >+ m_visualUpdatesAllowed = false; >+ m_visualUpdatesSuppressionTimer.stop(); >+ >+ m_isSuspended = true; > } > > void Document::resume() > { >+ if (!m_isSuspended) >+ return; >+ > Vector<Element*> elements; > copyToVector(m_documentSuspensionCallbackElements, elements); > for (auto* element : elements) >@@ -4537,6 +4554,14 @@ void Document::resume() > > ASSERT(m_frame); > m_frame->loader().client().dispatchDidBecomeFrameset(isFrameSet()); >+ m_frame->animation().resumeAnimationsForDocument(this); >+ >+ resumeActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended); >+ resumeScriptedAnimationControllerCallbacks(); >+ >+ m_visualUpdatesAllowed = true; >+ >+ m_isSuspended = false; > } > > void Document::registerForDocumentSuspensionCallbacks(Element* e) >diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h >index d28650d5948f4564be479580a9bfb360263b3845..e65a7198e27353140174a57d6298f42919b49c52 100644 >--- a/Source/WebCore/dom/Document.h >+++ b/Source/WebCore/dom/Document.h >@@ -1753,6 +1753,7 @@ private: > > bool m_hasStyleWithViewportUnits; > bool m_isTimerThrottlingEnabled { false }; >+ bool m_isSuspended { false }; > > HashSet<MediaProducer*> m_audioProducers; > MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying }; >diff --git a/Source/WebCore/history/CachedFrame.cpp b/Source/WebCore/history/CachedFrame.cpp >index 260fdb382ae35ec1cddb50501775611eb993ad45..72187c4a4982881bb4fbf9276946c98e590c4b55 100644 >--- a/Source/WebCore/history/CachedFrame.cpp >+++ b/Source/WebCore/history/CachedFrame.cpp >@@ -165,9 +165,9 @@ CachedFrame::CachedFrame(Frame& frame) > // but after we've fired the pagehide event, in case that creates more objects. > // Suspending must also happen after we've recursed over child frames, in case > // those create more objects. >+ > m_document->suspend(); >- m_document->suspendScriptedAnimationControllerCallbacks(); >- m_document->suspendActiveDOMObjects(ActiveDOMObject::PageCache); >+ > m_cachedFrameScriptData = std::make_unique<ScriptCachedFrameData>(frame); > > m_document->domWindow()->suspendForDocumentSuspension(); >@@ -179,9 +179,6 @@ CachedFrame::CachedFrame(Frame& frame) > > frame.view()->clearScrollableAreas(); > >- // suspend() can set up a layout timer on the FrameView, so clear timers after that. >- frame.clearTimers(); >- > // Deconstruct the FrameTree, to restore it later. > // We do this for two reasons: > // 1 - We reuse the main frame, so when it navigates to a new page load it needs to start with a blank FrameTree. >diff --git a/Source/WebCore/history/PageCache.cpp b/Source/WebCore/history/PageCache.cpp >index 523cb105b289a5d8391ea635d712288b4a878217..5961056c076e472426348de2f0c639304a10f0fc 100644 >--- a/Source/WebCore/history/PageCache.cpp >+++ b/Source/WebCore/history/PageCache.cpp >@@ -122,7 +122,7 @@ static bool canCacheFrame(Frame& frame, DiagnosticLoggingClient& diagnosticLoggi > logPageCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::hasPluginsKey()); > isCacheable = false; > } >- if (frame.isMainFrame() && frame.document()->url().protocolIs("https") && documentLoader->response().cacheControlContainsNoStore()) { >+ if (frame.isMainFrame() && frame.document() && frame.document()->url().protocolIs("https") && documentLoader->response().cacheControlContainsNoStore()) { > PCLOG(" -Frame is HTTPS, and cache control prohibits storing"); > logPageCacheFailureDiagnosticMessage(diagnosticLoggingClient, DiagnosticLoggingKeys::httpsNoStoreKey()); > isCacheable = false; >@@ -149,7 +149,7 @@ static bool canCacheFrame(Frame& frame, DiagnosticLoggingClient& diagnosticLoggi > } > > Vector<ActiveDOMObject*> unsuspendableObjects; >- if (!frame.document()->canSuspendActiveDOMObjectsForDocumentSuspension(&unsuspendableObjects)) { >+ if (frame.document() && !frame.document()->canSuspendActiveDOMObjectsForDocumentSuspension(&unsuspendableObjects)) { > PCLOG(" -The document cannot suspend its active DOM Objects"); > for (auto* activeDOMObject : unsuspendableObjects) { > PCLOG(" - Unsuspendable: ", activeDOMObject->activeDOMObjectName()); >diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp >index 30e585d43075bb060e6b40af48c949a0568721f9..4abc18659cc6e9c7b130d2e062287be1a872e2a1 100644 >--- a/Source/WebCore/page/Page.cpp >+++ b/Source/WebCore/page/Page.cpp >@@ -143,6 +143,7 @@ static void networkStateChanged(bool isOnLine) > } > > static const ViewState::Flags PageInitialViewState = ViewState::IsVisible | ViewState::IsInWindow; >+bool Page::s_tabSuspensionIsEnabled = false; > > Page::Page(PageConfiguration& pageConfiguration) > : m_chrome(std::make_unique<Chrome>(*this, *pageConfiguration.chromeClient)) >@@ -223,6 +224,7 @@ Page::Page(PageConfiguration& pageConfiguration) > , m_visitedLinkStore(*WTF::move(pageConfiguration.visitedLinkStore)) > , m_sessionID(SessionID::defaultSessionID()) > , m_isClosing(false) >+ , m_tabSuspensionTimer(*this, &Page::tabSuspensionTimerFired) > { > setTimerThrottlingEnabled(m_viewState & ViewState::IsVisuallyIdle); > >@@ -1293,6 +1295,11 @@ void Page::setViewState(ViewState::Flags viewState) > void Page::setPageActivityState(PageActivityState::Flags activityState) > { > chrome().client().setPageActivityState(activityState); >+ >+ if (activityState == PageActivityState::NoFlags && !isVisible()) >+ scheduleTabSuspension(true); >+ else >+ scheduleTabSuspension(false); > } > > void Page::setIsVisible(bool isVisible) >@@ -1338,6 +1345,8 @@ void Page::setIsVisibleInternal(bool isVisible) > if (FrameView* view = mainFrame().view()) > view->hide(); > } >+ >+ scheduleTabSuspension(!isVisible); > } > > void Page::setIsPrerender() >@@ -1821,4 +1830,48 @@ void Page::setResourceUsageOverlayVisible(bool visible) > } > #endif > >+bool Page::canTabSuspend() >+{ >+ return s_tabSuspensionIsEnabled && !m_isPrerender && (m_pageThrottler.activityState() == PageActivityState::NoFlags) && PageCache::singleton().canCache(this); >+} >+ >+void Page::setIsTabSuspended(bool shouldSuspend) >+{ >+ for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) { >+ if (auto* document = frame->document()) { >+ if (shouldSuspend) >+ document->suspend(); >+ else >+ document->resume(); >+ } >+ } >+} >+ >+void Page::setTabSuspensionEnabled(bool enable) >+{ >+ s_tabSuspensionIsEnabled = enable; >+} >+ >+void Page::scheduleTabSuspension(bool shouldSuspend) >+{ >+ if (m_shouldTabSuspend == shouldSuspend) >+ return; >+ >+ if (shouldSuspend && canTabSuspend()) { >+ m_shouldTabSuspend = shouldSuspend; >+ m_tabSuspensionTimer.startOneShot(0); >+ } else { >+ m_tabSuspensionTimer.stop(); >+ if (!shouldSuspend) { >+ m_shouldTabSuspend = shouldSuspend; >+ setIsTabSuspended(false); >+ } >+ } >+} >+ >+void Page::tabSuspensionTimerFired() >+{ >+ setIsTabSuspended(true); >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h >index 9ee50c7f316f3d4ef0ce01234ec1cbd26bd28303..4651cbc70f53b1cceb6475e8c2b6166125110e1f 100644 >--- a/Source/WebCore/page/Page.h >+++ b/Source/WebCore/page/Page.h >@@ -138,6 +138,7 @@ class Page : public Supplementable<Page> { > public: > WEBCORE_EXPORT static void updateStyleForAllPagesAfterGlobalChangeInEnvironment(); > WEBCORE_EXPORT static void clearPreviousItemFromAllPages(HistoryItem*); >+ WEBCORE_EXPORT static void setTabSuspensionEnabled(bool); > > WEBCORE_EXPORT explicit Page(PageConfiguration&); > WEBCORE_EXPORT ~Page(); >@@ -365,6 +366,8 @@ public: > // with exponential growth in the number of frames. > static const int maxNumberOfFrames = 1000; > >+ static bool s_tabSuspensionIsEnabled; >+ > void setEditable(bool isEditable) { m_isEditable = isEditable; } > bool isEditable() { return m_isEditable; } > >@@ -488,6 +491,7 @@ public: > > void setShowAllPlugins(bool showAll) { m_showAllPlugins = showAll; } > bool showAllPlugins() const; >+ void setIsTabSuspended(bool); > > private: > WEBCORE_EXPORT void initGroup(); >@@ -513,6 +517,9 @@ private: > > void hiddenPageDOMTimerThrottlingStateChanged(); > void setTimerThrottlingEnabled(bool); >+ bool canTabSuspend(); >+ void scheduleTabSuspension(bool); >+ void tabSuspensionTimerFired(); > > const std::unique_ptr<Chrome> m_chrome; > const std::unique_ptr<DragCaretController> m_dragCaretController; >@@ -602,6 +609,7 @@ private: > bool m_isEditable; > bool m_isPrerender; > ViewState::Flags m_viewState; >+ PageActivityState::Flags m_pageActivityState; > > LayoutMilestones m_requestedLayoutMilestones; > >@@ -652,6 +660,8 @@ private: > SessionID m_sessionID; > > bool m_isClosing; >+ bool m_shouldTabSuspend { false }; >+ Timer m_tabSuspensionTimer; > > MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying }; > >diff --git a/Source/WebCore/page/PageThrottler.h b/Source/WebCore/page/PageThrottler.h >index 631633b16e5ae2c859a15bb8ec1d12a841e81dc0..ffecbf0ac8fcb34a8b74327b91751c7465bff51f 100644 >--- a/Source/WebCore/page/PageThrottler.h >+++ b/Source/WebCore/page/PageThrottler.h >@@ -59,6 +59,7 @@ public: > PageThrottler(Page&); > > void didReceiveUserInput() { m_userInputHysteresis.impulse(); } >+ PageActivityState::Flags activityState() { return m_activityState; } > void pluginDidEvaluateWhileAudioIsPlaying() { m_audiblePluginHysteresis.impulse(); } > PageActivityAssertionToken mediaActivityToken(); > PageActivityAssertionToken pageLoadActivityToken(); >diff --git a/Source/WebKit2/Shared/WebProcessCreationParameters.cpp b/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >index a932f0c859d18092c9b061e195323e5d318414fd..6af317edcccb3f378ed89491c4adf7b6ceb1bbe9 100644 >--- a/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >+++ b/Source/WebKit2/Shared/WebProcessCreationParameters.cpp >@@ -43,6 +43,9 @@ WebProcessCreationParameters::WebProcessCreationParameters() > , shouldEnableJIT(false) > , shouldEnableFTLJIT(false) > #endif >+#if PLATFORM(MAC) >+ , shouldEnableTabSuspension(false) >+#endif > , memoryCacheDisabled(false) > #if ENABLE(SERVICE_CONTROLS) > , hasImageServices(false) >@@ -118,6 +121,10 @@ void WebProcessCreationParameters::encode(IPC::ArgumentEncoder& encoder) const > encoder << bundleParameterData->dataReference(); > #endif > >+#if PLATFORM(MAC) >+ encoder << shouldEnableTabSuspension; >+#endif >+ > #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) > encoder << notificationPermissions; > #endif >@@ -257,6 +264,11 @@ bool WebProcessCreationParameters::decode(IPC::ArgumentDecoder& decoder, WebProc > } > #endif > >+#if PLATFORM(MAC) >+ if (!decoder.decode(parameters.shouldEnableTabSuspension)) >+ return false; >+#endif >+ > #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) > if (!decoder.decode(parameters.notificationPermissions)) > return false; >diff --git a/Source/WebKit2/Shared/WebProcessCreationParameters.h b/Source/WebKit2/Shared/WebProcessCreationParameters.h >index 8088ddd2c157103057f6928320d529ebb46b00e4..2f80c63d78354909eead52e68b4f829c1c179562 100644 >--- a/Source/WebKit2/Shared/WebProcessCreationParameters.h >+++ b/Source/WebKit2/Shared/WebProcessCreationParameters.h >@@ -142,6 +142,10 @@ struct WebProcessCreationParameters { > > #endif // PLATFORM(COCOA) > >+#if PLATFORM(MAC) >+ bool shouldEnableTabSuspension; >+#endif >+ > #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) > HashMap<String, bool> notificationPermissions; > #endif >diff --git a/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm >index 7d4f4945d22984e4e3c7eccd786e69cdb517b5bc..7e965f16d8f18b832dcfe91cf036c30996bd5916 100644 >--- a/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm >+++ b/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm >@@ -84,6 +84,10 @@ static NSString * const WebKitNetworkCacheSpeculativeRevalidationEnabledDefaults > #endif > #endif > >+#if PLATFORM(MAC) >+NSString *WebKitTabSuspension = @"WebKitTabSuspension"; >+#endif >+ > namespace WebKit { > > NSString *SchemeForCustomProtocolRegisteredNotificationName = @"WebKitSchemeForCustomProtocolRegisteredNotification"; >@@ -101,6 +105,10 @@ static void registerUserDefaultsIfNeeded() > [registrationDictionary setObject:[NSNumber numberWithBool:YES] forKey:WebKitJSCJITEnabledDefaultsKey]; > [registrationDictionary setObject:[NSNumber numberWithBool:YES] forKey:WebKitJSCFTLJITEnabledDefaultsKey]; > >+#if PLATFORM(MAC) >+ [registrationDictionary setObject:[NSNumber numberWithBool:NO] forKey:WebKitTabSuspension]; >+#endif >+ > #if ENABLE(NETWORK_CACHE) > [registrationDictionary setObject:[NSNumber numberWithBool:YES] forKey:WebKitNetworkCacheEnabledDefaultsKey]; > [registrationDictionary setObject:[NSNumber numberWithBool:NO] forKey:WebKitNetworkCacheEfficacyLoggingEnabledDefaultsKey]; >@@ -170,6 +178,10 @@ void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& > parameters.accessibilityEnhancedUserInterfaceEnabled = false; > #endif > >+#if PLATFORM(MAC) >+ parameters.shouldEnableTabSuspension = [[NSUserDefaults standardUserDefaults] boolForKey:WebKitTabSuspension]; >+#endif >+ > parameters.shouldEnableJIT = [[NSUserDefaults standardUserDefaults] boolForKey:WebKitJSCJITEnabledDefaultsKey]; > parameters.shouldEnableFTLJIT = [[NSUserDefaults standardUserDefaults] boolForKey:WebKitJSCFTLJITEnabledDefaultsKey]; > parameters.shouldEnableMemoryPressureReliefLogging = [[NSUserDefaults standardUserDefaults] boolForKey:@"LogMemoryJetsamDetails"]; >diff --git a/Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm b/Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm >index e56f1301bcc69214b27179e91249e759dc133892..c1fb014e37283377716f8fcde31109d08a3f0523 100644 >--- a/Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm >+++ b/Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm >@@ -145,6 +145,7 @@ void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters&& par > > #if PLATFORM(MAC) > WebCore::FontCache::setFontWhitelist(parameters.fontWhitelist); >+ Page::setTabSuspensionEnabled(parameters.shouldEnableTabSuspension); > #endif > > m_compositingRenderServerPort = WTF::move(parameters.acceleratedCompositingPort);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 150515
:
265649
|
265651
|
265652
|
265653
|
266016
|
267092
|
267120
|
267122
|
267153
|
267167
|
267181
|
267222
|
267224
|
267225
| 267227