Title: [177104] trunk/Source/WebKit2
Revision
177104
Author
timothy_hor...@apple.com
Date
2014-12-10 15:00:13 -0800 (Wed, 10 Dec 2014)

Log Message

Provide SPI to asynchronously move a WKView into a window and know when it has painted
https://bugs.webkit.org/show_bug.cgi?id=139460
<rdar://problem/19135389>

Reviewed by Anders Carlsson.

* UIProcess/API/Cocoa/WKViewPrivate.h:
Add _prepareForMoveToWindow:withCompletionHandler:, which internally
goes through the motions of being parented in that window and calls
the completion handler once painting is done and the view is ready
to be displayed (upon which we expect the view to actually move into the window).

* UIProcess/API/mac/WKView.mm:
(-[WKView viewWillMoveToWindow:]):
If we currently have a _targetWindowForMovePreparation (and are
pretending to be in that window), avoid performing viewWillMoveToWindow:
for a different window.

(-[WKView viewDidMoveToWindow]):
(-[WKView doWindowDidChangeScreen]):
(-[WKView _intrinsicDeviceScaleFactor]):
(-[WKView _colorSpace]):
(-[WKView _targetWindowForMovePreparation]):
If we have a _targetWindowForMovePreparation, use its properties instead
of self.window's.

(-[WKView _prepareForMoveToWindow:withCompletionHandler:]):
Simulate a move into the target window, but defer sending the view state update.
Then, send the view state update after registering the completion handler.

* UIProcess/API/mac/WKViewInternal.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
Rename m_viewStateChangeWantsReply to m_viewStateChangeWantsSynchronousReply.

(WebKit::WebPageProxy::installViewStateChangeCompletionHandler):
Added. Allow installing a block that will be called the next time
we get a didUpdateViewState back from the WebProcess after pushing the
current view state changes.

(WebKit::WebPageProxy::viewStateDidChange):
Adapt to the aforementioned rename.

(WebKit::WebPageProxy::dispatchViewStateChange):
Adapt to the aforementioned rename.
Send the view state change callback IDs along with SetViewState.

(WebKit::WebPageProxy::updateViewState):
Adapt to the aforementioned rename.

* UIProcess/WebPageProxy.h:
* UIProcess/mac/PageClientImpl.h:
* UIProcess/mac/PageClientImpl.mm:
(WebKit::PageClientImpl::activeWindow):
(WebKit::PageClientImpl::isViewWindowActive):
(WebKit::PageClientImpl::isViewVisible):
(WebKit::PageClientImpl::isViewVisibleOrOccluded):
(WebKit::PageClientImpl::isViewInWindow):
(WebKit::PageClientImpl::viewLayerHostingMode):
If we have a _targetWindowForMovePreparation, use its properties instead
of the WKView's window's.

* WebProcess/WebPage/DrawingArea.h:
(WebKit::DrawingArea::viewStateDidChange):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::reinitializeWebPage):
(WebKit::WebPage::setViewState):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
* WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
(WebKit::TiledCoreAnimationDrawingArea::viewStateDidChange):
Push the callback IDs to the WebProcess, and accumulate them in TiledCoreAnimationDrawingArea.

(WebKit::TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired):
Call all of the callbacks after one runloop cycle, just like DidUpdateViewState.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (177103 => 177104)


--- trunk/Source/WebKit2/ChangeLog	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/ChangeLog	2014-12-10 23:00:13 UTC (rev 177104)
@@ -1,3 +1,85 @@
+2014-12-10  Timothy Horton  <timothy_hor...@apple.com>
+
+        Provide SPI to asynchronously move a WKView into a window and know when it has painted
+        https://bugs.webkit.org/show_bug.cgi?id=139460
+        <rdar://problem/19135389>
+
+        Reviewed by Anders Carlsson.
+
+        * UIProcess/API/Cocoa/WKViewPrivate.h:
+        Add _prepareForMoveToWindow:withCompletionHandler:, which internally
+        goes through the motions of being parented in that window and calls
+        the completion handler once painting is done and the view is ready
+        to be displayed (upon which we expect the view to actually move into the window).
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView viewWillMoveToWindow:]):
+        If we currently have a _targetWindowForMovePreparation (and are
+        pretending to be in that window), avoid performing viewWillMoveToWindow:
+        for a different window.
+
+        (-[WKView viewDidMoveToWindow]):
+        (-[WKView doWindowDidChangeScreen]):
+        (-[WKView _intrinsicDeviceScaleFactor]):
+        (-[WKView _colorSpace]):
+        (-[WKView _targetWindowForMovePreparation]):
+        If we have a _targetWindowForMovePreparation, use its properties instead
+        of self.window's.
+
+        (-[WKView _prepareForMoveToWindow:withCompletionHandler:]):
+        Simulate a move into the target window, but defer sending the view state update.
+        Then, send the view state update after registering the completion handler.
+
+        * UIProcess/API/mac/WKViewInternal.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        Rename m_viewStateChangeWantsReply to m_viewStateChangeWantsSynchronousReply.
+
+        (WebKit::WebPageProxy::installViewStateChangeCompletionHandler):
+        Added. Allow installing a block that will be called the next time
+        we get a didUpdateViewState back from the WebProcess after pushing the
+        current view state changes.
+
+        (WebKit::WebPageProxy::viewStateDidChange):
+        Adapt to the aforementioned rename.
+
+        (WebKit::WebPageProxy::dispatchViewStateChange):
+        Adapt to the aforementioned rename.
+        Send the view state change callback IDs along with SetViewState.
+
+        (WebKit::WebPageProxy::updateViewState):
+        Adapt to the aforementioned rename.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/mac/PageClientImpl.h:
+        * UIProcess/mac/PageClientImpl.mm:
+        (WebKit::PageClientImpl::activeWindow):
+        (WebKit::PageClientImpl::isViewWindowActive):
+        (WebKit::PageClientImpl::isViewVisible):
+        (WebKit::PageClientImpl::isViewVisibleOrOccluded):
+        (WebKit::PageClientImpl::isViewInWindow):
+        (WebKit::PageClientImpl::viewLayerHostingMode):
+        If we have a _targetWindowForMovePreparation, use its properties instead
+        of the WKView's window's.
+
+        * WebProcess/WebPage/DrawingArea.h:
+        (WebKit::DrawingArea::viewStateDidChange):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::reinitializeWebPage):
+        (WebKit::WebPage::setViewState):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::viewStateDidChange):
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h:
+        * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm:
+        (WebKit::TiledCoreAnimationDrawingArea::viewStateDidChange):
+        Push the callback IDs to the WebProcess, and accumulate them in TiledCoreAnimationDrawingArea.
+
+        (WebKit::TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired):
+        Call all of the callbacks after one runloop cycle, just like DidUpdateViewState.
+
 2014-12-10  Anders Carlsson  <ander...@apple.com>
 
         Add session storage handling to StorageNamespaceProvider

Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKViewPrivate.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -100,6 +100,7 @@
 - (void)endDeferringViewInWindowChanges;
 - (void)endDeferringViewInWindowChangesSync;
 - (BOOL)isDeferringViewInWindowChanges;
+- (void)_prepareForMoveToWindow:(NSWindow *)targetWindow withCompletionHandler:(void(^)(void))completionHandler;
 
 - (BOOL)windowOcclusionDetectionEnabled;
 - (void)setWindowOcclusionDetectionEnabled:(BOOL)flag;

Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-12-10 23:00:13 UTC (rev 177104)
@@ -227,6 +227,7 @@
     
     unsigned _frameSizeUpdatesDisabledCount;
     BOOL _shouldDeferViewInWindowChanges;
+    NSWindow *_targetWindowForMovePreparation;
 
     BOOL _viewInWindowChangeWasDeferred;
 
@@ -2497,7 +2498,7 @@
 
 - (void)removeWindowObservers
 {
-    NSWindow *window = [self window];
+    NSWindow *window = _data->_targetWindowForMovePreparation ? _data->_targetWindowForMovePreparation : [self window];
     if (!window)
         return;
 
@@ -2524,6 +2525,9 @@
 
 - (void)viewWillMoveToWindow:(NSWindow *)window
 {
+    // If we're in the middle of preparing to move to a window, we should only be moved to that window.
+    ASSERT(!_data->_targetWindowForMovePreparation || (_data->_targetWindowForMovePreparation == window));
+
     NSWindow *currentWindow = [self window];
     if (window == currentWindow)
         return;
@@ -2536,7 +2540,9 @@
 
 - (void)viewDidMoveToWindow
 {
-    if ([self window]) {
+    NSWindow *window = _data->_targetWindowForMovePreparation ? _data->_targetWindowForMovePreparation : self.window;
+
+    if (window) {
         [self doWindowDidChangeScreen];
 
         ViewState::Flags viewStateChanges = ViewState::WindowIsActive | ViewState::IsVisible;
@@ -2580,7 +2586,8 @@
 
 - (void)doWindowDidChangeScreen
 {
-    _data->_page->windowScreenDidChange((PlatformDisplayID)[[[[[self window] screen] deviceDescription] objectForKey:@"NSScreenNumber"] intValue]);
+    NSWindow *window = _data->_targetWindowForMovePreparation ? _data->_targetWindowForMovePreparation : self.window;
+    _data->_page->windowScreenDidChange((PlatformDisplayID)[[[[window screen] deviceDescription] objectForKey:@"NSScreenNumber"] intValue]);
 }
 
 - (void)_windowDidBecomeKey:(NSNotification *)notification
@@ -2817,8 +2824,9 @@
 
 - (float)_intrinsicDeviceScaleFactor
 {
-    NSWindow *window = [self window];
-    if (window)
+    if (_data->_targetWindowForMovePreparation)
+        return [_data->_targetWindowForMovePreparation backingScaleFactor];
+    if (NSWindow *window = [self window])
         return [window backingScaleFactor];
     return [[NSScreen mainScreen] backingScaleFactor];
 }
@@ -2863,8 +2871,10 @@
 - (WebKit::ColorSpaceData)_colorSpace
 {
     if (!_data->_colorSpace) {
-        if ([self window])
-            _data->_colorSpace = [[self window] colorSpace];
+        if (_data->_targetWindowForMovePreparation)
+            _data->_colorSpace = [_data->_targetWindowForMovePreparation colorSpace];
+        else if (NSWindow *window = [self window])
+            _data->_colorSpace = [window colorSpace];
         else
             _data->_colorSpace = [[NSScreen mainScreen] colorSpace];
     }
@@ -4005,6 +4015,31 @@
     }
 }
 
+- (void)_prepareForMoveToWindow:(NSWindow *)targetWindow withCompletionHandler:(void(^)(void))completionHandler
+{
+    _data->_shouldDeferViewInWindowChanges = YES;
+    [self viewWillMoveToWindow:targetWindow];
+    _data->_targetWindowForMovePreparation = targetWindow;
+    [self viewDidMoveToWindow];
+
+    _data->_shouldDeferViewInWindowChanges = NO;
+
+    _data->_page->installViewStateChangeCompletionHandler(^() {
+        completionHandler();
+        ASSERT(self.window == _data->_targetWindowForMovePreparation);
+        _data->_targetWindowForMovePreparation = nil;
+    });
+
+    [self _dispatchSetTopContentInset];
+    _data->_page->viewStateDidChange(ViewState::IsInWindow, false, WebPageProxy::ViewStateChangeDispatchMode::Immediate);
+    _data->_viewInWindowChangeWasDeferred = NO;
+}
+
+- (NSWindow *)_targetWindowForMovePreparation
+{
+    return _data->_targetWindowForMovePreparation;
+}
+
 - (BOOL)isDeferringViewInWindowChanges
 {
     return _data->_shouldDeferViewInWindowChanges;

Modified: trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -132,4 +132,6 @@
 
 @property (nonatomic, retain, setter=_setPrimaryTrackingArea:) NSTrackingArea *_primaryTrackingArea;
 
+@property (readonly) NSWindow *_targetWindowForMovePreparation;
+
 @end

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2014-12-10 23:00:13 UTC (rev 177104)
@@ -375,7 +375,7 @@
     , m_navigationID(0)
     , m_configurationPreferenceValues(configuration.preferenceValues)
     , m_potentiallyChangedViewStateFlags(ViewState::NoFlags)
-    , m_viewStateChangeWantsReply(false)
+    , m_viewStateChangeWantsSynchronousReply(false)
     , m_isPlayingAudio(false)
 {
     m_websiteDataStore->addWebPage(*this);
@@ -1174,10 +1174,26 @@
         m_viewState |= ViewState::IsVisuallyIdle;
 }
 
-void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsReply, ViewStateChangeDispatchMode dispatchMode)
+void WebPageProxy::installViewStateChangeCompletionHandler(void (^completionHandler)())
 {
+    if (!isValid()) {
+        completionHandler();
+        return;
+    }
+
+    auto copiedCompletionHandler = Block_copy(completionHandler);
+    RefPtr<VoidCallback> voidCallback = VoidCallback::create([copiedCompletionHandler] (CallbackBase::Error) {
+        copiedCompletionHandler();
+        Block_release(copiedCompletionHandler);
+    }, std::make_unique<ProcessThrottler::BackgroundActivityToken>(m_process->throttler()));
+    uint64_t callbackID = m_callbacks.put(voidCallback.release());
+    m_nextViewStateChangeCallbacks.append(callbackID);
+}
+
+void WebPageProxy::viewStateDidChange(ViewState::Flags mayHaveChanged, bool wantsSynchronousReply, ViewStateChangeDispatchMode dispatchMode)
+{
     m_potentiallyChangedViewStateFlags |= mayHaveChanged;
-    m_viewStateChangeWantsReply = m_viewStateChangeWantsReply || wantsReply;
+    m_viewStateChangeWantsSynchronousReply = m_viewStateChangeWantsSynchronousReply || wantsSynchronousReply;
 
 #if PLATFORM(COCOA)
     bool isNewlyInWindow = !isInWindow() && (mayHaveChanged & ViewState::IsInWindow) && m_pageClient.isViewInWindow();
@@ -1236,11 +1252,13 @@
 
     // 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;
+        m_viewStateChangeWantsSynchronousReply = true;
 
-    if (changed || m_viewStateChangeWantsReply)
-        m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsReply), m_pageID);
+    if (changed || m_viewStateChangeWantsSynchronousReply)
+        m_process->send(Messages::WebPage::SetViewState(m_viewState, m_viewStateChangeWantsSynchronousReply, m_nextViewStateChangeCallbacks), m_pageID);
 
+    m_nextViewStateChangeCallbacks.clear();
+
     // This must happen after the SetViewState message is sent, to ensure the page visibility event can fire.
     updateActivityToken();
 
@@ -1262,11 +1280,11 @@
 
     updateBackingStoreDiscardableState();
 
-    if (m_viewStateChangeWantsReply)
+    if (m_viewStateChangeWantsSynchronousReply)
         waitForDidUpdateViewState();
 
     m_potentiallyChangedViewStateFlags = ViewState::NoFlags;
-    m_viewStateChangeWantsReply = false;
+    m_viewStateChangeWantsSynchronousReply = false;
 }
 
 void WebPageProxy::updateActivityToken()

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -371,7 +371,8 @@
     bool delegatesScrolling() const { return m_delegatesScrolling; }
 
     enum class ViewStateChangeDispatchMode { Deferrable, Immediate };
-    void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, bool wantsReply = false, ViewStateChangeDispatchMode = ViewStateChangeDispatchMode::Deferrable);
+    void viewStateDidChange(WebCore::ViewState::Flags mayHaveChanged, bool wantsSynchronousReply = false, ViewStateChangeDispatchMode = ViewStateChangeDispatchMode::Deferrable);
+    void installViewStateChangeCompletionHandler(void(^completionHandler)());
     bool isInWindow() const { return m_viewState & WebCore::ViewState::IsInWindow; }
     void waitForDidUpdateViewState();
     void didUpdateViewState() { m_waitingForDidUpdateViewState = false; }
@@ -1585,7 +1586,8 @@
 
     WebPreferencesStore::ValueMap m_configurationPreferenceValues;
     WebCore::ViewState::Flags m_potentiallyChangedViewStateFlags;
-    bool m_viewStateChangeWantsReply;
+    bool m_viewStateChangeWantsSynchronousReply;
+    Vector<uint64_t> m_nextViewStateChangeCallbacks;
 
     bool m_isPlayingAudio;
 };

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -183,6 +183,7 @@
     virtual void willRecordNavigationSnapshot(WebBackForwardListItem&) override;
 
     NSView *activeView() const;
+    NSWindow *activeWindow() const;
 
     virtual void didFirstVisuallyNonEmptyLayoutForMainFrame() override;
     virtual void didFinishLoadForMainFrame() override;

Modified: trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm (177103 => 177104)


--- trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/UIProcess/mac/PageClientImpl.mm	2014-12-10 23:00:13 UTC (rev 177104)
@@ -196,9 +196,20 @@
 #endif
 }
 
+NSWindow *PageClientImpl::activeWindow() const
+{
+#if WK_API_ENABLED
+    if (m_wkView._thumbnailView)
+        return m_wkView._thumbnailView.window;
+#endif
+    if (m_wkView._targetWindowForMovePreparation)
+        return m_wkView._targetWindowForMovePreparation;
+    return m_wkView.window;
+}
+
 bool PageClientImpl::isViewWindowActive()
 {
-    NSWindow *activeViewWindow = activeView().window;
+    NSWindow *activeViewWindow = activeWindow();
     return activeViewWindow.isKeyWindow || [NSApp keyWindow] == activeViewWindow;
 }
 
@@ -215,7 +226,7 @@
 bool PageClientImpl::isViewVisible()
 {
     NSView *activeView = this->activeView();
-    NSWindow *activeViewWindow = activeView.window;
+    NSWindow *activeViewWindow = activeWindow();
 
     if (!activeViewWindow)
         return false;
@@ -243,12 +254,12 @@
 
 bool PageClientImpl::isViewVisibleOrOccluded()
 {
-    return activeView().window.isVisible;
+    return activeWindow().isVisible;
 }
 
 bool PageClientImpl::isViewInWindow()
 {
-    return activeView().window;
+    return activeWindow();
 }
 
 bool PageClientImpl::isVisuallyIdle()
@@ -259,7 +270,7 @@
 LayerHostingMode PageClientImpl::viewLayerHostingMode()
 {
 #if HAVE(OUT_OF_PROCESS_LAYER_HOSTING)
-    if ([activeView().window _hostsLayersInWindowServer])
+    if ([activeWindow() _hostsLayersInWindowServer])
         return LayerHostingMode::OutOfProcess;
 #endif
     return LayerHostingMode::InProcess;

Modified: trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/DrawingArea.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -115,7 +115,7 @@
 
     virtual void dispatchAfterEnsuringUpdatedScrollPosition(std::function<void ()>);
 
-    virtual void viewStateDidChange(WebCore::ViewState::Flags, bool /*wantsDidUpdateViewState*/) { }
+    virtual void viewStateDidChange(WebCore::ViewState::Flags, bool /* wantsDidUpdateViewState */, const Vector<uint64_t>& /* callbackIDs */) { }
     virtual void setLayerHostingMode(LayerHostingMode) { }
 
     virtual bool markLayersVolatileImmediatelyIfPossible() { return true; }

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp	2014-12-10 23:00:13 UTC (rev 177104)
@@ -504,7 +504,7 @@
 void WebPage::reinitializeWebPage(const WebPageCreationParameters& parameters)
 {
     if (m_viewState != parameters.viewState)
-        setViewState(parameters.viewState);
+        setViewState(parameters.viewState, false, Vector<uint64_t>());
     if (m_layerHostingMode != parameters.layerHostingMode)
         setLayerHostingMode(static_cast<unsigned>(parameters.layerHostingMode));
 }
@@ -2311,7 +2311,7 @@
         layoutIfNeeded();
 }
 
-void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState)
+void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState, const Vector<uint64_t>& callbackIDs)
 {
     ViewState::Flags changed = m_viewState ^ viewState;
     m_viewState = viewState;
@@ -2320,7 +2320,7 @@
     for (auto* pluginView : m_pluginViews)
         pluginView->viewStateDidChange(changed);
 
-    m_drawingArea->viewStateDidChange(changed, wantsDidUpdateViewState);
+    m_drawingArea->viewStateDidChange(changed, wantsDidUpdateViewState, callbackIDs);
 
     if (changed & ViewState::IsInWindow)
         updateIsInWindow();

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -925,7 +925,7 @@
     void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
     void setWindowResizerSize(const WebCore::IntSize&);
     void updateIsInWindow(bool isInitialState = false);
-    void setViewState(WebCore::ViewState::Flags, bool wantsDidUpdateViewState = false);
+    void setViewState(WebCore::ViewState::Flags, bool wantsDidUpdateViewState, const Vector<uint64_t>& callbackIDs);
     void validateCommand(const String&, uint64_t);
     void executeEditCommand(const String&);
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in	2014-12-10 23:00:13 UTC (rev 177104)
@@ -22,7 +22,7 @@
 
 messages -> WebPage LegacyReceiver {
     SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event)
-    SetViewState(unsigned viewState, bool wantsDidUpdateViewState)
+    SetViewState(unsigned viewState, bool wantsDidUpdateViewState, Vector<uint64_t> callbackIDs)
     SetLayerHostingMode(unsigned layerHostingMode)
 
     SetSessionID(WebCore::SessionID sessionID)

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -103,7 +103,7 @@
 
     virtual void mainFrameContentSizeChanged(const WebCore::IntSize&) override;
 
-    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState) override;
+    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector<uint64_t>& callbackIDs) override;
 
     virtual bool adjustLayerFlushThrottling(WebCore::LayerFlushThrottleState::Flags) override;
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-12-10 23:00:13 UTC (rev 177104)
@@ -467,7 +467,7 @@
     m_connection->sendMessage(WTF::move(m_commitEncoder));
 }
 
-void RemoteLayerTreeDrawingArea::viewStateDidChange(ViewState::Flags, bool wantsDidUpdateViewState)
+void RemoteLayerTreeDrawingArea::viewStateDidChange(ViewState::Flags, bool wantsDidUpdateViewState, const Vector<uint64_t>&)
 {
     // FIXME: Should we suspend painting while not visible, like TiledCoreAnimationDrawingArea? Probably.
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h	2014-12-10 23:00:13 UTC (rev 177104)
@@ -81,7 +81,7 @@
 
     virtual bool shouldUseTiledBackingForFrameView(const WebCore::FrameView*) override;
 
-    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState) override;
+    virtual void viewStateDidChange(WebCore::ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector<uint64_t>&) override;
     void didUpdateViewStateTimerFired();
 
     virtual void attachViewOverlayGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*) override;
@@ -141,6 +141,8 @@
     WebCore::TransformationMatrix m_transform;
 
     RunLoop::Timer<TiledCoreAnimationDrawingArea> m_sendDidUpdateViewStateTimer;
+    Vector<uint64_t> m_nextViewStateChangeCallbackIDs;
+    bool m_wantsDidUpdateViewState;
 
     WebCore::GraphicsLayer* m_viewOverlayRootLayer;
 };

Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm (177103 => 177104)


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm	2014-12-10 22:50:28 UTC (rev 177103)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm	2014-12-10 23:00:13 UTC (rev 177104)
@@ -78,6 +78,7 @@
     , m_scrolledExposedRect(FloatRect::infiniteRect())
     , m_transientZoomScale(1)
     , m_sendDidUpdateViewStateTimer(RunLoop::main(), this, &TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired)
+    , m_wantsDidUpdateViewState(false)
     , m_viewOverlayRootLayer(nullptr)
 {
     m_webPage.corePage()->settings().setForceCompositingMode(true);
@@ -327,8 +328,11 @@
     }
 }
 
-void TiledCoreAnimationDrawingArea::viewStateDidChange(ViewState::Flags changed, bool wantsDidUpdateViewState)
+void TiledCoreAnimationDrawingArea::viewStateDidChange(ViewState::Flags changed, bool wantsDidUpdateViewState, const Vector<uint64_t>& nextViewStateChangeCallbackIDs)
 {
+    m_nextViewStateChangeCallbackIDs.appendVector(nextViewStateChangeCallbackIDs);
+    m_wantsDidUpdateViewState |= wantsDidUpdateViewState;
+
     if (changed & ViewState::IsVisible) {
         if (m_webPage.isVisible())
             resumePainting();
@@ -336,14 +340,22 @@
             suspendPainting();
     }
 
-    if (wantsDidUpdateViewState)
+    if (m_wantsDidUpdateViewState || !m_nextViewStateChangeCallbackIDs.isEmpty())
         m_sendDidUpdateViewStateTimer.startOneShot(0);
 }
 
 void TiledCoreAnimationDrawingArea::didUpdateViewStateTimerFired()
 {
     [CATransaction flush];
-    m_webPage.send(Messages::WebPageProxy::DidUpdateViewState());
+
+    if (m_wantsDidUpdateViewState)
+        m_webPage.send(Messages::WebPageProxy::DidUpdateViewState());
+
+    for (uint64_t callbackID : m_nextViewStateChangeCallbackIDs)
+        m_webPage.send(Messages::WebPageProxy::VoidCallback(callbackID));
+
+    m_nextViewStateChangeCallbackIDs.clear();
+    m_wantsDidUpdateViewState = false;
 }
 
 void TiledCoreAnimationDrawingArea::suspendPainting()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to