Title: [161296] trunk/Source/WebKit2
Revision
161296
Author
[email protected]
Date
2014-01-03 16:35:59 -0800 (Fri, 03 Jan 2014)

Log Message

[iOS] [WK2] TileController creates all tiles on first paint, making it slow and consuming lots of memory
https://bugs.webkit.org/show_bug.cgi?id=126457

Reviewed by Simon Fraser.

Instead of making all of the tiles all of the time, we should use the
view-exposed-rect mechanism to inform TileController about what portion
of the WKContentView is currently exposed by the WKScrollView.

* UIProcess/API/ios/WKContentView.h:
* UIProcess/API/ios/WKContentView.mm:
(-[WKContentView setViewportSize:]):
(-[WKContentView didFinishScrollTo:]):
(-[WKContentView didScrollTo:]):
Inform the WebPageProxy that our exposed rect changed.

* UIProcess/API/ios/WKView.mm:
(-[WKView scrollViewDidScroll:]):
Inform the WKContentView that we've scrolled at all.
Rename the existing WKContentView didScrollTo: to didFinishScrollTo:,
because it is expected to only fire when a scroll lands. Add didScrollTo:,
which fires continually as scrolling progresses.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
(WebKit::WebPageProxy::viewExposedRectChanged):
(WebKit::WebPageProxy::exposedRectChangedTimerFired):
* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::viewExposedRect):
* UIProcess/mac/WebPageProxyMac.mm:
Move view-exposed-rect stuff to WebPageProxy so it can be built on both
Mac and iOS, and un-!PLATFORM(IOS) some of the related members.

* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea):
(WebKit::RemoteLayerTreeDrawingArea::setExposedRect):
(WebKit::RemoteLayerTreeDrawingArea::setClipsToExposedRect):
(WebKit::RemoteLayerTreeDrawingArea::updateScrolledExposedRect):
(WebKit::RemoteLayerTreeDrawingArea::updateMainFrameClipsToExposedRect):
(WebKit::RemoteLayerTreeDrawingArea::mainFrameTiledBacking):
Steal TiledCoreAnimationDrawingArea's exposed-rect code.
Note that on iOS, we don't need to manually offset the exposed rect by
the scroll position, because the scroll position is already baked into
the exposed rect, and WebCore's notion of the scroll position will be
inaccurate until the scroll lands.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (161295 => 161296)


--- trunk/Source/WebKit2/ChangeLog	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/ChangeLog	2014-01-04 00:35:59 UTC (rev 161296)
@@ -1,3 +1,52 @@
+2014-01-03  Tim Horton  <[email protected]>
+
+        [iOS] [WK2] TileController creates all tiles on first paint, making it slow and consuming lots of memory
+        https://bugs.webkit.org/show_bug.cgi?id=126457
+
+        Reviewed by Simon Fraser.
+
+        Instead of making all of the tiles all of the time, we should use the
+        view-exposed-rect mechanism to inform TileController about what portion
+        of the WKContentView is currently exposed by the WKScrollView.
+
+        * UIProcess/API/ios/WKContentView.h:
+        * UIProcess/API/ios/WKContentView.mm:
+        (-[WKContentView setViewportSize:]):
+        (-[WKContentView didFinishScrollTo:]):
+        (-[WKContentView didScrollTo:]):
+        Inform the WebPageProxy that our exposed rect changed.
+
+        * UIProcess/API/ios/WKView.mm:
+        (-[WKView scrollViewDidScroll:]):
+        Inform the WKContentView that we've scrolled at all.
+        Rename the existing WKContentView didScrollTo: to didFinishScrollTo:,
+        because it is expected to only fire when a scroll lands. Add didScrollTo:,
+        which fires continually as scrolling progresses.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        (WebKit::WebPageProxy::viewExposedRectChanged):
+        (WebKit::WebPageProxy::exposedRectChangedTimerFired):
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::viewExposedRect):
+        * UIProcess/mac/WebPageProxyMac.mm:
+        Move view-exposed-rect stuff to WebPageProxy so it can be built on both
+        Mac and iOS, and un-!PLATFORM(IOS) some of the related members.
+
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea):
+        (WebKit::RemoteLayerTreeDrawingArea::setExposedRect):
+        (WebKit::RemoteLayerTreeDrawingArea::setClipsToExposedRect):
+        (WebKit::RemoteLayerTreeDrawingArea::updateScrolledExposedRect):
+        (WebKit::RemoteLayerTreeDrawingArea::updateMainFrameClipsToExposedRect):
+        (WebKit::RemoteLayerTreeDrawingArea::mainFrameTiledBacking):
+        Steal TiledCoreAnimationDrawingArea's exposed-rect code.
+        Note that on iOS, we don't need to manually offset the exposed rect by
+        the scroll position, because the scroll position is already baked into
+        the exposed rect, and WebCore's notion of the scroll position will be
+        inaccurate until the scroll lands.
+
 2014-01-03  Simon Fraser  <[email protected]>
 
         Give all PlatformCALayers a PlatformLayerID, not just remote ones

Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.h (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.h	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.h	2014-01-04 00:35:59 UTC (rev 161296)
@@ -64,6 +64,7 @@
 - (void)setMinimumSize:(CGSize)size;
 - (void)setViewportSize:(CGSize)size;
 
+- (void)didFinishScrollTo:(CGPoint)contentOffset;
 - (void)didScrollTo:(CGPoint)contentOffset;
 - (void)didZoomToScale:(CGFloat)scale;
 

Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.mm (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.mm	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKContentView.mm	2014-01-04 00:35:59 UTC (rev 161296)
@@ -138,13 +138,20 @@
 - (void)setViewportSize:(CGSize)size
 {
     _page->setFixedLayoutSize(IntSize(size));
+    _page->viewExposedRectChanged(FloatRect(_page->viewExposedRect().location(), FloatSize(size)), WebPageProxy::ClipsToExposedRect::Clip);
 }
 
-- (void)didScrollTo:(CGPoint)contentOffset
+- (void)didFinishScrollTo:(CGPoint)contentOffset
 {
     _page->didFinishScrolling(contentOffset);
+    _page->viewExposedRectChanged(FloatRect(FloatPoint(contentOffset), _page->fixedLayoutSize()), WebPageProxy::ClipsToExposedRect::Clip);
 }
 
+- (void)didScrollTo:(CGPoint)contentOffset
+{
+    _page->viewExposedRectChanged(FloatRect(FloatPoint(contentOffset), _page->fixedLayoutSize()), WebPageProxy::ClipsToExposedRect::Clip);
+}
+
 - (void)didZoomToScale:(CGFloat)scale
 {
     _page->didFinishZooming(scale);

Modified: trunk/Source/WebKit2/UIProcess/API/ios/WKView.mm (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/API/ios/WKView.mm	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/API/ios/WKView.mm	2014-01-04 00:35:59 UTC (rev 161296)
@@ -187,29 +187,35 @@
         _userHasChangedPageScale = YES;
 }
 
-- (void)_didScroll
+- (void)_didFinishScroll
 {
     CGPoint position = [_scrollView convertPoint:[_scrollView contentOffset] toView:_contentView.get()];
-    [_contentView didScrollTo:position];
+    [_contentView didFinishScrollTo:position];
 }
 
 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
 {
     // If we're decelerating, scroll offset will be updated when scrollViewDidFinishDecelerating: is called.
     if (!decelerate)
-        [self _didScroll];
+        [self _didFinishScroll];
 }
 
 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
 {
-    [self _didScroll];
+    [self _didFinishScroll];
 }
 
 - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
 {
-    [self _didScroll];
+    [self _didFinishScroll];
 }
 
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView
+{
+    CGPoint position = [_scrollView convertPoint:[_scrollView contentOffset] toView:_contentView.get()];
+    [_contentView didScrollTo:position];
+}
+
 - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
 {
     ASSERT(scrollView == _scrollView);

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


--- trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm	2014-01-04 00:35:59 UTC (rev 161296)
@@ -390,7 +390,7 @@
     if (_data->_useContentPreparationRectForVisibleRect)
         exposedRect = NSUnionRect(_data->_contentPreparationRect, exposedRect);
 
-    _data->_page->viewExposedRectChanged(exposedRect, _data->_clipsToVisibleRect);
+    _data->_page->viewExposedRectChanged(exposedRect, _data->_clipsToVisibleRect ? WebPageProxy::ClipsToExposedRect::Clip : WebPageProxy::ClipsToExposedRect::DoNotClip);
 }
 
 - (void)setFrameSize:(NSSize)size

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2014-01-04 00:35:59 UTC (rev 161296)
@@ -302,10 +302,10 @@
     , m_mediaVolume(1)
     , m_mayStartMediaWhenInWindow(true)
     , m_waitingForDidUpdateViewState(false)
-#if PLATFORM(MAC) && !PLATFORM(IOS)
+#if PLATFORM(MAC)
     , m_exposedRectChangedTimer(this, &WebPageProxy::exposedRectChangedTimerFired)
-    , m_clipsToExposedRect(false)
-    , m_lastSentClipsToExposedRect(false)
+    , m_clipsToExposedRect(ClipsToExposedRect::DoNotClip)
+    , m_lastSentClipsToExposedRect(ClipsToExposedRect::DoNotClip)
 #endif
     , m_scrollPinningBehavior(DoNotPin)
 {
@@ -4394,4 +4394,31 @@
         m_process->send(Messages::WebPage::SetScrollPinningBehavior(pinning), m_pageID);
 }
 
+#if PLATFORM(MAC) || PLATFORM(IOS)
+void WebPageProxy::viewExposedRectChanged(const FloatRect& exposedRect, ClipsToExposedRect clipsToExposedRect)
+{
+    if (!isValid())
+        return;
+
+    m_exposedRect = exposedRect;
+    m_clipsToExposedRect = clipsToExposedRect;
+
+    if (!m_exposedRectChangedTimer.isActive())
+        m_exposedRectChangedTimer.startOneShot(0);
+}
+
+void WebPageProxy::exposedRectChangedTimerFired(Timer<WebPageProxy>*)
+{
+    if (!isValid())
+        return;
+
+    if (m_exposedRect == m_lastSentExposedRect && m_clipsToExposedRect == m_lastSentClipsToExposedRect)
+        return;
+
+    process().send(Messages::WebPage::ViewExposedRectChanged(m_exposedRect, m_clipsToExposedRect == ClipsToExposedRect::Clip), m_pageID);
+    m_lastSentExposedRect = m_exposedRect;
+    m_lastSentClipsToExposedRect = m_clipsToExposedRect;
+}
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2014-01-04 00:35:59 UTC (rev 161296)
@@ -463,7 +463,9 @@
 
 #if PLATFORM(MAC)
     void windowAndViewFramesChanged(const WebCore::FloatRect& viewFrameInWindowCoordinates, const WebCore::FloatPoint& accessibilityViewCoordinates);
-    void viewExposedRectChanged(const WebCore::FloatRect& exposedRect, bool);
+    enum class ClipsToExposedRect { DoNotClip, Clip };
+    void viewExposedRectChanged(const WebCore::FloatRect& exposedRect, ClipsToExposedRect);
+    WebCore::FloatRect viewExposedRect() const { return m_exposedRect; }
     void exposedRectChangedTimerFired(WebCore::Timer<WebPageProxy>*);
     void setMainFrameIsScrollable(bool);
 
@@ -1355,13 +1357,11 @@
     bool m_waitingForDidUpdateViewState;
 
 #if PLATFORM(MAC)
-#if !PLATFORM(IOS)
     WebCore::Timer<WebPageProxy> m_exposedRectChangedTimer;
-#endif // PLATFORM(IOS)
     WebCore::FloatRect m_exposedRect;
     WebCore::FloatRect m_lastSentExposedRect;
-    bool m_clipsToExposedRect;
-    bool m_lastSentClipsToExposedRect;
+    ClipsToExposedRect m_clipsToExposedRect;
+    ClipsToExposedRect m_lastSentClipsToExposedRect;
 #endif
 
 #if PLATFORM(MAC)

Modified: trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm (161295 => 161296)


--- trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm	2014-01-04 00:35:59 UTC (rev 161296)
@@ -155,31 +155,6 @@
     process().send(Messages::WebPage::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, windowFrameInUnflippedScreenCoordinates, viewFrameInWindowCoordinates, accessibilityViewCoordinates), m_pageID);
 }
 
-void WebPageProxy::viewExposedRectChanged(const FloatRect& exposedRect, bool clipsToExposedRect)
-{
-    if (!isValid())
-        return;
-
-    m_exposedRect = exposedRect;
-    m_clipsToExposedRect = clipsToExposedRect;
-
-    if (!m_exposedRectChangedTimer.isActive())
-        m_exposedRectChangedTimer.startOneShot(0);
-}
-
-void WebPageProxy::exposedRectChangedTimerFired(Timer<WebPageProxy>*)
-{
-    if (!isValid())
-        return;
-
-    if (m_exposedRect == m_lastSentExposedRect && m_clipsToExposedRect == m_lastSentClipsToExposedRect)
-        return;
-
-    process().send(Messages::WebPage::ViewExposedRectChanged(m_exposedRect, m_clipsToExposedRect), m_pageID);
-    m_lastSentExposedRect = m_exposedRect;
-    m_lastSentClipsToExposedRect = m_clipsToExposedRect;
-}
-
 void WebPageProxy::setMainFrameIsScrollable(bool isScrollable)
 {
     if (!isValid())

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


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h	2014-01-04 00:35:59 UTC (rev 161296)
@@ -69,6 +69,9 @@
     virtual void forceRepaint() OVERRIDE;
     virtual bool forceRepaintAsync(uint64_t) OVERRIDE { return false; }
 
+    virtual void setExposedRect(const WebCore::FloatRect&) OVERRIDE;
+    virtual void setClipsToExposedRect(bool) OVERRIDE;
+
     // WebCore::GraphicsLayerClient
     virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double time) OVERRIDE { }
     virtual void notifyFlushRequired(const WebCore::GraphicsLayer*) OVERRIDE { }
@@ -80,12 +83,21 @@
     virtual bool allowCompositingLayerVisualDegradation() const OVERRIDE { return false; }
 #endif
 
+    void updateMainFrameClipsToExposedRect();
+    void updateScrolledExposedRect();
+
+    WebCore::TiledBacking* mainFrameTiledBacking() const;
+
     std::unique_ptr<RemoteLayerTreeContext> m_remoteLayerTreeContext;
     RefPtr<WebCore::PlatformCALayer> m_rootLayer;
 
     HashMap<PageOverlay*, std::unique_ptr<GraphicsLayerCARemote>> m_pageOverlayLayers;
 
     WebCore::IntSize m_viewSize;
+
+    WebCore::FloatRect m_exposedRect;
+    WebCore::FloatRect m_scrolledExposedRect;
+    bool m_clipsToExposedRect;
 };
 
 } // namespace WebKit

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


--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-01-04 00:24:08 UTC (rev 161295)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm	2014-01-04 00:35:59 UTC (rev 161296)
@@ -34,6 +34,7 @@
 #import <WebCore/FrameView.h>
 #import <WebCore/MainFrame.h>
 #import <WebCore/Settings.h>
+#import <WebCore/TiledBacking.h>
 
 using namespace WebCore;
 
@@ -42,10 +43,12 @@
 RemoteLayerTreeDrawingArea::RemoteLayerTreeDrawingArea(WebPage* webPage, const WebPageCreationParameters&)
     : DrawingArea(DrawingAreaTypeRemoteLayerTree, webPage)
     , m_remoteLayerTreeContext(std::make_unique<RemoteLayerTreeContext>(webPage))
+    , m_clipsToExposedRect(false)
 {
     webPage->corePage()->settings().setForceCompositingMode(true);
 #if PLATFORM(IOS)
     webPage->corePage()->settings().setDelegatesPageScaling(true);
+    setClipsToExposedRect(true);
 #endif
 }
 
@@ -207,4 +210,63 @@
     m_remoteLayerTreeContext->forceRepaint();
 }
 
+void RemoteLayerTreeDrawingArea::setExposedRect(const FloatRect& exposedRect)
+{
+    m_exposedRect = exposedRect;
+    updateScrolledExposedRect();
+}
+
+void RemoteLayerTreeDrawingArea::setClipsToExposedRect(bool clipsToExposedRect)
+{
+    m_clipsToExposedRect = clipsToExposedRect;
+    updateScrolledExposedRect();
+    updateMainFrameClipsToExposedRect();
+}
+
+void RemoteLayerTreeDrawingArea::updateScrolledExposedRect()
+{
+    if (!m_clipsToExposedRect)
+        return;
+
+    FrameView* frameView = m_webPage->corePage()->mainFrame().view();
+    if (!frameView)
+        return;
+
+    m_scrolledExposedRect = m_exposedRect;
+
+#if !PLATFORM(IOS)
+    IntPoint scrollPositionWithOrigin = frameView->scrollPosition() + toIntSize(frameView->scrollOrigin());
+    m_scrolledExposedRect.moveBy(scrollPositionWithOrigin);
+#endif
+
+    mainFrameTiledBacking()->setExposedRect(m_scrolledExposedRect);
+
+    for (auto it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it) {
+        if (TiledBacking* tiledBacking = it->value->tiledBacking())
+            tiledBacking->setExposedRect(m_scrolledExposedRect);
+    }
+}
+
+void RemoteLayerTreeDrawingArea::updateMainFrameClipsToExposedRect()
+{
+    if (TiledBacking* tiledBacking = mainFrameTiledBacking())
+        tiledBacking->setClipsToExposedRect(m_clipsToExposedRect);
+
+    for (auto it = m_pageOverlayLayers.begin(), end = m_pageOverlayLayers.end(); it != end; ++it)
+        if (TiledBacking* tiledBacking = it->value->tiledBacking())
+            tiledBacking->setClipsToExposedRect(m_clipsToExposedRect);
+
+    FrameView* frameView = m_webPage->corePage()->mainFrame().view();
+    if (!frameView)
+        return;
+    
+    frameView->adjustTiledBackingCoverage();
+}
+
+TiledBacking* RemoteLayerTreeDrawingArea::mainFrameTiledBacking() const
+{
+    FrameView* frameView = m_webPage->corePage()->mainFrame().view();
+    return frameView ? frameView->tiledBacking() : 0;
+}
+
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to