Changeset 171154 in webkit


Ignore:
Timestamp:
Jul 16, 2014 3:26:56 PM (10 years ago)
Author:
benjamin@webkit.org
Message:

[iOS][WK2] Synchronize the dynamic viewport updates with their layer tree commit
https://bugs.webkit.org/show_bug.cgi?id=134965
Related to <rdar://problem/17082607>

Patch by Benjamin Poulain <bpoulain@apple.com> on 2014-07-16
Reviewed by Tim Horton.

Dynamic viewport update relies on the _resizeAnimationTransformAdjustments being applied
to the page at the new size during the transition.

Because of the races between the LayerTree Commit and DynamicViewportSizeUpdate, the transform
can be applied to the wrong set of tiles.
This is mostly a problem for unresponsive WebProcess or when the synchronization is done
immediately.

There is at least one more case that is not handled: if synchronizeDynamicViewportUpdate()
completely fails to get the new page, the UIProcess is in a somewhat messy state.
I will look into that separately than the layer tree synchronization.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _didCommitLayerTree:]):
(-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:nextValidLayerTreeTransactionID:]):
(-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:]): Deleted.

  • UIProcess/API/Cocoa/WKWebViewInternal.h:
  • UIProcess/PageClient.h:
  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::WebPageProxy):
(WebKit::WebPageProxy::resetState):

  • UIProcess/WebPageProxy.h:
  • UIProcess/ios/PageClientImplIOS.h:
  • UIProcess/ios/PageClientImplIOS.mm:

(WebKit::PageClientImpl::dynamicViewportUpdateChangedTarget):

  • UIProcess/ios/WebPageProxyIOS.mm:

(WebKit::WebPageProxy::dynamicViewportSizeUpdate):
(WebKit::WebPageProxy::synchronizeDynamicViewportUpdate):
(WebKit::WebPageProxy::didCommitLayerTree):
(WebKit::WebPageProxy::dynamicViewportUpdateChangedTarget):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::WebPage):
(WebKit::WebPage::didCommitLoad):

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/WebPage.messages.in:
  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::synchronizeDynamicViewportUpdate):
(WebKit::WebPage::updateVisibleContentRects):

  • WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:

(WebKit::RemoteLayerTreeDrawingArea::nextTransactionID):
(WebKit::RemoteLayerTreeDrawingArea::currentTransactionID): Deleted.

Location:
trunk/Source/WebKit2
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r171146 r171154  
     12014-07-16  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [iOS][WK2] Synchronize the dynamic viewport updates with their layer tree commit
     4        https://bugs.webkit.org/show_bug.cgi?id=134965
     5        Related to <rdar://problem/17082607>
     6
     7        Reviewed by Tim Horton.
     8
     9        Dynamic viewport update relies on the _resizeAnimationTransformAdjustments being applied
     10        to the page at the new size during the transition.
     11
     12        Because of the races between the LayerTree Commit and DynamicViewportSizeUpdate, the transform
     13        can be applied to the wrong set of tiles.
     14        This is mostly a problem for unresponsive WebProcess or when the synchronization is done
     15        immediately.
     16
     17        There is at least one more case that is not handled: if synchronizeDynamicViewportUpdate()
     18        completely fails to get the new page, the UIProcess is in a somewhat messy state.
     19        I will look into that separately than the layer tree synchronization.
     20
     21        * UIProcess/API/Cocoa/WKWebView.mm:
     22        (-[WKWebView _didCommitLayerTree:]):
     23        (-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:nextValidLayerTreeTransactionID:]):
     24        (-[WKWebView _dynamicViewportUpdateChangedTargetToScale:position:]): Deleted.
     25        * UIProcess/API/Cocoa/WKWebViewInternal.h:
     26        * UIProcess/PageClient.h:
     27        * UIProcess/WebPageProxy.cpp:
     28        (WebKit::WebPageProxy::WebPageProxy):
     29        (WebKit::WebPageProxy::resetState):
     30        * UIProcess/WebPageProxy.h:
     31        * UIProcess/ios/PageClientImplIOS.h:
     32        * UIProcess/ios/PageClientImplIOS.mm:
     33        (WebKit::PageClientImpl::dynamicViewportUpdateChangedTarget):
     34        * UIProcess/ios/WebPageProxyIOS.mm:
     35        (WebKit::WebPageProxy::dynamicViewportSizeUpdate):
     36        (WebKit::WebPageProxy::synchronizeDynamicViewportUpdate):
     37        (WebKit::WebPageProxy::didCommitLayerTree):
     38        (WebKit::WebPageProxy::dynamicViewportUpdateChangedTarget):
     39        * WebProcess/WebPage/WebPage.cpp:
     40        (WebKit::WebPage::WebPage):
     41        (WebKit::WebPage::didCommitLoad):
     42        * WebProcess/WebPage/WebPage.h:
     43        * WebProcess/WebPage/WebPage.messages.in:
     44        * WebProcess/WebPage/ios/WebPageIOS.mm:
     45        (WebKit::WebPage::synchronizeDynamicViewportUpdate):
     46        (WebKit::WebPage::updateVisibleContentRects):
     47        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
     48        (WebKit::RemoteLayerTreeDrawingArea::nextTransactionID):
     49        (WebKit::RemoteLayerTreeDrawingArea::currentTransactionID): Deleted.
     50
    1512014-07-16  Dan Bernstein  <mitz@apple.com>
    252
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

    r171135 r171154  
    171171    BOOL _isAnimatingResize;
    172172    CATransform3D _resizeAnimationTransformAdjustments;
     173    uint64_t _resizeAnimationTransformTransactionID;
    173174    RetainPtr<UIView> _resizeAnimationView;
    174175    CGFloat _lastAdjustmentForScroller;
     
    805806
    806807    if (_isAnimatingResize) {
    807         [_resizeAnimationView layer].sublayerTransform = _resizeAnimationTransformAdjustments;
     808        if (layerTreeTransaction.transactionID() >= _resizeAnimationTransformTransactionID)
     809            [_resizeAnimationView layer].sublayerTransform = _resizeAnimationTransformAdjustments;
    808810        return;
    809811    }
     
    866868}
    867869
    868 - (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition
     870- (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition nextValidLayerTreeTransactionID:(uint64_t)nextValidLayerTreeTransactionID
    869871{
    870872    if (_isAnimatingResize) {
     
    879881        _resizeAnimationTransformAdjustments.m41 = (currentContentOffset.x - newContentOffset.x) / animatingScaleTarget;
    880882        _resizeAnimationTransformAdjustments.m42 = (currentContentOffset.y - newContentOffset.y) / animatingScaleTarget;
     883        _resizeAnimationTransformTransactionID = nextValidLayerTreeTransactionID;
    881884    }
    882885}
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h

    r170974 r171154  
    7575- (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&)layerTreeTransaction;
    7676
    77 - (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition;
     77- (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition nextValidLayerTreeTransactionID:(uint64_t)nextValidLayerTreeTransactionID;
    7878- (void)_restorePageStateToExposedRect:(WebCore::FloatRect)exposedRect scale:(double)scale;
    7979- (void)_restorePageStateToUnobscuredCenter:(WebCore::FloatPoint)center scale:(double)scale;
  • trunk/Source/WebKit2/UIProcess/PageClient.h

    r171045 r171154  
    254254
    255255    virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) = 0;
    256     virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition) = 0;
     256    virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition, uint64_t transactionID) = 0;
    257257    virtual void restorePageState(const WebCore::FloatRect&, double) = 0;
    258258    virtual void restorePageCenterAndScale(const WebCore::FloatPoint&, double) = 0;
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp

    r171045 r171154  
    275275#if PLATFORM(IOS)
    276276    , m_deviceOrientation(0)
    277     , m_dynamicViewportSizeUpdateInProgress(false)
     277    , m_dynamicViewportSizeUpdateWaitingForTarget(false)
     278    , m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit(false)
     279    , m_dynamicViewportSizeUpdateLayerTreeTransactionID(0)
    278280#endif
    279281    , m_geolocationPermissionRequestManager(*this)
     
    43454347
    43464348    m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo();
    4347     m_dynamicViewportSizeUpdateInProgress = false;
     4349    m_dynamicViewportSizeUpdateWaitingForTarget = false;
     4350    m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
     4351    m_dynamicViewportSizeUpdateLayerTreeTransactionID = 0;
    43484352#endif
    43494353
  • trunk/Source/WebKit2/UIProcess/WebPageProxy.h

    r171124 r171154  
    13231323    VisibleContentRectUpdateInfo m_lastVisibleContentRectUpdate;
    13241324    int32_t m_deviceOrientation;
    1325     bool m_dynamicViewportSizeUpdateInProgress;
     1325    bool m_dynamicViewportSizeUpdateWaitingForTarget;
     1326    bool m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit;
     1327    uint64_t m_dynamicViewportSizeUpdateLayerTreeTransactionID;
    13261328#endif
    13271329
  • trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h

    r171045 r171154  
    114114
    115115    virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&) override;
    116     virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition) override;
     116    virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition, uint64_t transactionID) override;
    117117    virtual void restorePageState(const WebCore::FloatRect&, double) override;
    118118    virtual void restorePageCenterAndScale(const WebCore::FloatPoint&, double) override;
  • trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm

    r171045 r171154  
    497497}
    498498
    499 void PageClientImpl::dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition)
    500 {
    501     [m_webView _dynamicViewportUpdateChangedTargetToScale:newScale position:newScrollPosition];
     499void PageClientImpl::dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
     500{
     501    [m_webView _dynamicViewportUpdateChangedTargetToScale:newScale position:newScrollPosition nextValidLayerTreeTransactionID:nextValidLayerTreeTransactionID];
    502502}
    503503
  • trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm

    r171124 r171154  
    251251void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& minimumLayoutSize, const WebCore::FloatSize& minimumLayoutSizeForMinimalUI, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates,  double targetScale, int32_t deviceOrientation)
    252252{
    253     m_dynamicViewportSizeUpdateInProgress = true;
     253    m_dynamicViewportSizeUpdateWaitingForTarget = true;
     254    m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = true;
    254255    m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(minimumLayoutSize, minimumLayoutSizeForMinimalUI, maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect, targetUnobscuredRectInScrollViewCoordinates, targetScale, deviceOrientation), m_pageID);
    255256}
     
    257258void WebPageProxy::synchronizeDynamicViewportUpdate()
    258259{
    259     if (m_dynamicViewportSizeUpdateInProgress) {
     260    if (m_dynamicViewportSizeUpdateWaitingForTarget) {
    260261        // We do not want the UIProcess to finish animated resize with the old content size, scale, etc.
    261262        // If that happens, the UIProcess would start pushing new VisibleContentRectUpdateInfo to the WebProcess with
     
    269270        // The following is a workaround to have the UIProcess in a consistent state.
    270271        // Instead of handling nested resize, we block the UIProcess until the animated resize finishes.
    271         m_dynamicViewportSizeUpdateInProgress = false;
    272272        double newScale;
    273273        FloatPoint newScrollPosition;
    274         if (m_process->sendSync(Messages::WebPage::SynchronizeDynamicViewportUpdate(), Messages::WebPage::SynchronizeDynamicViewportUpdate::Reply(newScale, newScrollPosition), m_pageID, std::chrono::seconds(2))) {
    275             m_pageClient.dynamicViewportUpdateChangedTarget(newScale, newScrollPosition);
    276 
    277             m_process->connection()->waitForAndDispatchImmediately<Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree>(m_pageID, std::chrono::seconds(1));
     274        uint64_t nextValidLayerTreeTransactionID;
     275        if (m_process->sendSync(Messages::WebPage::SynchronizeDynamicViewportUpdate(), Messages::WebPage::SynchronizeDynamicViewportUpdate::Reply(newScale, newScrollPosition, nextValidLayerTreeTransactionID), m_pageID, std::chrono::seconds(2))) {
     276            m_dynamicViewportSizeUpdateWaitingForTarget = false;
     277            m_dynamicViewportSizeUpdateLayerTreeTransactionID = nextValidLayerTreeTransactionID;
     278            m_pageClient.dynamicViewportUpdateChangedTarget(newScale, newScrollPosition, nextValidLayerTreeTransactionID);
    278279        }
    279     }
     280
     281    }
     282
     283    // If m_dynamicViewportSizeUpdateWaitingForTarget is false, we are waiting for the next valid frame with the hope it is the one for the new target.
     284    // If m_dynamicViewportSizeUpdateWaitingForTarget is still true, this is a desesperate attempt to get the valid frame before finishing the animation.
     285    if (m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit)
     286        m_process->connection()->waitForAndDispatchImmediately<Messages::RemoteLayerTreeDrawingAreaProxy::CommitLayerTree>(m_pageID, std::chrono::seconds(1), IPC::InterruptWaitingIfSyncMessageArrives);
     287
     288    m_dynamicViewportSizeUpdateWaitingForTarget = false;
     289    m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
    280290}
    281291
     
    308318    m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
    309319
     320    if (!m_dynamicViewportSizeUpdateWaitingForTarget && m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit) {
     321        if (layerTreeTransaction.transactionID() >= m_dynamicViewportSizeUpdateLayerTreeTransactionID)
     322            m_dynamicViewportSizeUpdateWaitingForLayerTreeCommit = false;
     323    }
     324
    310325    m_pageClient.didCommitLayerTree(layerTreeTransaction);
    311326}
     
    617632void WebPageProxy::dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint& newScrollPosition)
    618633{
    619     if (m_dynamicViewportSizeUpdateInProgress) {
    620         m_dynamicViewportSizeUpdateInProgress = false;
    621         m_pageClient.dynamicViewportUpdateChangedTarget(newScale, newScrollPosition);
     634    if (m_dynamicViewportSizeUpdateWaitingForTarget) {
     635        m_dynamicViewportSizeUpdateLayerTreeTransactionID = toRemoteLayerTreeDrawingAreaProxy(drawingArea())->nextLayerTreeTransactionID();
     636        m_dynamicViewportSizeUpdateWaitingForTarget = false;
     637        m_pageClient.dynamicViewportUpdateChangedTarget(newScale, newScrollPosition, m_dynamicViewportSizeUpdateLayerTreeTransactionID);
    622638    }
    623639}
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp

    r171057 r171154  
    297297#endif
    298298#if PLATFORM(IOS)
    299     , m_lastLayerTreeTransactionIDBeforeDidCommitLoad(0)
     299    , m_firstLayerTreeTransactionIDAfterDidCommitLoad(0)
    300300    , m_hasReceivedVisibleContentRectsAfterDidCommitLoad(false)
    301301    , m_scaleWasSetByUIProcess(false)
     
    44484448    m_hasReceivedVisibleContentRectsAfterDidCommitLoad = false;
    44494449    m_scaleWasSetByUIProcess = false;
    4450     m_lastLayerTreeTransactionIDBeforeDidCommitLoad = toRemoteLayerTreeDrawingArea(*m_drawingArea).currentTransactionID();
     4450    m_firstLayerTreeTransactionIDAfterDidCommitLoad = toRemoteLayerTreeDrawingArea(*m_drawingArea).nextTransactionID();
    44514451    m_userHasChangedPageScaleFactor = false;
    44524452
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h

    r171057 r171154  
    748748    void setDeviceOrientation(int32_t);
    749749    void dynamicViewportSizeUpdate(const WebCore::FloatSize& minimumLayoutSize, const WebCore::FloatSize& minimumLayoutSizeForMinimalUI, const WebCore::FloatSize& maximumUnobscuredSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, const WebCore::FloatRect& targetUnobscuredRectInScrollViewCoordinates, double scale, int32_t deviceOrientation);
    750     void synchronizeDynamicViewportUpdate(double& newTargetScale, WebCore::FloatPoint& newScrollPosition);
     750    void synchronizeDynamicViewportUpdate(double& newTargetScale, WebCore::FloatPoint& newScrollPosition, uint64_t& nextValidLayerTreeTransactionID);
    751751    void updateVisibleContentRects(const VisibleContentRectUpdateInfo&);
    752752    bool scaleWasSetByUIProcess() const { return m_scaleWasSetByUIProcess; }
     
    12261226
    12271227    WebCore::ViewportConfiguration m_viewportConfiguration;
    1228     uint64_t m_lastLayerTreeTransactionIDBeforeDidCommitLoad;
     1228    uint64_t m_firstLayerTreeTransactionIDAfterDidCommitLoad;
    12291229    bool m_hasReceivedVisibleContentRectsAfterDidCommitLoad;
    12301230    bool m_scaleWasSetByUIProcess;
  • trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

    r170981 r171154  
    4949    SetDeviceOrientation(int32_t deviceOrientation)
    5050    DynamicViewportSizeUpdate(WebCore::FloatSize minimumLayoutSize, WebCore::FloatSize minimumLayoutSizeForMinimalUI,  WebCore::FloatSize maximumUnobscuredSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, WebCore::FloatRect targetUnobscuredRectInScrollViewCoordinates, double scale, int32_t deviceOrientation)
    51     SynchronizeDynamicViewportUpdate() -> (double newTargetScale, WebCore::FloatPoint newScrollPosition)
     51    SynchronizeDynamicViewportUpdate() -> (double newTargetScale, WebCore::FloatPoint newScrollPosition, uint64_t nextValidLayerTreeTransactionID)
    5252
    5353    HandleTap(WebCore::IntPoint point)
  • trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

    r171101 r171154  
    3838#import "InteractionInformationAtPosition.h"
    3939#import "PluginView.h"
     40#import "RemoteLayerTreeDrawingArea.h"
    4041#import "VisibleContentRectUpdateInfo.h"
    4142#import "WKAccessibilityWebPageObjectIOS.h"
     
    23252326}
    23262327
    2327 void WebPage::synchronizeDynamicViewportUpdate(double& newTargetScale, FloatPoint& newScrollPosition)
     2328void WebPage::synchronizeDynamicViewportUpdate(double& newTargetScale, FloatPoint& newScrollPosition, uint64_t& nextValidLayerTreeTransactionID)
    23282329{
    23292330    newTargetScale = pageScaleFactor();
    23302331    newScrollPosition = m_page->mainFrame().view()->scrollPosition();
     2332    nextValidLayerTreeTransactionID = toRemoteLayerTreeDrawingArea(*m_drawingArea).nextTransactionID();
    23312333}
    23322334
     
    24382440{
    24392441    // Skip any VisibleContentRectUpdate that have been queued before DidCommitLoad suppresses the updates in the UIProcess.
    2440     if (visibleContentRectUpdateInfo.lastLayerTreeTransactionID() <= m_lastLayerTreeTransactionIDBeforeDidCommitLoad)
     2442    if (visibleContentRectUpdateInfo.lastLayerTreeTransactionID() <= m_firstLayerTreeTransactionIDAfterDidCommitLoad)
    24412443        return;
    24422444
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h

    r170787 r171154  
    5555    virtual ~RemoteLayerTreeDrawingArea();
    5656
    57     uint64_t currentTransactionID() const { return m_currentTransactionID; }
     57    uint64_t nextTransactionID() const { return m_currentTransactionID + 1; }
    5858
    5959private:
Note: See TracChangeset for help on using the changeset viewer.